ও (1) অতিরিক্ত স্থান ব্যবহার করে দুটি স্ট্রিং একে অপরের অনুমতি দেওয়া আছে কিনা তা কীভাবে পরীক্ষা করবেন?


13

দুটি স্ট্রিং দেওয়া আছে কীভাবে আপনি ও (1) স্পেস ব্যবহার করে একে অপরের ক্রমবিন্যাস কিনা তা পরীক্ষা করে দেখতে পারেন? স্ট্রিংগুলি সংশোধন করা কোনওভাবেই অনুমোদিত নয়।
দ্রষ্টব্য: উভয় স্ট্রিংয়ের দৈর্ঘ্য এবং বর্ণমালার আকারের ক্ষেত্রে ও (1) স্থান।


3
আপনি কি মনে করেন? আপনি কী চেষ্টা করেছেন এবং কোথায় আটকে গেছেন? স্ট্রিংগুলি কি ধ্রুব আকারের বর্ণমালার উপরে থাকে? আপনি কি তাদের হিস্টোগ্রামগুলি গণনা করার চেষ্টা করেছেন?
যুবাল ফিল্মাস

@ ইউভালফিল্মাস এটি স্ট্রিংয়ের দৈর্ঘ্য এবং বর্ণমালার আকার উভয় ও (1) স্থান হওয়া উচিত
বেনামে

এটি পরিষ্কারভাবে অসম্ভব বলে মনে হচ্ছে। যে কোনও অ্যালগরিদমের কমপক্ষে একটি স্ট্রিং বা একটি একক অক্ষরে একটি অবস্থান সঞ্চয় করতে অতিরিক্ত স্থানের প্রয়োজন হবে। এই জিনিসগুলির কোনওটিই ও (1) নয়।
ডেভিড শোয়ার্জ

@ ডেভিডশওয়ার্টজ - কিভাবে? ও (1) অর্থ ধ্রুবক, একটি বুট নয়। স্ট্রিংটি কত দীর্ঘ তা বিবেচনাধীন নয়, এতে অবস্থানটি একটি সংখ্যা।
Davor

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

উত্তর:


7

নিষ্পাপ দৃষ্টিভঙ্গি উভয় স্ট্রিংয়ের হিস্টোগ্রাম তৈরি করা এবং সেগুলি একই কিনা তা পরীক্ষা করা হবে। যেহেতু আমাদের এমন একটি ডেটা স্ট্রাকচার (যার আকার বর্ণমালার আকারের সাথে লিনিয়ার হতে পারে) সংরক্ষণ করার অনুমতি নেই, তাই আমাদের প্রতিটি সম্ভাব্য চিহ্নের উপস্থিতিগুলি অন্যগুলির পরে গণনা করতে হবে:

function count(letter, string)
    var count := 0
    foreach element in string
        if letter = element
            count++
    return count

function samePermutation(stringA, stringB)
    foreach s in alphabet
        if count(s, stringA) != count(s, stringB)
            return false
    return true

এটি অবশ্যই ধরে নিয়েছে যে গণনাগুলি এবং পুনরুক্তি সূচকগুলি স্ট্রিংয়ের দৈর্ঘ্যের উপর নির্ভরশীল না হয়ে স্থির আকারের পূর্ণসংখ্যা হয়।


একটি অপ্টিমাইজেশন হিসাবে, আপনি একটি অ্যারের উপরে যেতে পারেন এবং কেবলমাত্র আপনার মুখোমুখি হওয়া অক্ষরের হিস্টোগ্রামগুলি গণনা করতে পারেন। এইভাবে বর্ণমালা আকারের চেয়ে জটিল হয়ে যায়।
যুবাল ফিল্মাস

@ ইউভালফিল্মাস মন্তব্যে প্রসারিত করতে আপনার 1 টিও পরীক্ষা করতে হবে) স্ট্রিংয়ের দৈর্ঘ্য একই বা 2) উভয় ইনপুট স্ট্রিংয়ের উপরে পুনরাবৃত্তি হবে কিনা তা পরীক্ষা করে দেখুন। আপনার এগুলির একটি প্রয়োজন কারণ এটি সম্ভব একটিতে কয়েকটি অক্ষর অন্যটিতে নেই। বিকল্প 1 এর গণনা কম হওয়া উচিত।
বার্নসবিএ

@ ইউভালফিল্মাস আমি এড়াতে চেয়েছিলাম যেহেতু এটি চতুর্ভুজ সময় জটিলতার অর্থ হ'ল, আমি বর্ণমালাটি গড় স্ট্রিংয়ের আকারের চেয়ে ছোট হওয়ার আশা করতাম। ছোট স্ট্রিং এবং অর্ডারযুক্ত বর্ণমালার জন্য, আমি অভ্যন্তরীণ লুপের গণনার সাথে পরবর্তী ক্ষুদ্রতম উপস্থিত চিহ্নকে গণনা করার বিষয়টি বিবেচনা করব, যাতে কোনও বর্ণমালার লুপের কয়েকটি পুনরাবৃত্তি বাদ দিতে পারে - এর জটিলতার সাথে O(n * min(n, |Σ|))। এইচএম, এখন আমি এটি সম্পর্কে চিন্তা করি, এটি আপনার উত্তর থেকে "পুনরাবৃত্তি করার অনুমতি দেওয়া" সমাধানের মতো মনে হচ্ছে, তাই না?
বার্গি

countনয় O(1)(অর্থাত এটি উপচে পড়তে পারে)
পুনরায় পোস্ট করুন

1
@ আন্তঃকোড আমি কখনই বলিনি যে countএটি int:-) হ্যাঁ, এটি কাজ করবে না, তবে জাভাতে যে কোনওভাবেই ঘটতে পারে না
বার্গি

12

দ্বারা অ্যারেগুলি চিহ্নিত করুন এবং ধরুন এগুলির দৈর্ঘ্য nA,Bn

মনে করুন প্রথমে প্রতিটি অ্যারের মানগুলি পৃথক are এখানে একটি আলগোরিদিম যা স্থান ব্যবহার করে:O(1)

  1. উভয় অ্যারের ন্যূনতম মানগুলি গণনা করুন এবং সেগুলি অভিন্ন কিনা তা পরীক্ষা করুন।

  2. উভয় অ্যারের দ্বিতীয় ন্যূনতম মানগুলি গণনা করুন এবং সেগুলি অভিন্ন কিনা তা পরীক্ষা করুন।

  3. ইত্যাদি।

O(1)k(k+1)k

যখন উপাদানগুলিকে পুনরাবৃত্তি করার অনুমতি দেওয়া হয়, আমরা নীচে আলগোরিদিমটি সংশোধন করি:

  1. mA,1,mB,1mA,1=mB,1

  2. mA,2,mB,2mA,1,mB,1mA,2=mB,2

  3. ইত্যাদি।


1
O(n2)O(1)

4
O(lgn)O(1)

7
গণনা প্রয়োজন (লোগারিদমিক) স্থান প্রয়োজন, কিন্তু - স্থান ব্যবহারের এই সংজ্ঞা অনুসারে - এমনকি অ্যারের মাধ্যমে পুনরাবৃত্তিও করে না। সুতরাং, স্থান ব্যবহারের কঠোর অর্থের অধীনে, অবিচ্ছিন্ন স্থানে এটি করার কোনও উপায় নেই।
ড্যানিয়েল জোর

4
@ ড্যানিয়েলজুর, এটি নির্ভর করে আপনি কোন দামের মডেলটি ব্যবহার করছেন। অভিন্ন খরচে, ধ্রুব স্থানে এটি সম্ভব।
রায়ান

7
আপনি যদি কেবলমাত্র স্থির সংখ্যক বিটের অনুমতি পেয়ে থাকেন তবে আপনি কেবল ধ্রুব আকারের বর্ণমালা পরিচালনা করতে পারেন (এটি নিয়মিত ভাষার তত্ত্ব থেকে অনুসরণ করা হয়)।
যুবাল ফিল্মাস

2

কিছু ফাংশন সংজ্ঞা দিন (সি) যা কিছু অক্ষর সিটিকে একটি অনন্য প্রাথমিক সংখ্যাতে মানচিত্র করে (a = 2, b = 3, c = 5, ইত্যাদি)।

set checksum = 1
set count = 0 <-- this is probably not even necessary, but it's another level of check
for character c in string 1
    checksum = checksum * f(c)
    count = count + 1
for character c in string 2
    checksum = checksum / f(c)
    count = count = 1

permutation = count == 0 and checksum == 1

O(1)


f(c)O(1)O(1)

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

4
O(logn)

4
Θ(n)n

0

আপনি এটি করতে পারেন O(nlogn)। দুটি স্ট্রিং বাছাই করুন এবং সূচকে সূচকের সাথে তাদের তুলনা করুন। এগুলির যে কোনও জায়গায় পার্থক্য থাকলে তারা একে অপরের অনুমতি নয়।

একটি O(n)সমাধানের জন্য, হ্যাশিং ব্যবহার করা যেতে পারে। এই হ্যাশিং ফাংশনটি কাজ করবে এবং যে eকোনও চিঠির জন্য এটির মূল্যমান হবে। যদি স্ট্রিংগুলির দুটি হ্যাশগুলি পৃথক হয় তবে সেগুলি একে অপরের অনুমতি নয়।

লিঙ্কটিতে হ্যাশিং ফাংশন:

একজন সম্ভাব্য প্রার্থী এটি হতে পারে। একটি বিজোড় পূর্ণসংখ্যা আর ঠিক করুন প্রতিটি উপাদান এবং আপনি হ্যাশ ফ্যাক্টর (R + 2 * ই) গণনা করতে চান। তারপরে এই সমস্ত কারণগুলির পণ্য গণনা করুন। অবশেষে হ্যাশ পেতে পণ্যটি 2 দ্বারা ভাগ করুন।

(আর + 2 ই) 2-এর ফ্যাক্টরটি গ্যারান্টি দেয় যে সমস্ত উপাদানগুলি বিজোড়, তাই পণ্যটি কখনই 0 হয়ে যাবে এড়ানো এড়ানো 2 শেষে ভাগ কারণ পণ্যটি সর্বদা অদ্ভুত থাকবে, সুতরাং বিভাগটি কেবল একটি ধ্রুবক বিটকে সরিয়ে দেয় ।

উদাহরণস্বরূপ, আমি আর = 1779033703 নির্বাচন করি This এটি একটি স্বেচ্ছাসেবী পছন্দ, কিছু পরীক্ষা-নিরীক্ষা করা দেখানো উচিত যদি প্রদত্ত আর ভাল হয় না খারাপ। ধরে নিন আপনার মানগুলি [1, 10, 3, 18]। পণ্যটি (32-বিট ইনট ব্যবহার করে গণনা করা) is

(আর + ২) * (আর +২০) * (আর + 6) * (আর +৩)) = ৩7767২৪৩১১ সুতরাং হ্যাশটি হবে

3376724311/2 = 1688362155।

আর এর মান পরিবর্তন করে ডাবল হ্যাশিং (বা আরও বেশি পরিমাণে করার জন্য) ব্যবহার করা তাদের খুব উচ্চ সম্ভাবনার সাথে ক্রমবর্ধমান হিসাবে সফলভাবে সনাক্ত করতে পারে ।


1
আপনি স্ট্রিংগুলি সংশোধন করার অনুমতি না পাওয়ায় আপনি বাছাই করতে পারবেন না। হ্যাশিংয়ের ক্ষেত্রে এটি একটি এলোমেলোম অ্যালগরিদম যা ভুল উত্তর দিতে পারে।
যুবাল ফিল্মাস

0

ধরা যাক আপনার কাছে দুটি স্ট্রিং রয়েছে যা এস এবং টি বলে।

তারা বৈষম্য নয় তা নিশ্চিত করার জন্য আপনি হুরিস্টিকস ব্যবহার করতে পারেন।

  1. s.length == t.leth
  2. s এর বর্ণের যোগফল = = টির মধ্যে অক্ষরের যোগফল
  3. [২. হিসাবে একই তবে যোগারের পরিবর্তে xor সহ]

এর পরে আপনি স্ট্রিং সমান কিনা তা প্রমাণ করতে খুব সহজেই একটি অ্যালগরিদম চালাতে পারেন।

  1. একটি স্ট্রিংকে অন্যটির সাথে সমান করে তুলনা করুন (ও (এন ^ 2))
  2. উভয়কে বাছাই করুন এবং তুলনা করুন (ও (2n লগ (এন))
  3. উভয় স্ট্রিংয়ে একই পরিমাণ রয়েছে কিনা এর জন্য প্রতিটি চরের জন্য পরীক্ষা করুন (O (n ^ 2))

আপনার অতিরিক্ত স্থান ব্যবহারের অনুমতি না থাকলে অবশ্যই আপনি এই দ্রুত বাছাই করতে পারবেন না। সুতরাং আপনি কোন অ্যালগরিদমটি চয়ন করেন তা বিবেচনা করে না - প্রতিটি অ্যালগরিদম O (n ^ 2) সময়ে চলবে যখন কেবল ও (1) স্থান থাকবে এবং যদি হিউরিস্টিক প্রমাণ করতে সক্ষম হয় যে তারা সমান হতে পারে না।


3
" স্ট্রিংগুলিকে কোনওভাবেই পরিবর্তন করার অনুমতি নেই is "
বার্গি

0

পুরো রুটিনের জন্য সি-স্টাইল কোডে:

for (int i = 0; i < n; i++) {
   int k = -1;
   next: for (int j = 0; j <= i; j++)
       if (A[j] == A[i]) {
          while (++k < n)
              if (B[k] == A[i])
                  continue next;
          return false; // note at this point j == i
       }
}
return true; 

বা খুব ভার্বোস সিউডো কোডে (1-ভিত্তিক সূচক ব্যবহার করে)

// our loop invariant is that B contains a permutation of the letters
// in A[1]..A[i-1]
for i=1..n
   if !checkLetters(A, B, i)
      return false
return true

যেখানে ফাংশন চেকলেটারগুলি (A, B, i) পরীক্ষা করে যে যদি A [1] এ [i] এর এম কপি থাকে .. A [i], তবে বিতে কমপক্ষে A [i] এর এম কপি রয়েছে:

checkLetters(A,B,i)
    k = 0 // scan index into B
    for j=1..i
      if A[j] = A[i]
         k = findNextValue(B, k+1, A[i])
         if k > n
            return false
    return true

এবং ফাংশন ফাইন্ড নেক্সটভ্যালু বিতে সূচক থেকে শুরু হওয়া কোনও মানটির জন্য অনুসন্ধান করে এবং যেখানে এটি পাওয়া যায় সেখানে সূচকটি ফেরত দেয় (বা এন + 1 না পাওয়া গেলে)।

n2


আপনি কি দয়া করে আপনার সি কোডটি সিউডোকোডে রূপান্তর করতে পারবেন? এটি কোনও প্রোগ্রামিং সাইট নয়।
যুবাল ফিল্মাস

এটি বার্গির উত্তরের অন্য রূপের মতো বলে মনে হচ্ছে (কিছু অসংলগ্ন পার্থক্য সহ)।
যুবাল ফিল্মাস

O(nm)O(n2)

0

O(n3n

লুপের মাধ্যমে string1এবং string2, যে চরিত্র চেক জন্য কত ঘন ঘন এটা খুঁজে পাওয়া যেতে পারে string1এবং string2। আমি একটি চরিত্র অন্য স্ট্রিংয়ের তুলনায় এক স্ট্রিংয়ের সাথে প্রায়শই আছি, এটি কোনও ক্রমশক্তি নয়। যদি সমস্ত অক্ষরের ফ্রিকোয়েন্সি সমান হয় তবে স্ট্রিংগুলি একে অপরের ক্রমান্বয়।

এই সুনির্দিষ্ট করার জন্য এখানে অজগরটির একটি টুকরো দেওয়া হয়েছে

s1="abcaba"
s2="aadbba"

def check_if_permutations(string1, string2):
  for string in [string1, string2]:
    # string references string1 
    #  string2, it is not a copy
    for char in string:
      count1=0
      for char1 in string1:
        if  char==char1:
          count1+=1
      count2=0
      for char2 in string2:
        if  char==char2:
          count2+=1
      if count1!=count2:
        print('unbalanced character',char)
        return()
  print ("permutations")
  return()

check_if_permutations(s1,s2)

stringstring1string2charchar1char2O(logn)count1count2string[string1, string2]

অবশ্যই আপনার এমনকি কাউন্ট ভেরিয়েবলের প্রয়োজন নেই তবে পয়েন্টার ব্যবহার করতে পারেন।

s1="abcaba"
s2="aadbba"

def check_if_permutations(string1, string2):
  for string in [string1, string2]:
    # string references one of string1 
    # or string2, it is not a copy
    for char in string:
      # p1 and p2 should be views as pointers
      p1=0
      p2=0
      while (p1<len(string1)) and (p2<len(string2)):
        # p1>=len(string1): p1 points to beyond end of string
        while (p1<len(string1)) and (string1[p1]!=char) :
          p1+=1
        while(p2<len(string2)) and (string2[p2]!=char):
          p2+=1
        if (p1<len(string1)) != (p2<len(string2)):
          print('unbalanced character',char)
          return()
        p1+=1
        p2+=1
  print ("permutations")
  return()

check_if_permutations(s1,s2)

O(log(n))

n


এটি নীচে বার্গির সমাধান হিসাবে একই।
যুবাল ফিল্মাস

@ ইউভালফিল্মাস নং, এটি পুরো বর্ণমালায় পুনরাবৃত্তি করে না এবং তাই এর রানটাইম বর্ণমালার আকারের উপর নির্ভর করে না। এটি কেবল দুটি স্ট্রিং ব্যবহার করে যা পরীক্ষা করা উচিত। এছাড়াও দ্বিতীয় প্রোগ্রাম গণনা এড়ানো হয়।
चमत्कार 173

@ ইউভালফিল্মাস আমি এখন দেখতে পাচ্ছি যে আপনার এবং অন্যান্য মন্তব্যগুলি আমার প্রোগ্রামে আমি যেভাবে ব্যবহার করেছি তার দিকে নির্দেশ করে।
चमत्कार 173
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.