ค้นหาระยะทางแก้ไขต่ำสุดระหว่างสองสตริง


13

คำอธิบาย

แก้ไขระยะห่างระหว่างสองสายเป็นหน้าที่ของจำนวนที่น้อยที่สุดของการแทรกการลบหรือแทนการแปลงหนึ่งคำลงในคำอื่น

ค่าใช้จ่ายในการแทรกและลบ 1 และค่าทดแทน 2

ตัวอย่างเช่นระยะห่างระหว่างABและAคือ 1 เนื่องจากการลบมีค่าใช้จ่าย 1 และการแก้ไขที่จำเป็นเท่านั้นคือการลบBอักขระ

ระยะห่างระหว่างCARและFARคือ 2 เนื่องจากการทดแทนมีค่าใช้จ่าย 2 วิธีอื่นในการดูที่นี้คือการลบหนึ่งครั้งและการแทรกหนึ่งครั้ง

กฎระเบียบ

กำหนดให้มีสองสายอินพุต (ที่ให้มา แต่สะดวกในภาษาของคุณ) โปรแกรมของคุณต้องค้นหาระยะทางแก้ไขขั้นต่ำระหว่างสองสาย

คุณอาจสมมติว่าสตริงมีอักขระเท่านั้นA-Zและมีน้อยกว่า 100 อักขระและมากกว่า 0 อักขระ

นี่คือรหัสกอล์ฟดังนั้นทางออกที่สั้นที่สุดชนะ

กรณีทดสอบตัวอย่าง

ISLANDER, SLANDER
> 1
MART, KARMA
> 5
KITTEN, SITTING
> 5
INTENTION, EXECUTION
> 8

ฉันทำสิ่งนี้ใน excel ในคลาสอัลกอริทึม รู้สึกสนุกที่ได้เปิดโครงการเป็นเอกสาร. xls มันใช้งานได้ดีจริง ๆ ฉันจะดูว่าฉันสามารถหาได้
captncraig

PHP ควรจะชนะสิ่งนี้ได้อย่างง่ายดาย
st0le

@ st0le - levenshteinฟังก์ชั่นในตัวจะถือว่าการแทนที่เป็นหนึ่งการแก้ไข (ทดแทน) ไม่ใช่สอง (ลบ + แทรก)
Mr. Llama

คำตอบ:


7

brainfuck, 2680

+>>>>>>>>>>>>>>>>>>>>>>++++++>,<[->-----<]>--[+++++++++++++++++++++
+++++++++++>>[->>+<<]>>+<<,--------------------------------]>>[-<<<
+>>>]<<<<[>[-<<+>>]<<<]>[-<<<<<+>>>>>]>[>>],----------[++++++++++>>
[->>+<<]>>+<<,----------]>>[-<<<+>>>]<<<<[>[-<<+>>]<<<]>[-<<+>>]<<[
-<+>>+<]<<<[->+<]>[-<+>>>>+<<<]>>>[-<+>]<[->+>+<<]<[-<+>]<[->+>+<<]
<[-<+>>+<]<[->+<]>>>>>>[-[->>+<<]<<[->>+<<]<<[->>+<<]>>>>>>]<<[->>+
>+<<<]>>>[-<<<+>>>]<[->>+[->+>+<<]<<[->>+<<]>>]>>[-]<[<<]<<<+[->>>+
<<<]>>>[-<+<<+>>>]<<<<<[->>[->>>>[->>+<<]<<[->>+<<]<<[->>+<<]<<[->>
+<<]>>>>]>>[->>>>+<<<<]>>>>[-<<<<+<<+>>>>>>]<<+[->>+<<]>>[-<<+<+>>>
]<<<<<<<<]>>[-]>>[-]>>[-]-[+<<-]+>>>>>>>>>>>>>>>>>[-<+>]<[->+<<<<+>
>>]<<<[->>>>>>[-<+>]<[->+<<<<+>>>]<<<<<<<[-]<<+>>>>>>[-<<<<+>>>>>>>
>>>[-<+>]<[->+>+<<]<<<<<<<<<[->+<]>[->>>>>>>>+<<<<<<<<<+>]<<<[->+<]
>[->>>>>>>>+<<<<<<<<<+>]>>>>>>>>>[-<<<<<+>>>>>]<<<<<[->>+>>>+<<<<<]
>>>>>>>>[-[->>+<<]<<[->>+<<]<<[->>+<<]<<[->>+<<]>>>>>>>>]<<<<<<+>>-
[-<<[-<<<<+>>>>]<<<<[->>+>>+<<<<]>>[->>>>>>[->>+<<]<<[->>+<<]<<[->>
+<<]<<[->>+<<]>>]>>>>]>>[->>+<<]>>[-<<+>>>>+<<]->>-[-[->>+<<]>>]>[-
>+<]>[-<+>>>+<<]<<<[->+<]>[-<+>>>+<<]+[->>[-<<+>>]>>[-<<+>>]<<<<<<+
]<<<<<<[->>>>>>+<<<<<<]>>>>>>>>[-<<<<<<<<+>>>>>>>>]<<<<[->>>>+<<<<]
-<<[-]>>>>>>>>[-<<<<<<<<+>>>>>>>>]<<<<[->>[->>+<<]<<[->>+<<]>>]>>-[
-[->>+<<]>>]<[->+<]>[-<+>>>+<<]+[->>[-<<+>>]<<<<+]>>[-<<+>>]<<<<<<<
<-[+>>[-<<+>>]>>[-<<+>>]>>[-<<+>>]<<<<<<<<-]+>>>[-]<[->+<]>>>[-]<[-
>+<]>>>[-]<[->+<]>>>[->+<]>[-<+>>>>>>>>>>>>>+<<<<<<<<<<<<]>>>>>>>>>
>>>-[-[->>+<<]>>]>[->+<]>[-<+<+>>]<<<<-[+>>[-<<+>>]<<<<-]+>>[-<+>]>
>>>>>>>>[->+<]>[-<+>>>>>>>>>>>+<<<<<<<<<<]>>>>>[->+<]>[-<+>>>>>+<<<
<]>>>>-[-[->>+<<]>>]>[->+<]>[-<+<+>>]<<<<-[+>>[-<<+>>]<<<<-]+>[->-<
]>[-<[-]+>]<[->>>+<<<]>>>[-<<+<+>>>]<<-[+>[->+<]<]<[->>+<-[[-]>[->+
<]>[-<+>>>+<<]+>>[-<<[-]>>]<[->+<]>[-<+>>>+<<]+>>[-<<[-]>>]<[->+<]>
[-<+>>>+<<]+>>[-<<[-]>>]<<[-<<[-]+>>]<<[-<<[-]+>>]<<[-<<[-]+>>]<<<+
>->->>->>-<<<<<]<[->+<]]>[-<+>]>>[-<<<+>>>]<<<[->>>>>>>>>>>>>+<<<<<
<<<<<<<<]>>>>>>>>[->+<]>[-<+>>>>>>>>>+<<<<<<<<]>[->+<]>[-<+>>>>>>>>
>+<<<<<<<<]>>>>>>>>>[->>>+<<<]>>>[-<<+<+>>>]<<<<<[->>>>>+<<<<<]>>>>
>[-<<<<<+<<<+>>>>>>>>]<<<<<<<<+>>>>>>[-[->>+<<]<<[->>+<<]<<[->>+<<]
<<[->>+<<]<<[->>+<<]>>>>>>>>>>]<<<<[-<<[-<<<<<<+>>>>>>]<<<<<<[->>+>
>>>+<<<<<<]>>[->>>>>>>>[->>+<<]<<[->>+<<]<<[->>+<<]<<[->>+<<]<<[->>
+<<]>>]>>>>>>]<<[-]<<[->>>>+<<<<]>>>>>>[-[->>+<<]<<[->>+<<]>>>>]<<[
->>>>>+<<<<<]-[+<<-]+>>>>>>>>>>>>>>>]<<]>>>>>>>>[->+<]<<[->+<]<<[->
+<]>>>>>[-[->>+<<]<<[->>+<<]<<[->>+<<]>>>>>>]<<<<[->>[->>>>+<<<<]>>
>>[-<<+<<+>>>>]<<+[-[->>+<<]<<[->>+<<]<<[->>+<<]>>>>>>]<<<<]>>[-[->
>+<<]>>]>>>>++++++++++<[->-[>+>>]>[+[-<+>]>+>>]<<<<<]>>>[->-[>+>>]>
[+[-<+>]>+>>]<<<<<]>[-]<++++++[->++++++++[->+>+<<<<+>>]<]>>>.<.<<<.

แน่นอนว่าใช้โปรแกรมแบบไดนามิก

สตริงอินพุตควรคั่นด้วยช่องว่างและตามด้วยบรรทัดใหม่ ตัวอย่างเช่น:

INTENTION EXECUTION
008

1
จัดแนวเรียบร้อยและอ่านง่าย - ฉันชอบ +1 เลย!
โทมัส

นี่เป็นภาษาคอมพิวเตอร์หรือไม่ : O

นี่เป็นคำถามที่สับสนมากที่สุด ... +1 เพียงเพราะมันเป็น BF
HyperNeutrino

5

Python, 138 148 152ตัวอักษร

ตกลงฉันรู้หลักการ แต่ไม่เคยใช้การแก้ไขระยะทางมาก่อนดังนั้นที่นี่จะไป:

x,y=raw_input().split()
d=range(99)
for a in x:
 c=d;d=[d[0]+1]
 for b,p,q in zip(y,c[1:],c):d+=[min(d[-1]+1,p+1,q+2*(a!=b))]
print d[-1]

4

PHP, 40

ปฏิบัติตามกฎที่ระบุไว้ แต่ไม่ใช่วิญญาณของกฎ:

<?=levenshtein($argv[1],$argv[2],1,2,1);

รับพารามิเตอร์สองตัวเป็นอาร์กิวเมนต์ php edit_dist.php word1 word2ตัวอย่างโทร:
โดยทั่วไปlevenshtein()ถือว่าการทดแทนเป็นหนึ่งการดำเนินการ แต่มีรูปแบบที่โอเวอร์โหลดซึ่งสามารถระบุน้ำหนักการแทรก / การย่อย / การลบได้ ในกรณีนี้มัน 1/2/1


3

APL (90 ตัวอักษร)

⊃⌽({h←1+c←⊃⍵⋄d←h,1↓⍵⋄h,(⊂⍵){y←⍵+1⋄d[y]←⍺{h⌷b=⍵⌷a:⍵⌷⍺⋄1+d[⍵]⌊y⌷⍺}⍵}¨⍳x}⍣(⊃⍴b←,⍞))0,⍳x←⍴a←,⍞

ฉันใช้ Dyalog APL เป็นล่ามของฉันโดย⎕IOตั้งค่าเป็น 1 และ⎕MLตั้งค่าเป็น 0 การ{ ... }คำนวณโดยตรงของฟังก์ชัน ( ) ให้แถวเป็นอินพุตแถวถัดไปของเมทริกซ์ระยะทาง (เริ่มจากแถวแรก: 0,⍳x.) ตัวดำเนินการพลังงาน ( ) ใช้เพื่อซ้อนฟังก์ชันหนึ่งครั้งสำหรับแต่ละอักขระในสตริงที่สอง ( ⊃⍴b) หลังจากนั้นแถวสุดท้ายจะถูกกลับรายการ ( ) และองค์ประกอบแรกจะถูกนำมา ( )

ตัวอย่าง:

      ⊃⌽({h←1+c←⊃⍵⋄d←h,1↓⍵⋄h,(⊂⍵){y←⍵+1⋄d[y]←⍺{h⌷b=⍵⌷a:⍵⌷⍺⋄1+d[⍵]⌊y⌷⍺}⍵}¨⍳x}⍣(⊃⍴b←,⍞))0,⍳x←⍴a←,⍞
LOCKSMITH
BLACKSMITH
3
      ⊃⌽({h←1+c←⊃⍵⋄d←h,1↓⍵⋄h,(⊂⍵){y←⍵+1⋄d[y]←⍺{h⌷b=⍵⌷a:⍵⌷⍺⋄1+d[⍵]⌊y⌷⍺}⍵}¨⍳x}⍣(⊃⍴b←,⍞))0,⍳x←⍴a←,⍞
GATTTGTGACGCACCCTCAGAACTGCAGTAATGGTCCAGCTGCTTCACAGGCAACTGGTAACCACCTCATTTGGGGATGTTTCTGCCTTGCTAGCAGTGCCAGAGAGAACTTCATCATTGTCACCTCATCAAAGACTACTTTTTCAGACATCTCCTGTAG
AAGTACTGAACTCCTAATATCACCAATTCTTCTAAGTTCCTGGACATTGATCCGGAGGAGGATTCGCAGTTCAACATCAAGGTAAGGAAGGATACAGCATTGTTATCGTTGTTGAGATATTAGTAAGAAATACGCCTTTCCCCATGTTGTAAACGGGCTA
118

3

R 51

สิ่งนี้อ่านในสองบรรทัดจากผู้ใช้ (ซึ่งเป็นอินพุต) จากนั้นใช้adistฟังก์ชันเพื่อคำนวณระยะทาง เนื่องจากการทดแทนมีค่าใช้จ่าย 2 สำหรับปัญหานี้เราต้องเพิ่มเวกเตอร์ที่มีชื่อสำหรับพารามิเตอร์ต้นทุนสำหรับโฆษณา เนื่องจากยังมีพารามิเตอร์การนับสำหรับ adist เราจึงสามารถลดต้นทุนให้ cos ได้ดังนั้นเราจึงยังมีการจับคู่ที่ไม่ซ้ำกันสำหรับชื่อพารามิเตอร์

x=readLines(n=2);adist(x[1],x[2],cos=c(i=1,d=1,s=2))

ตัวอย่างการใช้

> x=readLines(n=2);adist(x[1],x[2],cos=c(i=1,d=1,s=2))
MART
KARMA
     [,1]
[1,]    5

0

ทับทิม 1.9, 124

l=->a,b{a[0]?b[0]?[(a[0]==b[0]?-1:1)+l[a[1..-1],b[1..-1]],l[a[1..-1],b],l[a,b[1..-1]]].min+1: a.size: b.size}
puts l[*ARGV]

เวอร์ชัน Golfed ของวิธี Ruby แบบเรียกซ้ำที่ช้าที่ปรับเปลี่ยนเพื่อเพิ่มน้ำหนักเป็นสองเท่าสำหรับการทดแทน ความจริงที่ว่ามันใช้เวลา 7 ตัวอักษรในการลบตัวอักษรตัวแรกของสตริงที่เจ็บปวดจริงๆและมันก็เจ๋งที่จะแทนที่(a[0]==b[0]?-1:1)ด้วยบางอย่างเช่น-1**a[0]<=>b[0]แต่ลำดับของการดำเนินการไม่ใช่เพื่อนของฉัน


0

Smalltalk (Smalltalk / X), 34

ฉันโชคดี - คลาส "String" มาตรฐานมี levenshtein อยู่แล้ว:

ป้อน a, b:

a levenshteinTo:b s:2 k:2 c:1 i:1 d:1

(พารามิเตอร์เพิ่มเติมอนุญาตให้มีน้ำหนักแตกต่างกันในการทดแทนการลบ ฯลฯ )

ทดสอบการทำงาน:

#( 'ISLANDER'  'SLANDER' 
   'MART'      'KARMA'   
   'KITTEN'    'SITTING' 
   'INTENTION' 'EXECUTION'  
) pairWiseDo:[:a :b|
    a print. ' ' print. b print. ' ' print.
    (a levenshteinTo:b
            s:2 k:2 c:1 i:1 d:1) printCR.
].

->

ISLANDER SLANDER 1
MART KARMA 5
KITTEN SITTING 5
INTENTION EXECUTION 8
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.