আইসোমর্ফ স্ট্রিং আছে কিনা তা পরীক্ষা করুন


12

শব্দটি isomorphs হয় কিনা এবং আইসোমর্ফের সংজ্ঞা দেওয়ার জন্য এর প্রথম অংশটি অনুলিপি করে কিনা এই প্রশ্নটি চেকের একটি সম্প্রসারণ ।

অক্ষরের পুনরাবৃত্তির একই প্যাটার্ন থাকলে দুটি শব্দ isomorphs হয় । উদাহরণস্বরূপ, উভয় ESTATEএবং DUELEDপ্যাটার্ন আছেabcdca

ESTATE
DUELED

abcdca

কারণ 1 এবং 6 বর্ণগুলি একই, 3 এবং 5 বর্ণগুলি একই, এবং আরও কিছু নয়। এর অর্থ এটিও মিলে যাওয়ার সাথে শব্দগুলি একটি বিকল্প সাইফারের সাথে সম্পর্কিত E <-> D, S <-> U, T <-> E, A <-> L

দুটি স্ট্রিং X এবং Y দেওয়া হয়েছে, এক্স এর সাথে Y এর চেয়ে আর বেশি নয়, কাজটি নির্ধারণ করা হবে যে Y এর একটি স্তর আছে যা X এর সাথে একটি আইসোমর্ফ রয়েছে if

ইনপুট: a..zA..Z এর দুটি খালি খালি অক্ষরের স্ট্রিং যা প্রতি লাইনে একটি স্ট্রিং। এটি স্ট্যান্ডার্ড ইনপুট থেকে আসবে।

আউটপুট দ্বিতীয় স্ট্রিংয়ের একটি স্ট্রিং যা প্রথম স্ট্রিং সহ একটি আইসোমর্ফ হয়, যদি এরকম কোনও উপস্থিত থাকে। অন্যথায় আউটপুট "না!"।

নিয়মাবলী আপনার কোডটি ইনপুটটির মোট দৈর্ঘ্যে রৈখিক সময়ে চলতে হবে।

স্কোর আপনার স্কোরটি আপনার কোডের বাইট সংখ্যা। সবচেয়ে কম বাইট জেতা


উদাহরণ ইনপুট এবং আউটপুট

adca
ddaddabdaabbcc

dabd

ডগা

সেখানে এক না অন্তত এ জন্য যে জটিল, কার্যত দ্রুত এবং এই সমস্যার রৈখিক সময় সমাধান।


@AlexA। আমার মনে হয় কেউ আমাকে বলেছিল যে আপনি যদি চলমান সময় / জটিলতা সীমাবদ্ধ করেন তবে তা কোড-চ্যালেঞ্জ হওয়া উচিত। অবশ্যই যদি তা ভুল হয় তবে আমি এটি পরিবর্তন করে খুশি।

7
যদি রান সময়টি একটি নিয়মের সাথে আবদ্ধ হয় এবং স্কোরিংকে প্রভাবিত না করে, কোড-গল্ফ কোড-চ্যালেঞ্জের চেয়ে ভাল ফিট।
ডেনিস

রৈখিক সময়ের অর্থ এটি ও (এম + এন) এবং ও (এমএক্সএন) না ও ও (এমএক্স (এনএম)) হওয়া দরকার যেখানে এম, এন প্রথম এবং দ্বিতীয় স্ট্রিংয়ের দৈর্ঘ্য?
কিছু ব্যবহারকারী

@ সুমিউসার হ্যাঁ এর অর্থ ও (মি + এন)।

1
@ বেটাডেকে দেখুন "এক্স এবং ওয়াইয়ের দুটি স্ট্রিং দেওয়া হয়েছে, এক্স এর সাথে Y এর চেয়ে আর বেশি নয়, কাজটি নির্ধারণ করা হবে যে Y এর কোন স্ট্রিং রয়েছে যা X এর সাথে একটি সমকোণীয় is"

উত্তর:


8

পাইথন 2, 338 326 323 321 310 306 297 293 290 289 280 279 266 264 259 237 230 229 226 223 222 220 219 217 ( 260 238 231 228 225 223 221 220 218 0 প্রস্থান স্থিতি সহ)

exec'''s=raw_input()
S=[M-s.rfind(c,0,M)for M,c in enumerate(s)]
k=0
j=x=%s
while k<=M+x:
 if S[k]>j<W[j]or S[k]==W[j]:
    k+=1;j+=1;T+=[j]
    if j-L>x:print s[k-j:k];z
 else:j=T[j]
'''*2%('-1;T=[0];W=S;L=M',0)
print'No!'

অ্যালগরিদম হ'ল কেএমপির একটি প্রকরণ, চরিত্রের মিলের জন্য সূচক ভিত্তিক পরীক্ষা ব্যবহার করে। মূল ধারণাটি হ'ল আমরা যদি পজিশনে কোনও অমিল পেয়ে থাকি X[i]তবে আমরা ম্যাচের জন্য পরবর্তী সম্ভাব্য জায়গায় ফিরে যেতে পারি of এর দীর্ঘতম প্রত্যয়টি X[:i]একটি উপসর্গের আইসোমরফিক X

বাম থেকে ডানে কাজ করে আমরা প্রতিটি অক্ষরকে সেই চরিত্রের সাম্প্রতিকতম পূর্ববর্তী উপস্থিতির দূরত্বের সমান সূচক নির্ধারণ করি, বা যদি পূর্বের কোনও উপস্থিতি না থাকে তবে আমরা বর্তমান স্ট্রিং উপসর্গটির দৈর্ঘ্য গ্রহণ করি। উদাহরণ স্বরূপ:

MISSISSIPPI
12313213913

দুটি অক্ষর মেলে কিনা তা পরীক্ষা করতে আমরা সূচকগুলি তুলনা করি, বর্তমান (উপ) স্ট্রিংয়ের দৈর্ঘ্যের চেয়ে বড় সূচকগুলির জন্য যথাযথভাবে সামঞ্জস্য করি।

কেএমপি অ্যালগরিদম একটু সরল হয়ে যায় কারণ আমরা প্রথম চরিত্রটিতে কোনও অমিল পেতে পারি না।

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

দ্রষ্টব্য: কম্পিউটিং সূচকগুলির জন্য, আমরা ব্যবহার করতে পারি str.rfind(অভিধানটি ব্যবহার করে আমার আগের পদ্ধতির বিপরীতে) এবং এখনও রৈখিক জটিলতা ধরে রেখে ধরে নিচ্ছি যে str.rfindশেষ থেকে অনুসন্ধান শুরু হবে (যা একমাত্র বুদ্ধিমান প্রয়োগের পছন্দ বলে মনে হচ্ছে) - বর্ণমালার প্রতিটি অক্ষরের জন্য , আমাদের কখনই স্ট্রিংয়ের একই অংশটি দু'বার অতিক্রম করতে হয় না, সুতরাং (বর্ণমালার আকার) * (স্ট্রিংয়ের আকার) তুলনার একটি উপরের বাউন্ড থাকে।

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

e=lambda a:a>i<W[i]or a==W[i]
exec('s=raw_input();S=[];p={};M=i=0\nfor c in s:S+=[M-p.get(c,-1)];p[c]=M;M+=1\nW=S;L=M;'*2)[:-9]
T=[0]*L
k=1
while~k+L:
 if e(W[k]):i+=1;k+=1;T[k]=i
 else:i=T[i]
m=i=0
while m+i<M:
 if e(S[m+i]):
    if~-L==i:print s[m:m+L];z
    i+=1
 else:m+=i-T[i];i=T[i]
print'No!'

eফাংশন পরীক্ষা অক্ষরের সমানতা। execবিবৃতি সূচকের নির্ধারণ এবং কিছু পরিবর্তনশীল initialisations আছে। Xপিছনে ফিরে আসা মানগুলির জন্য প্রথম লুপ প্রক্রিয়া , এবং দ্বিতীয় লুপটি স্ট্রিং অনুসন্ধান করে।

আপডেট: এখানে এমন একটি সংস্করণ যা পরিষ্কারভাবে প্রস্থান করে, এক বাইটের দামে:

r='No!'
exec'''s=raw_input()
S=[M-s.rfind(c,0,M)for M,c in enumerate(s)]
k=0
j=x=%s
while k<=M+x:
 if S[k]>j<W[j]or S[k]==W[j]:
    k+=1;j+=1;T+=[j]
    if j-L>x:r=k=s[k-j:k]
 else:j=T[j]
'''*2%('-1;T=[0];W=S;L=M',0)
print r

আমি মনে করি আপনি পাইথন 3 করে একটি বাইট সংরক্ষণ করতে পারেন। r=raw_inputবনাম r = input4 বাইট সংরক্ষণ করে এবং মুদ্রণের
প্যারেনগুলি

@ মালটিসেন মন্তব্যটির জন্য ধন্যবাদ। আমি এটি লেখার সময় পাইথন 3 বিবেচনা করি নি, তবে ব্যয় এবং সঞ্চয় হিসাবে, পাইথন 3-তে ইন্ডেন্টেশন করার জন্য স্পেস এবং ট্যাবগুলি মিশ্রিত করতে না পারায় অতিরিক্ত 2 বাইট ব্যয় করতে হবে
মিচ শোয়ার্জ

@ মাল্টেসেন কেবলমাত্র অনুসরণ করতে, বিষয়টি এখন আর ট্যাব নয় তবে বন্ধনী হিসাবে রয়েছে exec
মিচ শোয়ার্টজ

এটি সত্যিই দুর্দান্ত উত্তর! আমি এখন সিজেমে এটি দেখার অপেক্ষায় রয়েছি :)

6

পাইথন 3, 401 বাইট

import string,itertools
X=input()
Y=input()
x=len(X)
t=[-1]+[0]*~-x
j=2
c=0
while j<x:
 if X[j-1]==X[c]:c+=1;t[j]=c;j+=1
 elif c>0:c=t[c]
 else:t[j]=0;j+=1
s=string.ascii_letters
*b,=map(s.find,X)
for p in itertools.permutations(s):
 m=i=0
 while m+i<len(Y):
  if p[b[i]]==Y[m+i]:
   if~-x==i:print(Y[m:m+x]);exit()
   else:i+=1
  else:
   if-1<t[i]:m+=i-t[i];i=t[i]
   else:i=0;m+=1
else:print("No!")

এটি এখনও বেশিরভাগই নিখরচায়, তবে আমি মনে করি এটি কাজ করা উচিত। মূল অ্যালগরিদম হ'ল কেএমপি , এবং একটি অতিরিক্ত উপাদান যা বর্ণমালার আকারে যুক্তিযুক্ত (যা ভাল, যেহেতু বর্ণমালা ধ্রুবক)। অন্য কথায়, এটি / সম্পূর্ণরূপে অবৈজ্ঞানিক লিনিয়ার অ্যালগোরিদম হওয়া উচিত।

বিশ্লেষণে সহায়তা করার জন্য এখানে কয়েকটি মন্তব্য রয়েছে:

# KMP failure table for the substring, O(n)
t=[-1]+[0]*~-x
j=2
c=0
while j<x:
 if X[j-1]==X[c]:c+=1;t[j]=c;j+=1
 elif c>0:c=t[c]
 else:t[j]=0;j+=1

# Convert each char to its index in a-zA-Z, O(alphabet * n)
s=string.ascii_letters
*b,=map(s.find,X)

# For every permutation of letters..., O(alphabet!)
for p in itertools.permutations(s):
 # Run KMP, O(n)
 m=i=0
 while m+i<len(Y):
  if p[b[i]]==Y[m+i]:
   if~-x==i:print(Y[m:m+x]);exit()
   else:i+=1
  else:
   if-1<t[i]:m+=i-t[i];i=t[i]
   else:i=0;m+=1
else:print("No!")

পরীক্ষার জন্য, আপনি এর sচেয়েও ছোট বর্ণমালা দিয়ে প্রতিস্থাপন করতে পারেন string.ascii_letters


2

এপিএল (ডায়ালগ) , 32 বাইট

এটি একটি ইনফিক্স ফাংশন, এক্সকে বাম আর্গুমেন্ট হিসাবে এবং Y কে ডান আর্গুমেন্ট হিসাবে গ্রহণ করবে।

{(s,⊂'No!')⊃⍨(⍳⍨¨s←⍵,/⍨≢⍺)⍳⊂⍳⍨⍺}

এটি অনলাইন চেষ্টা করুন!

{... } বেনামী ল্যামডা যেখানে এবং প্রতিনিধিত্ব আর্গুমেন্টগুলি (X এবং Y)

⍳⍨⍺X n এর নেক্সেক্স সেলফি ( এক্সে এক্স এর উপাদানগুলির প্রথম সংঘটিতের d n সূত্র)

 ঘেরযুক্ত করুন যাতে আমরা পুরো প্যাটার্নটির সন্ধান করতে পারি

(… এর মধ্যে প্রথম ঘটনার )⍳first ndex…

  ≢⍺ X এর ট্যালি (দৈর্ঘ্য)

  ⍵,/⍨ Y এর আকারের সমস্ত সাবস্ট্রিংগুলি (লিটল those এগুলির মধ্যে একত্রীকরণ হ্রাস, তবে এটি কোনও অপশন নয়)

  s← সংরক্ষণ s(জন্য গুলি ubstrings)

  ⍳⍨¨each ndex এর প্রত্যেকটির সেলফি

 এখন আমাদের কাছে প্রথম প্যাটার্নের সূচক বা কোনও মিল খুঁজে পাওয়া না গেলে 1 + প্যাটার্নের সংখ্যা রয়েছে

()⊃⍨ সেই সূচকটি থেকে বেছে নিতে ব্যবহার করুন ...

  ⊂'No!' বদ্ধ স্ট্রিং (যাতে এটি একক উপাদান হিসাবে কাজ করে)

  s, সঙ্গে preend s

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