সাক্ষাত্কারের প্রশ্ন: একটি স্ট্রিং অন্য স্ট্রিংয়ের ঘূর্ণন কিনা তা পরীক্ষা করুন [বন্ধ]


235

আমার এক বন্ধুকে সফ্টওয়্যার বিকাশকারী পদের জন্য সাক্ষাত্কারে আজ নীচের প্রশ্নটি জিজ্ঞাসা করা হয়েছিল:

দুটি স্ট্রিং দেওয়া হয়েছে s1এবং আপনি s2কীভাবে পরীক্ষা করবেন যে এটিরs1 একটি ঘোরানো সংস্করণ রয়েছে s2?

উদাহরণ:

তাহলে s1 = "stackoverflow"নিম্নলিখিতটি এর কয়েকটি ঘোরানো সংস্করণ:

"tackoverflows"
"ackoverflowst"
"overflowstack"

যেখানে যেমন "stackoverflwo"হয় না একটি আবর্তিত সংস্করণ।

তিনি যে উত্তরটি দিয়েছিলেন তা হ'ল:

s2দীর্ঘতম উপসর্গটি ধরুন এবং এটির একটি উপ স্ট্রিংটি সন্ধান করুন s1, এটি আপনাকে ঘোরানোর বিন্দু দেবে। আপনি যখন s2এই পয়েন্টটি খুঁজে পান , তখন সেই বিন্দুটি ভাঙ্গুন s2aএবং s2bতারপরে ঠিক আছে কিনা তা পরীক্ষা করে দেখুনconcatenate(s2a,s2b) == s1

এটি আমার এবং আমার বন্ধুর কাছে ভাল সমাধান বলে মনে হচ্ছে। তবে সাক্ষাত্কারটি অন্যথায় ভেবেছিল। তিনি আরও সহজ সমাধান চেয়েছিলেন। আপনি কীভাবে এটি করবেন তা বলার জন্য দয়া করে আমাকে সহায়তা করুন Java/C/C++?

আগাম ধন্যবাদ.


4
কনটেনেটেট (এস 2 এ, এস 2 বি) == এস 1 কিনা আপনাকে পরীক্ষা করতে হবে না, কারণ আপনি জানেন যে s2a s1 এর শুরুর সমান। আপনি কেবল s2b == ঘূর্ণন_পয়েন্ট থেকে শেষ পর্যন্ত s1 এর স্ট্রিং কিনা তা পরীক্ষা করতে পারেন।
জেসন হল

33
এই প্রশ্নগুলি এবং শীর্ষের উত্তরগুলি এতগুলি উপার্জন কিভাবে পেল !?
ডেভিড জনস্টোন

9
@ ডেভিড: কারণ এটি আকর্ষণীয়।
ক্যাম

6
আমি বলব, খুব আকর্ষণীয় এবং একটি মার্জিত, সহজ উত্তর।
গুরু

7
@ ডেভিড: কারণ এটি এমন একটি প্রশ্ন যা এখানে আগে জিজ্ঞাসা করা হয়নি এবং যা প্রত্যেকে বুঝতে পারে (যদি কেউ প্রশ্ন / উত্তর না বুঝতে পারে তবে সাধারণত এটি অবশ্যই উজ্জীবিত হয় না; একটি সুন্দর সাধারণ প্রশ্নের ব্যাপক শ্রোতা থাকে) এবং এছাড়াও কারণ এটি জাভা এবং সি উভয়ের সাথে ট্যাগ করা হয়েছে এটি গণনা করেছে :)
বালুস

উত্তর:


687

প্রথমে নিশ্চিত হয়ে নিন s1এবং s2একই দৈর্ঘ্যের। তারপরে পরীক্ষা করে দেখুন যে এটির সাথে s2সংলগ্নের একটি স্ট্রিং রয়েছে :s1s1

algorithm checkRotation(string s1, string s2) 
  if( len(s1) != len(s2))
    return false
  if( substring(s2,concat(s1,s1))
    return true
  return false
end

জাভাতে:

boolean isRotation(String s1,String s2) {
    return (s1.length() == s2.length()) && ((s1+s1).indexOf(s2) != -1);
}

49
আমি এর কমনীয়তা পছন্দ করি, তবে কোনও ভ্রান্ত ইতিবাচকতা আছে কিনা তা পরীক্ষা করার জন্য আমাকে কিছুক্ষণ চিন্তা করতে হয়েছিল। (আমি মনে করি না আছে।)
জন স্কিটি

6
আপনি (s1+s1).contains(s2)জাভা ব্যবহার করতে পারেন ।
পলিজেনুব্রিকেন্টস

4
যাইহোক আমি একটি সাক্ষাত্কারের প্রশ্ন হিসাবে এটি কিছুটা আপত্তি করব। এটি একটি "আহা!" উপাদান, আমি মনে করি। বেশিরভাগ প্রোগ্রামার (আমার অন্তর্ভুক্ত) কেবল নিষ্ঠুর শক্তি ব্যবহার করবে, যা যাইহোক অযৌক্তিক নয়, এবং এটি সাক্ষাত্কারকারীর পক্ষে যথেষ্ট "চালাক" নয় বলে মনে হতে পারে।
ড্যানিয়েল দারানাস

5
@ জন মনোযোগ দিন s1+s1। স্পষ্টতই, আকারের সাথে এর সমস্ত সাবস্ট্রিংগুলি নির্মাণের s1.lengthআবর্তন are s1অতএব, আকারের s1.lengthযে কোনও স্ট্রিংয়ের একটি স্ট্রিংগুলি s1+s1অবশ্যই একটি ঘূর্ণন হতে হবে s1
ড্যানিয়েল সি। সোব্রাল

6
@ ইউনিকর্নডিক্টিক্ট - এই সমাধানটি সম্পর্কে কী দুর্দান্ত তা আপনি যখন এটি উল্লেখ করেছেন, তবে এটি ভেবে না দেখার জন্য আমি নিজেকে ঘৃণা করি!
জেমস বি

101

অবশ্যই আরও ভাল উত্তর হবে, "আচ্ছা, আমি স্ট্যাকওভারফ্লো সম্প্রদায়কে জিজ্ঞাসা করতাম এবং সম্ভবত 5 মিনিটের মধ্যে কমপক্ষে 4 টি সত্যই ভাল উত্তর পেতে পারে"। মস্তিষ্ক ভাল এবং সব কিছু, তবে আমি সমাধানের জন্য অন্যের সাথে কীভাবে কাজ করতে হয় তা জানে এমন একজনের উপর আমি একটি উচ্চতর মান স্থাপন করব।


14
নিখুঁত গালের জন্য +1। আমার দিনটি তৈরি করেছে :-)
প্ল্যাটিনাম আজুর

5
যদি তারা দ্বিমত পোষণ করে তবে আপনি তাদের এই প্রশ্নের সাথে লিঙ্ক করতে পারেন।
ক্যাম

51
একটি সাক্ষাত্কারের সময় আপনার সেলফোনটি ফুটিয়ে তোলা অভদ্র হিসাবে বিবেচিত হতে পারে এবং শেষ পর্যন্ত তারা জোন স্কিটকে নিয়োগ দেবে।
tstenner

2
আসলে সম্ভবত আমি যা বলেছিলাম ঠিক তা
ক্রিস ডাট্রো

6
আমি মনে করি না তারা জোন স্কিটের পক্ষে সক্ষম হবে।
সমাধান

49

আর একটি অজগর উদাহরণ (উত্তর ভিত্তিতে):

def isrotation(s1,s2):
     return len(s1)==len(s2) and s1 in 2*s2

1
মজার বিষয় হ'ল আমি খুব s2বেশি s1করে ডুপ্লিকেট করার কথা ভাবি ... তখন বুঝতে পারলাম যে সম্পর্কটি যাইহোক প্রতিসাম্যিক।
ম্যাথিউ এম।

1
যদি স্ট্রিং দীর্ঘ হতে পারে তবে এখানে একটি পাইথন সংস্করণ রয়েছে যা বায়ার-মুর ব্যবহার করে ও (চলমান সময়): ডিফ আইস্রোটেশন (এস 1, এস 2): রিটার্ন লেন (এস 1) == লেন (এস 2) এবং রি ডট কম (পুনরায়) .escape (s1))। অনুসন্ধান (2 * s2) কোনওটি নয়
ডানকান

2
@ ডানকান: inঅপারেটর কোনও ও (এন) অ্যালগরিদম ব্যবহার করে না?
কেন ব্লুম

1
@ ডানকান: অজগর স্ট্রিং পদ্ধতিগুলি একটি অনুকূলিত বায়ার-মুর-হর্সপুল ব্যবহার করে। আমি ভাবছি জাভাতে যদি একই রকম অপ্টিমাইজেশন থাকে।
টমাস আহলে

1
@ থমাস এটিকে নির্দেশ করার জন্য ধন্যবাদ। আমি ভেবেছিলাম যে কেবল নিয়মিত প্রকাশগুলি বয়র-মুর ব্যবহার করে তবে আমি দেখতে পেয়েছি যে আমি ভুল ছিল। পাইথন ২.৪ এবং এর আগে আমার উত্তরটি সঠিক ছিল তবে পাইথন 2.5 s1 in s2অপ্টিমাইজড। অ্যালগরিদমের বিবরণের জন্য effbot.org/zone/stringlib.htm দেখুন । গুগল ইঙ্গিত দেয় যে জাভাতে দ্রুত স্ট্রিং অনুসন্ধান নেই ( উদাহরণস্বরূপ johannburkard.de/software/stringsearch দেখুন ) যদিও আমি সন্দেহ করি যে তারা যদি এটি পরিবর্তন করে তবে এটি কোনও কিছু ভেঙে ফেলবে।
ডানকান

32

যেহেতু অন্যরা চতুর্ভুজ সংক্রান্ত সবচেয়ে খারাপ সময়ের জটিলতা সমাধান জমা দিয়েছে, আমি একটি রৈখিক যুক্ত করব ( কেএমপি অ্যালগরিদমের উপর ভিত্তি করে ):

bool is_rotation(const string& str1, const string& str2)
{
  if(str1.size()!=str2.size())
    return false;

  vector<size_t> prefixes(str1.size(), 0);
  for(size_t i=1, j=0; i<str1.size(); i++) {
    while(j>0 && str1[i]!=str1[j])
      j=prefixes[j-1];
    if(str1[i]==str1[j]) j++;
    prefixes[i]=j;
  }

  size_t i=0, j=0;
  for(; i<str2.size(); i++) {
    while(j>0 && str2[i]!=str1[j])
      j=prefixes[j-1];
    if(str2[i]==str1[j]) j++;
  }
  for(i=0; i<str2.size(); i++) {
    if(j>=str1.size()) return true;
    while(j>0 && str2[i]!=str1[j])
      j=prefixes[j-1];
    if(str2[i]==str1[j]) j++;
  }

  return false;
}

কাজের উদাহরণ


5
আইডোন.কমের জন্য +1 - এটি দেখতে খুব আকর্ষণীয়!
মার্টিন ভ্যাসেটিকা

25

সম্পাদনা: আপনি যদি এটি খুঁজে পান তবে গৃহীত উত্তরটি এর চেয়ে স্পষ্টতই মার্জিত এবং দক্ষ। আমি এই উত্তরটি ছেড়ে দিয়েছিলাম যে আমি যদি মূল স্ট্রিং দ্বিগুণ করার চিন্তা না করি তবে আমি কী করব।


আমি কেবল এটাকে জোর করে ফেলব। প্রথমে দৈর্ঘ্যটি পরীক্ষা করুন এবং তারপরে প্রতিটি সম্ভাব্য ঘোরানোর চেষ্টা করুন। যদি তাদের মধ্যে কেউ কাজ না করে তবে মিথ্যা প্রত্যাবর্তন করুন - যদি তাদের মধ্যে কেউ কাজ করে, অবিলম্বে সত্যে ফিরে আসুন।

কনটেনেট করার কোনও বিশেষ প্রয়োজন নেই - কেবল পয়েন্টার (সি) বা সূচকগুলি (জাভা) ব্যবহার করুন এবং উভয় পাশাপাশি চলুন, প্রতিটি স্ট্রিংয়ের একটি - একটি স্ট্রিংয়ের শুরুতে এবং দ্বিতীয় স্ট্রিংয়ে বর্তমান প্রার্থী ঘূর্ণন অফসেট এবং যেখানে প্রয়োজন সেখানে মোড়ানো । স্ট্রিংয়ের প্রতিটি পয়েন্টে অক্ষর সমতার জন্য পরীক্ষা করুন। আপনি যদি প্রথম স্ট্রিংয়ের শেষে পৌঁছে যান তবে আপনি শেষ করেছেন।

এটি সম্ভবত কমকেটেট করা হিসাবে সহজ হবে - যদিও সম্ভবত কম দক্ষ, কমপক্ষে জাভাতে।


8
+1 - আমাদের সবচেয়ে কার্যকর সমাধানের প্রয়োজন নেই যা 3+ গুণ সবচেয়ে কার্যকর সমাধানে চলে। এটি সি ... মাইক্রো-অপ্টিমাইজেশন হ'ল ডি রিগার
স্টিফেন সি

8
সাক্ষাত্কার: লোটার কথা, তবে আমি বাজি ধরছি এই লোকটি কোড করতে পারে না।
হামফ্রে বোগার্ট

8
@ বিউ: যদি কেউ এটি ভাবতে চায় তবে তারা আমাকে কোড জিজ্ঞাসা করার জন্য স্বাগত। যদি কেউ কেবল আমাকে জিজ্ঞাসা করেন যে "আমি কীভাবে করব" আমি সাধারণত কোডে ঝাঁপ দেওয়ার চেয়ে অ্যালগরিদমকে বর্ণনা করি।
জন স্কিটি

3
@ জোন - আমি বৌয়ের মন্তব্যটিকে রসিকতা হিসাবে
দেখলাম

37
@ জন এটি একটি রসিকতা ছিল! সাক্ষাত্কারকারী জন স্কিটির সাক্ষাত্কার দেয় না, জন স্কিটি তাকে সাক্ষাত্কার দেয়।
হামফ্রে বোগার্ট

17

এখানে একটি কেবল মজাদার জন্য রেজেেক্স ব্যবহার করছে:

boolean isRotation(String s1, String s2) {
   return (s1.length() == s2.length()) && (s1 + s2).matches("(.*)(.*)\\2\\1");
}

আপনি যদি কোনও বিশেষ স্ট্রিমিটার অক্ষর ব্যবহার না করে গ্যারান্টিযুক্ত ব্যবহার করতে পারেন তবে আপনি এটিকে কিছুটা সহজ করে তুলতে পারেন।

boolean isRotation(String s1, String s2) {
   // neither string can contain "="
   return (s1 + "=" + s2).matches("(.*)(.*)=\\2\\1");
}

পরিবর্তে সীমাবদ্ধ পুনরাবৃত্তি সহ আপনি লুকহাইন্ড ব্যবহার করতে পারেন:

boolean isRotation(String s1, String s2) {
   return (s1 + s2).matches(
      String.format("(.*)(.*)(?<=^.{%d})\\2\\1", s1.length())
   );
}

6
একটি রেজেক্স মাস্টার হওয়ার জন্য +1।
ক্রিস থরন্টন

-1 একই বিবৃতিতে "রেজেক্স" এবং "মজাদার" শব্দটি রাখার জন্য, "মজা" "" নয় "দিয়ে পরিবর্তন না করে (কেবল রসিকতা করলাম, আমি ভোটটি
নামি

ইঙ্গিত করার জন্য যে-রেজেক্সগুলি মজাদার নয় for
ম্যানলিকোড

কোনও রেডেক্স কীভাবে বডি প্লিজ ব্যাখ্যা করতে পারে "(। *) (। *) = \\ 2 \\ 1" কীভাবে কাজ করেছে!
মাওয়া

10

হু, ছি ... সবাই O(n^2)উত্তর নিয়ে এত শিহরিত কেন ? আমি ইতিবাচক যে আমরা এখানে আরও ভাল করতে পারি। উপরের উত্তরে O(n)একটি O(n)লুপে একটি অপারেশন (সাবস্ট্রিং / সূচিপত্র কল) অন্তর্ভুক্ত রয়েছে। এমনকি আরও দক্ষ অনুসন্ধান অ্যালগরিদম দিয়েও; বলুন Boyer-Mooreবা KMP, সবচেয়ে খারাপ ক্ষেত্রে এখনও O(n^2)নকল সঙ্গে আছে with

একটি O(n)এলোমেলো উত্তর সহজবোধ্য; একটি হ্যাশ নিন (রবিন ফিঙ্গারপ্রিন্টের মতো) যা O(1)স্লাইডিং উইন্ডো সমর্থন করে ; হ্যাশ স্ট্রিং 1, তারপরে হ্যাশ স্ট্রিং 2, এবং স্ট্রিংটির চারপাশে হ্যাশ 1 এর জন্য উইন্ডোটি সরানোর জন্য এগিয়ে যান এবং হ্যাশ ফাংশনগুলির সংঘর্ষ হয় কিনা তা দেখুন।

যদি আমরা সবচেয়ে খারাপ পরিস্থিতিটি "ডিএনএর দুটি স্ট্র্যান্ড স্ক্যান করার" মতো কিছু মনে করি, তবে সংঘর্ষের সম্ভাবনা বেড়ে যায় এবং এটি সম্ভবত এরকম কিছুতে অবক্ষয় হয় something O(n^(1+e)) বা কিছুতে (কেবল এখানে অনুমান করা)।

অবশেষে, একটি ডিস্ট্রিমেন্টিক O(nlogn)সমাধান রয়েছে যার বাইরে খুব বড় ধ্রুব রয়েছে। মূলত, ধারণাটি দুটি স্ট্রিংয়ের একটি সংশ্লেষ গ্রহণ করা। কনভ্যুশনের সর্বাধিক মান হবে ঘূর্ণন পার্থক্য (যদি তারা ঘোরানো হয়); একটি O(n)চেক নিশ্চিত। সুন্দর জিনিসটি হ'ল যদি দুটি সমান সর্বোচ্চ মান হয় তবে তারা উভয়ই বৈধ সমাধান। আপনি দুটি এফএফটি এবং একটি ডট পণ্য এবং একটি আইএফএফটি দিয়ে কনভলিউশনটি করতে পারেনnlogn + nlogn + n + nlogn + n == O(nlogn)

যেহেতু আপনি জিরো দিয়ে প্যাড করতে পারবেন না এবং আপনি গ্যারান্টি দিতে পারবেন না যে স্ট্রিংগুলি 2 length n দৈর্ঘ্যের হয়, এফএফটি দ্রুত হবে না; তারা এখনও ধীর হবেO(nlogn) সিটি অ্যালগরিদমের চেয়ে অনেক বড় ধ্রুবক।

যা কিছু বলেছিল, আমি একেবারে, 100% ইতিবাচক যে এখানে একটি O(n)বিবাদী সমাধান রয়েছে, তবে আমি যদি এটি খুঁজে পেতে পারি তবে খুব খারাপ।


সংক্ষিপ্ত-নিজে-নিজেই স্ট্রিংয়ের কেএমপি (হয় শারীরিকভাবে বা কার্যত একটি সহ %stringsize) রৈখিক সময়ের জন্য গ্যারান্টিযুক্ত।
ক্রেজেন জাভিয়ার সিটেকার

রবিন-কার্পের জন্য +1। কেএমপির বিপরীতে, এটি ধ্রুবক স্থান ব্যবহার করে এবং এটি কার্যকর করা সহজ। (এটিও আমি প্রথম সেকেন্ডের মধ্যেই বলেছিলাম যে, 'সঠিক' উত্তরটি দেখা শক্ত করে তোলে কারণ এটি একটিই অধিকার এবং এটি মিষ্টি)) আপনার দৃolution় ধারণাটি শোরের অ্যালগোরিদম সম্পর্কে মনে করিয়ে দেয় - আমি আশ্চর্য হই যে কোনও সাবলাইন আছে কিনা কোয়ান্টাম সলিউশন - কিন্তু এখন এটি নির্বাক হয়ে যাচ্ছে, তাই না?
দারিয়াস বেকন

1
আর কে কোনও ডিস্ট্রিমেন্টিক ও (এন) সমাধান দেয় না, এবং কেএমপি হ'ল হে (এন) স্পেসে যা অবাঞ্ছিত হতে পারে। দুটি উপায়ে বা এসএমওএ অনুসন্ধানের সন্ধান করুন যা সময়ে ও (এন) এবং মহাকাশে ও (1) উভয়ই রয়েছে। যাইহোক, গ্লিবসি স্টারস্টার দুটি উপায়ে ব্যবহার করে তবে% লেন ব্যবহারের বিপরীতে যদি আপনি সত্যিকারের স্ট্রিংগুলি ব্যবহার করতে চান তবে আপনি স্পেসে ও (এন) এ ফিরে আসছেন। :-)
আর .. গিটিহাব থামিয়ে দিন IEL

8

মুষ্টি, নিশ্চিত করুন যে দুটি স্ট্রিংয়ের দৈর্ঘ্য একই রয়েছে। তারপরে সি-তে, আপনি একটি সাধারণ পয়েন্টার পুনরাবৃত্তির সাহায্যে এটি করতে পারেন।


int is_rotation(char* s1, char* s2)
{
  char *tmp1;
  char *tmp2;
  char *ref2;

  assert(s1 && s2);
  if ((s1 == s2) || (strcmp(s1, s2) == 0))
    return (1);
  if (strlen(s1) != strlen(s2))
    return (0);

  while (*s2)
    {
      tmp1 = s1;
      if ((ref2 = strchr(s2, *s1)) == NULL)
        return (0);
      tmp2 = ref2;
      while (*tmp1 && (*tmp1 == *tmp2))
        {
          ++tmp1;
          ++tmp2;
          if (*tmp2 == '\0')
            tmp2 = s2;
        }
      if (*tmp1 == '\0')
        return (1);
      else
        ++s2;
    }
  return (0);
}

19
আহ, সি আপনি যখন সি তে করতে পারেন তখন কেন অর্ধেক সময় এবং কোডে কিছু করুন!
হামফ্রে বোগার্ট

11
+1 এটি খুব ভাল সি লেখা হয়েছে এবং সত্যি কথা বলতে, প্রশ্নটিকে 'সি' ট্যাগ করা হয়।
নিক মুর

5
এই কোডটিতে আপনি স্ট্রিংগুলি কমপক্ষে 2 বার না হলেও 3 বার (স্ট্রেন এবং স্ট্রিম্পে) have আপনি এই চেকটি নিজেকে সংরক্ষণ করতে পারেন এবং আপনি সেই লজিকটিকে আপনার লুপে রাখতে পারেন। আপনি যেমন লুপিং করছেন, যদি একটি স্ট্রিং অক্ষরের গণনা অন্যের চেয়ে আলাদা হয় তবে লুপটি প্রস্থান করুন। আপনি দৈর্ঘ্যগুলি জানবেন, আপনি যেমনটি শুরুটি জানেন এবং আপনি কখন নাল টার্মিনেটরে আঘাত করবেন তা জানবেন।
নাসকো

12
@ বিউ মার্টিনেজ - কারণ কখনও কখনও মৃত্যুর সময় উন্নয়নের সময়ের চেয়ে বেশি গুরুত্বপূর্ণ :-)
ফকাহেলার

2
@ এফকাহেলার - বিষয়টি হ'ল এটি খুব ধীর হতে পারে। অন্যান্য ভাষায় অন্তর্নির্মিত ফাংশনগুলিতে সাধারণত বায়ার-মুর, রবিন-কার্প বা নুথ-মরিস-প্র্যাটের মতো দ্রুত স্ট্রিং অনুসন্ধান অ্যালগরিদম ব্যবহার করা হয়। এটি খুব নির্বোধ, কেবলমাত্র সি-তে সমস্ত কিছু পুনরায় উদ্ভাবন করুন এবং এটি দ্রুততর বলে ধরে নিন।
টমাস আহলে

8

এখানে একটি O(n)এবং জায়গায় অ্যালগরিটম রয়েছে। এটি <স্ট্রিংয়ের উপাদানগুলির জন্য অপারেটর ব্যবহার করে। এটা অবশ্যই আমার নয়। আমি তা থেকে গ্রহণ এখানে (সাইট পোলিশ হয়। আমি অতীতে একবার এটি উপর পদস্খলিত এবং আমি যে ভালো কিছু এখন ইংরেজিতে খুঁজে পাইনি, তাই আমি দেন আমি কি আছে :))।

bool equiv_cyc(const string &u, const string &v)
{
    int n = u.length(), i = -1, j = -1, k;
    if (n != v.length()) return false;

    while( i<n-1 && j<n-1 )
    {
        k = 1;
        while(k<=n && u[(i+k)%n]==v[(j+k)%n]) k++;
        if (k>n) return true;
        if (u[(i+k)%n] > v[(j+k)%n]) i += k; else j += k;
    }
    return false;
}

+1 টি ... হে (ঢ) ঠিক হয় খুব এ আরো অনেক কিছু A থেকে গভীর Comp-Sci কোনো অ চেয়ে দৃষ্টিকোণ হে (ঢ) সমাধান :)
SyntaxT3rr0r

4
সময় মতো অনুকূল এবং কোড-আকারের কাছাকাছি-অনুকূল (বাইনারি এবং এলওসি উভয়) এর সমাধানের জন্য +1। এই উত্তরটি একটি ব্যাখ্যা দিয়ে আরও ভাল হবে।
আর .. গীটহাব বন্ধ করুন ICE

একেবারে হতবাক। আমাদের ব্যাখ্যা দরকার!
j_random_hacker

7

আমি এখানে এটি করা ভাল বলে মনে করি Java:

boolean isRotation(String s1,String s2) {
    return (s1.length() == s2.length()) && (s1+s1).contains(s2);
}

পার্লে আমি করব:

sub isRotation {
 my($string1,$string2) = @_;
 return length($string1) == length($string2) && ($string1.$string1)=~/$string2/;
}

বা আরও ভাল রেজেক্স পরিবর্তে সূচক ফাংশন ব্যবহার করে :

sub isRotation {
 my($string1,$string2) = @_;
 return length($string1) == length($string2) && index($string2,$string1.$string1) != -1;
}

1
তুমি ভুলে গেছ \Qমধ্যে /\Q$string2/
ক্রেজেন জাভিয়ার সিটেকার

3
\Qকোনও বিশেষ চরিত্রের উদ্ধৃতি $string2। এটি ছাড়া, .কোনও 1-বর্ণের স্ট্রিংয়ের ঘূর্ণন হিসাবে বিবেচিত হবে।
জ্যাকরবিত

6

এটি সবচেয়ে দক্ষ পদ্ধতি কিনা তা নিশ্চিত নন তবে এটি তুলনামূলকভাবে আকর্ষণীয় হতে পারে : বুড়ি-হুইলারের রূপান্তর । ডব্লিউপি নিবন্ধ অনুসারে, ইনপুটটির সমস্ত ঘূর্ণন একই আউটপুট দেয়। সংক্ষেপণের মতো অ্যাপ্লিকেশনগুলির জন্য এটি আকাঙ্ক্ষিত নয়, সুতরাং আসল আবর্তনটি নির্দেশিত হয় (উদাহরণস্বরূপ একটি সূচক দ্বারা; নিবন্ধটি দেখুন)। তবে সাধারণ আবর্তন-স্বাধীন তুলনার জন্য, এটি আদর্শ মনে হয়। অবশ্যই এটি আদর্শভাবে দক্ষ নয়!


যেহেতু বুরোস-হুইলারের রূপান্তরটিতে স্ট্রিংয়ের সমস্ত ঘূর্ণন গণনা করা জড়িত, এটি অবশ্যই সর্বোত্তম হতে চলেছে না .. :-)
আর .. গিটিহাব স্টপ হেল্পিং আইসিসি

6

প্রতিটি চরিত্রকে প্রশস্ততা হিসাবে নিয়ে যান এবং এগুলির উপর একটি পৃথক ফুরিয়ার রূপান্তর করুন। যদি তারা কেবল ঘোরার দ্বারা পৃথক হয় তবে ফ্রিকোয়েন্সি বর্ণালী গোলাকার ত্রুটির মধ্যে একই হবে। দৈর্ঘ্য 2 পাওয়ার না হওয়া পর্যন্ত অবশ্যই এটি অদক্ষ তাই আপনি এফএফটি করতে পারেন :-)


আমরা এটি একটি আকর্ষণীয় কোডিং অনুশীলন হিসাবে ব্যবহার করেছি, আমি নিশ্চিত নই যে আমরা এটি মূল্যায়ন করতে সক্ষম হব;)।
জয়শাও

এফএফটি আপত্তিজনক :) আমার কাছ থেকে +1
আমির

5

কেউ এখনও একটি মডুলো পদ্ধতির প্রস্তাব দেয়নি, সুতরাং এখানে একটি:

static void Main(string[] args)
{
    Console.WriteLine("Rotation : {0}",
        IsRotation("stackoverflow", "ztackoverflow"));
    Console.WriteLine("Rotation : {0}",
        IsRotation("stackoverflow", "ackoverflowst"));
    Console.WriteLine("Rotation : {0}",
        IsRotation("stackoverflow", "overflowstack"));
    Console.WriteLine("Rotation : {0}",
        IsRotation("stackoverflow", "stackoverflwo"));
    Console.WriteLine("Rotation : {0}",
        IsRotation("stackoverflow", "tackoverflwos"));
    Console.ReadLine();
}

public static bool IsRotation(string a, string b)
{
    Console.WriteLine("\nA: {0} B: {1}", a, b);

    if (b.Length != a.Length)
        return false;

    int ndx = a.IndexOf(b[0]);
    bool isRotation = true;
    Console.WriteLine("Ndx: {0}", ndx);
    if (ndx == -1) return false;
    for (int i = 0; i < b.Length; ++i)
    {
        int rotatedNdx = (i + ndx) % b.Length;
        char rotatedA = a[rotatedNdx];

        Console.WriteLine( "B: {0} A[{1}]: {2}", b[i], rotatedNdx, rotatedA );

        if (b[i] != rotatedA)
        {
            isRotation = false;
            // break; uncomment this when you remove the Console.WriteLine
        }
    }
    return isRotation;
}

আউটপুট:

A: stackoverflow B: ztackoverflow
Ndx: -1
Rotation : False

A: stackoverflow B: ackoverflowst
Ndx: 2
B: a A[2]: a
B: c A[3]: c
B: k A[4]: k
B: o A[5]: o
B: v A[6]: v
B: e A[7]: e
B: r A[8]: r
B: f A[9]: f
B: l A[10]: l
B: o A[11]: o
B: w A[12]: w
B: s A[0]: s
B: t A[1]: t
Rotation : True

A: stackoverflow B: overflowstack
Ndx: 5
B: o A[5]: o
B: v A[6]: v
B: e A[7]: e
B: r A[8]: r
B: f A[9]: f
B: l A[10]: l
B: o A[11]: o
B: w A[12]: w
B: s A[0]: s
B: t A[1]: t
B: a A[2]: a
B: c A[3]: c
B: k A[4]: k
Rotation : True

A: stackoverflow B: stackoverflwo
Ndx: 0
B: s A[0]: s
B: t A[1]: t
B: a A[2]: a
B: c A[3]: c
B: k A[4]: k
B: o A[5]: o
B: v A[6]: v
B: e A[7]: e
B: r A[8]: r
B: f A[9]: f
B: l A[10]: l
B: w A[11]: o
B: o A[12]: w
Rotation : False

A: stackoverflow B: tackoverflwos
Ndx: 1
B: t A[1]: t
B: a A[2]: a
B: c A[3]: c
B: k A[4]: k
B: o A[5]: o
B: v A[6]: v
B: e A[7]: e
B: r A[8]: r
B: f A[9]: f
B: l A[10]: l
B: w A[11]: o
B: o A[12]: w
B: s A[0]: s
Rotation : False

[সম্পাদনা: ২০১০-০৪-১২]

Piotr উপরে আমার কোডের ত্রুটি লক্ষ্য করেছেনস্ট্রিংয়ের প্রথম অক্ষরটি দু'বার বা তার বেশি ঘটলে এটি ত্রুটি করে। উদাহরণস্বরূপ, stackoverflowপরীক্ষার owstackoverflowফলস্বরূপ মিথ্যা হয়েছিল, যখন এটি সত্য হওয়া উচিত।

ত্রুটি চিহ্নিত করার জন্য পাইওটারকে ধন্যবাদ।

এখন, সংশোধিত কোডটি এখানে:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;

namespace TestRotate
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Rotation : {0}",
                IsRotation("stackoverflow", "ztackoverflow"));
            Console.WriteLine("Rotation : {0}",
                IsRotation("stackoverflow", "ackoverflowst"));
            Console.WriteLine("Rotation : {0}",
                IsRotation("stackoverflow", "overflowstack"));
            Console.WriteLine("Rotation : {0}",
                IsRotation("stackoverflow", "stackoverflwo"));
            Console.WriteLine("Rotation : {0}",
                IsRotation("stackoverflow", "tackoverflwos"));

            Console.WriteLine("Rotation : {0}",
                IsRotation("stackoverflow", "owstackoverfl"));

            Console.ReadLine();
        }

        public static bool IsRotation(string a, string b)
        {
            Console.WriteLine("\nA: {0} B: {1}", a, b);

            if (b.Length != a.Length)
                return false;

            if (a.IndexOf(b[0]) == -1 )
                return false;

            foreach (int ndx in IndexList(a, b[0]))
            {
                bool isRotation = true;

                Console.WriteLine("Ndx: {0}", ndx);

                for (int i = 0; i < b.Length; ++i)
                {
                    int rotatedNdx = (i + ndx) % b.Length;
                    char rotatedA = a[rotatedNdx];

                    Console.WriteLine("B: {0} A[{1}]: {2}", b[i], rotatedNdx, rotatedA);

                    if (b[i] != rotatedA)
                    {
                        isRotation = false;
                        break;
                    }
                }
                if (isRotation)
                    return true;
            }
            return false;
        }

        public static IEnumerable<int> IndexList(string src, char c)
        {
            for (int i = 0; i < src.Length; ++i)
                if (src[i] == c)
                    yield return i;
        }

    }//class Program
}//namespace TestRotate

এখানে ফলাফল:

A: stackoverflow B: ztackoverflow
Rotation : False

A: stackoverflow B: ackoverflowst
Ndx: 2
B: a A[2]: a
B: c A[3]: c
B: k A[4]: k
B: o A[5]: o
B: v A[6]: v
B: e A[7]: e
B: r A[8]: r
B: f A[9]: f
B: l A[10]: l
B: o A[11]: o
B: w A[12]: w
B: s A[0]: s
B: t A[1]: t
Rotation : True

A: stackoverflow B: overflowstack
Ndx: 5
B: o A[5]: o
B: v A[6]: v
B: e A[7]: e
B: r A[8]: r
B: f A[9]: f
B: l A[10]: l
B: o A[11]: o
B: w A[12]: w
B: s A[0]: s
B: t A[1]: t
B: a A[2]: a
B: c A[3]: c
B: k A[4]: k
Rotation : True

A: stackoverflow B: stackoverflwo
Ndx: 0
B: s A[0]: s
B: t A[1]: t
B: a A[2]: a
B: c A[3]: c
B: k A[4]: k
B: o A[5]: o
B: v A[6]: v
B: e A[7]: e
B: r A[8]: r
B: f A[9]: f
B: l A[10]: l
B: w A[11]: o
Rotation : False

A: stackoverflow B: tackoverflwos
Ndx: 1
B: t A[1]: t
B: a A[2]: a
B: c A[3]: c
B: k A[4]: k
B: o A[5]: o
B: v A[6]: v
B: e A[7]: e
B: r A[8]: r
B: f A[9]: f
B: l A[10]: l
B: w A[11]: o
Rotation : False

A: stackoverflow B: owstackoverfl
Ndx: 5
B: o A[5]: o
B: w A[6]: v
Ndx: 11
B: o A[11]: o
B: w A[12]: w
B: s A[0]: s
B: t A[1]: t
B: a A[2]: a
B: c A[3]: c
B: k A[4]: k
B: o A[5]: o
B: v A[6]: v
B: e A[7]: e
B: r A[8]: r
B: f A[9]: f
B: l A[10]: l
Rotation : True

ল্যাম্বডা পদ্ধতির এখানে:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace IsRotation
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Rotation : {0}",
                IsRotation("stackoverflow", "ztackoverflow"));

            Console.WriteLine("Rotation : {0}",
                IsRotation("stackoverflow", "ackoverflowst"));

            Console.WriteLine("Rotation : {0}",
                IsRotation("stackoverflow", "overflowstack"));
            Console.WriteLine("Rotation : {0}",
                IsRotation("stackoverflow", "stackoverflwo"));

            Console.WriteLine("Rotation : {0}",
                IsRotation("stackoverflow", "owstackoverfl"));

            string strToTestFrom = "stackoverflow";
            foreach(string s in StringRotations(strToTestFrom))
            {
                Console.WriteLine("is {0} rotation of {1} ? {2}",
                    s, strToTestFrom,
                    IsRotation(strToTestFrom, s) );
            }
            Console.ReadLine();
        }

        public static IEnumerable<string> StringRotations(string src)
        {
            for (int i = 0; i < src.Length; ++i)
            {
                var sb = new StringBuilder();
                for (int x = 0; x < src.Length; ++x)
                    sb.Append(src[(i + x) % src.Length]);

                yield return sb.ToString();
            }
        }

        public static bool IsRotation(string a, string b)
        {
            if (b.Length != a.Length || a.IndexOf(b[0]) < 0 ) return false;
            foreach(int ndx in IndexList(a, b[0]))
            {
                int i = ndx;
                if (b.ToCharArray().All(x => x == a[i++ % a.Length]))
                    return true;
            }
            return false;
        }

        public static IEnumerable<int> IndexList(string src, char c)
        {
            for (int i = 0; i < src.Length; ++i)
                if (src[i] == c)
                    yield return i;
        }

    }//class Program

}//namespace IsRotation

এখানে ল্যাম্বদা পদ্ধতির আউটপুট:

Rotation : False
Rotation : True
Rotation : True
Rotation : False
Rotation : True
is stackoverflow rotation of stackoverflow ? True
is tackoverflows rotation of stackoverflow ? True
is ackoverflowst rotation of stackoverflow ? True
is ckoverflowsta rotation of stackoverflow ? True
is koverflowstac rotation of stackoverflow ? True
is overflowstack rotation of stackoverflow ? True
is verflowstacko rotation of stackoverflow ? True
is erflowstackov rotation of stackoverflow ? True
is rflowstackove rotation of stackoverflow ? True
is flowstackover rotation of stackoverflow ? True
is lowstackoverf rotation of stackoverflow ? True
is owstackoverfl rotation of stackoverflow ? True
is wstackoverflo rotation of stackoverflow ? True

Int ndx = a.IndexOf (খ [0]) থেকে আপনার উত্তরটি সঠিক বলে আমি মনে করি না; স্ট্রিংয়ে b [0] এর একই মান সহ অন্যান্য উপাদান না থাকলে কেবলমাত্র কাজ করবে।
পাইওটর

ত্রুটি লক্ষ্য করার জন্য ধন্যবাদ এখনই এটি সংশোধন করেছেন
মাইকেল বুয়েন

3

যেহেতু কেউ সি ++ সমাধান দেয়নি। এটি এখানে:

bool isRotation(string s1,string s2) {

  string temp = s1;
  temp += s1;
  return (s1.length() == s2.length()) && (temp.find(s2) != string::npos);
}

দু'টি পয়েন্ট: দৈর্ঘ্য না মিলে গেলেও আপনি তুলনামূলকভাবে ব্যয়বহুল স্ট্রিং কনকনেটেশন করছেন; আপনি s2 রেফারেন্স দ্বারা পাস করতে পারে।
টনি ডেলরয়

2

অপেরার সাধারণ পয়েন্টার রোটেশন ট্রিকটি কাজ করে তবে চলমান সময়ে সবচেয়ে খারাপ ক্ষেত্রে এটি অত্যন্ত অদক্ষ। কেবল অক্ষরের বহু দীর্ঘ পুনরাবৃত্ত রান সহ একটি স্ট্রিং কল্পনা করুন, যেমন:

এস 1 = হেল্লোহেল্লো 1 হেল্লোহেল্লো 2

এস 2 = হেল্লোহেল্লো 2 হেল্লোহেল্লো 1

"লম্পট না হওয়া পর্যন্ত লম্পট, তারপরে একের মাধ্যমে বৃদ্ধি এবং আবার চেষ্টা করুন" গণনাগতভাবে একটি ভয়াবহ পন্থা।

আপনি অত্যধিক প্রয়াস ছাড়াই প্লেইন সিতে সংক্ষিপ্ত রূপটি করতে পারেন তা প্রমাণ করার জন্য, এখানে আমার সমাধানটি দেওয়া হল:

  int isRotation(const char* s1, const char* s2) {
        assert(s1 && s2);

        size_t s1Len = strlen(s1);

        if (s1Len != strlen(s2)) return 0;

        char s1SelfConcat[ 2 * s1Len + 1 ];

        sprintf(s1SelfConcat, "%s%s", s1, s1);   

        return (strstr(s1SelfConcat, s2) ? 1 : 0);
}

ওভারহেডে ও (এন) মেমরির ব্যবহার ব্যয় করে এটি চলমান সময়ে লিনিয়ার।

(নোট করুন যে স্ট্রাস্টার () এর প্রয়োগকরণ প্ল্যাটফর্ম-নির্দিষ্ট, তবে বিশেষত মস্তিষ্ক-মৃত, বায়ার-মুর আলগোরিদমের মতো দ্রুত বিকল্পের সাথে সর্বদা প্রতিস্থাপন করা যেতে পারে)


1
strstr()O (n + m) এ থাকা কোনও প্ল্যাটফর্ম সম্পর্কে আপনি কি জানেন ? এছাড়াও, যদি মানক (বা অন্য কোনও কিছু) আপনাকে রৈখিক চলমান সময়ের গ্যারান্টি দেয় না strstr(), আপনি পুরোপুরি অ্যালগরিদমের লিনিয়ার সময় সমতা আছে তা জোর দিয়ে বলতে পারবেন না।
jpalecek

যে কারণে আমি বলেছিলাম যে এটি বায়ার-মুর অ্যালগরিদম দ্বারা প্রতিস্থাপিত হতে পারে, এটি লিনিয়ার সময়ে চালিত করে।
RarrRarrRarr

আপনার বরাদ্দকরণের পদ্ধতিতে বেশ কয়েকটি সম্ভাব্য সমস্যা রয়েছে s1SelfConcat: এটি কেবল সি 9 এক্সের পর থেকেই সি ভেরিয়েবল অ্যারে মাপগুলিকে অনুমতি দেয় (যদিও জিসিসি এটি আরও দীর্ঘায়িত করেছে), এবং আপনি স্ট্যাকের উপর বড় স্ট্রিংগুলি বরাদ্দ করতে সমস্যায় পড়বেন। ইউসুফ ক্রেইনিন এই সমস্যাটি সম্পর্কে একটি মজাদার ব্লগ পোস্ট লিখেছিলেন । এছাড়াও, বায়ার-মুরের সাথে আপনার সমাধানটি চতুর্ভুজ সময়; আপনি কেএমপি চান
ক্রেজেন জাভিয়ার সিটেকার


2

আমি উত্তরটি পছন্দ করি যা এস 2 এস -1 এর সাথে সংমিশ্রিত এস 1 এর একটি স্ট্রিং কিনা তা যাচাই করে।

আমি একটি অপ্টিমাইজেশন যুক্ত করতে চেয়েছিলাম যা এটি কমনীয়তা হারাবে না।

স্ট্রিংগুলিকে সম্মতি দেওয়ার পরিবর্তে আপনি একটি যোগদানের ভিউ ব্যবহার করতে পারেন (আমি অন্য ভাষার জন্য জানি না, তবে সি ++ বুস্টের জন্য such এমন ধরণের মতামত সরবরাহ করে)।

স্ট্রিংয়ের ক্ষেত্রে অন্যটির স্ট্রিংগুলি রৈখিক গড় জটিলতা রয়েছে কিনা তা যাচাই করে (সবচেয়ে খারাপ ক্ষেত্রে জটিলতাটি চতুর্ভুজ হয়), এই অপ্টিমাইজেশনের গড় 2 গুনের গুণক দ্বারা গতি উন্নত করা উচিত।


2

একটি খাঁটি জাভা উত্তর (নাল চেকগুলি সান করে)

private boolean isRotation(String s1,String s2){
    if(s1.length() != s2.length()) return false;
    for(int i=0; i < s1.length()-1; i++){
        s1 = new StringBuilder(s1.substring(1)).append(s1.charAt(0)).toString();
        //--or-- s1 = s1.substring(1) + s1.charAt(0)
        if(s1.equals(s2)) return true;
    }
    return false;
}

2

এবং এখন সম্পূর্ণ ভিন্ন কিছু।

আপনি যদি কিছু বাধা প্রসঙ্গে সত্যই দ্রুত উত্তর চান যখন স্ট্রিংগুলি একে অপরের ঘূর্ণন নয়

  • উভয় স্ট্রিংয়ে কিছু অক্ষর ভিত্তিক চেকসাম (সমস্ত অক্ষরকে xore করার মতো) গণনা করুন। স্বাক্ষরগুলি পৃথক হলে স্ট্রিংগুলি একে অপরের ঘূর্ণন নয়।

সম্মত, এটি ব্যর্থ হতে পারে, তবে স্ট্রিংগুলি মেলে না এবং এটি যদি মিলছে তবে আপনি চেক করার জন্য স্ট্রিং কন্টেটিংয়ের মতো আরও একটি অ্যালগরিদম ব্যবহার করতে পারেন তা বলা খুব দ্রুত।


1

আরেকটি রুবি সমাধান উপর ভিত্তি করে উত্তর:

def rotation?(a, b); a.size == b.size and (b*2)[a]; end

1

পিএইচপি লিখতে strlenএবং strposফাংশনগুলি ব্যবহার করা খুব সহজ :

function isRotation($string1, $string2) {
    return strlen($string1) == strlen($string2) && (($string1.$string1).strpos($string2) != -1);
}

আমি strposঅভ্যন্তরীণভাবে কী ব্যবহার করে তা জানি না , তবে এটি কেএমপি ব্যবহার করলে এটি সময়মতো লিনিয়ার হবে।


1

একটি স্ট্রিং বিপরীত। উভয়ের এফএফটি নিন (তাদের পূর্ণসংখ্যার সাধারণ ক্রম হিসাবে বিবেচনা করুন)। ফলাফলগুলি একসাথে পয়েন্ট-ভিত্তিক গুণিত করুন। বিপরীত এফএফটি ব্যবহার করে ফিরে রূপান্তর করুন। যদি স্ট্রিংগুলি একে অপরের ঘূর্ণন হয় তবে ফলাফলটির একটি একক শিখর থাকবে - শিখরের অবস্থানটি একে অপরের প্রতি শ্রদ্ধার সাথে কতটা ঘোরানো হয় তা দ্বারা তা নির্দেশ করবে।


0

কেন এমন কিছু হয় না?


//is q a rotation of p?
bool isRotation(string p, string q) {
    string table = q + q;    
    return table.IndexOf(p) != -1;
}

অবশ্যই, আপনি নিজের ইন্ডেক্স অফ () ফাংশন লিখতে পারেন; আমি নিশ্চিত না .এনইটি একটি নিষ্কলুষ উপায় বা দ্রুততর উপায় ব্যবহার করে কিনা।

সাদাসিধা:


int IndexOf(string s) {
    for (int i = 0; i < this.Length - s.Length; i++)
        if (this.Substring(i, s.Length) == s) return i;
    return -1;
}

দ্রুত:


int IndexOf(string s) {
    int count = 0;
    for (int i = 0; i < this.Length; i++) {
        if (this[i] == s[count])
            count++;
        else
            count = 0;
        if (count == s.Length)
            return i - s.Length;
    }
    return -1;
}

সম্পাদনা: আমার বাইরের কিছু সমস্যা হতে পারে; চেক করার মতো মনে হয় না ;)


0

আমি পার্লে এটি করতাম :

sub isRotation { 
     return length $_[0] == length $_[1] and index($_[1],$_[0],$_[0]) != -1; 
}

0
int rotation(char *s1,char *s2)
{
    int i,j,k,p=0,n;
    n=strlen(s1);
    k=strlen(s2);
    if (n!=k)
        return 0;
    for (i=0;i<n;i++)
    {
        if (s1[0]==s2[i])
        {
            for (j=i,k=0;k<n;k++,j++)
            {
                if (s1[k]==s2[j])
                    p++;
                if (j==n-1)
                    j=0;
            }
        }
    }
    if (n==p+1)
      return 1;
    else
      return 0;
}

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.