Longest common subsequence: Difference between revisions
Content added Content deleted
m (→{{trans|Ruby}}) |
m (Fixed lang tags.) |
||
Line 11: | Line 11: | ||
=={{header|Ada}}== |
=={{header|Ada}}== |
||
Using recursion: |
Using recursion: |
||
<lang ada> |
<lang ada>with Ada.Text_IO; use Ada.Text_IO; |
||
with Ada.Text_IO; use Ada.Text_IO; |
|||
procedure Test_LCS is |
procedure Test_LCS is |
||
Line 36: | Line 35: | ||
begin |
begin |
||
Put_Line (LCS ("thisisatest", "testing123testing")); |
Put_Line (LCS ("thisisatest", "testing123testing")); |
||
end Test_LCS; |
end Test_LCS;</lang> |
||
⚫ | |||
Sample output: |
Sample output: |
||
<pre> |
<pre> |
||
Line 43: | Line 41: | ||
</pre> |
</pre> |
||
Non-recursive solution: |
Non-recursive solution: |
||
<lang ada> |
<lang ada>with Ada.Text_IO; use Ada.Text_IO; |
||
with Ada.Text_IO; use Ada.Text_IO; |
|||
procedure Test_LCS is |
procedure Test_LCS is |
||
Line 88: | Line 85: | ||
begin |
begin |
||
Put_Line (LCS ("thisisatest", "testing123testing")); |
Put_Line (LCS ("thisisatest", "testing123testing")); |
||
end Test_LCS; |
end Test_LCS;</lang> |
||
⚫ | |||
Sample output: |
Sample output: |
||
<pre> |
<pre> |
||
Line 100: | Line 96: | ||
{{works with|ALGOL 68G|Any - tested with release mk15-0.8b.fc9.i386}} |
{{works with|ALGOL 68G|Any - tested with release mk15-0.8b.fc9.i386}} |
||
{{works with|ELLA ALGOL 68|Any (with appropriate job cards) - tested with release 1.8.8d.fc9.i386}} |
{{works with|ELLA ALGOL 68|Any (with appropriate job cards) - tested with release 1.8.8d.fc9.i386}} |
||
<lang> |
<lang algol68>main:( |
||
main:( |
|||
PROC lcs = (STRING a, b)STRING: |
PROC lcs = (STRING a, b)STRING: |
||
BEGIN |
BEGIN |
||
Line 115: | Line 110: | ||
END # lcs #; |
END # lcs #; |
||
print((lcs ("thisisatest", "testing123testing"), new line)) |
print((lcs ("thisisatest", "testing123testing"), new line)) |
||
⚫ | |||
) |
|||
⚫ | |||
Output: |
Output: |
||
<pre> |
<pre> |
||
Line 298: | Line 292: | ||
The [http://en.wikipedia.org/wiki/Longest_common_subsequence#Solution_for_two_sequences Wikipedia solution] translates directly into Haskell, with the only difference that equal characters are added in front: |
The [http://en.wikipedia.org/wiki/Longest_common_subsequence#Solution_for_two_sequences Wikipedia solution] translates directly into Haskell, with the only difference that equal characters are added in front: |
||
⚫ | |||
<pre> |
|||
⚫ | |||
lcs [] _ = [] |
lcs [] _ = [] |
||
Line 305: | Line 298: | ||
lcs (x:xs) (y:ys) |
lcs (x:xs) (y:ys) |
||
| x == y = x : lcs xs ys |
| x == y = x : lcs xs ys |
||
| otherwise = longest (lcs (x:xs) ys) (lcs xs (y:ys)) |
| otherwise = longest (lcs (x:xs) ys) (lcs xs (y:ys))</lang> |
||
</pre> |
|||
Memoization (aka dynamic programming) of that uses ''zip'' to make both the index and the character available: |
Memoization (aka dynamic programming) of that uses ''zip'' to make both the index and the character available: |
||
⚫ | |||
<pre> |
|||
⚫ | |||
lcs xs ys = a!(0,0) where |
lcs xs ys = a!(0,0) where |
||
Line 321: | Line 312: | ||
f x y i j |
f x y i j |
||
| x == y = x : a!(i+1,j+1) |
| x == y = x : a!(i+1,j+1) |
||
| otherwise = longest (a!(i,j+1)) (a!(i+1,j)) |
| otherwise = longest (a!(i,j+1)) (a!(i+1,j))</lang> |
||
</pre> |
|||
Both solutions work of course not only with strings, but also with any other list. Example: |
Both solutions work of course not only with strings, but also with any other list. Example: |
||
⚫ | |||
<pre> |
|||
⚫ | |||
⚫ | |||
"tsitest" |
|||
</pre> |
|||
=={{header|J}}== |
=={{header|J}}== |
||
<lang j>lcs=: dyad define |
|||
|.x{~ 0{"1 cullOne^:_ (\:~~ +/@|:) 4$.$. x =/ y |
|||
) |
|||
cullOne=: verb define |
|||
if. (#y) = First0=.0(= i. 1:) 1,*./|: 2 >/\ y |
|||
do. y else. y #~ 0 First0}(#y)#1 end. |
|||
⚫ | |||
) |
|||
=={{header|Java}}== |
=={{header|Java}}== |
||
Line 391: | Line 379: | ||
=={{header|Logo}}== |
=={{header|Logo}}== |
||
This implementation works on both words and lists. |
This implementation works on both words and lists. |
||
<lang logo> |
<lang logo>to longest :s :t |
||
to longest :s :t |
|||
output ifelse greater? count :s count :t [:s] [:t] |
output ifelse greater? count :s count :t [:s] [:t] |
||
end |
end |
||
Line 400: | Line 387: | ||
if equal? first :s first :t [output combine first :s lcs bf :s bf :t] |
if equal? first :s first :t [output combine first :s lcs bf :s bf :t] |
||
output longest lcs :s bf :t lcs bf :s :t |
output longest lcs :s bf :t lcs bf :s :t |
||
end |
end</lang> |
||
</lang> |
|||
=={{header|M4}}== |
=={{header|M4}}== |
||
⚫ | |||
<lang M4> |
|||
⚫ | |||
define(`get2d',`defn($1[$2][$3])') |
define(`get2d',`defn($1[$2][$3])') |
||
define(`tryboth', |
define(`tryboth', |
||
Line 425: | Line 410: | ||
lcs(`1234',`1224533324') |
lcs(`1234',`1224533324') |
||
lcs(`thisisatest',`testing123testing') |
lcs(`thisisatest',`testing123testing')</lang> |
||
</lang> |
|||
Note: the caching (set2d/get2d) obscures the code even more than usual, but is necessary in order to get the second test to run in a reasonable amount of time. |
Note: the caching (set2d/get2d) obscures the code even more than usual, but is necessary in order to get the second test to run in a reasonable amount of time. |
||
=={{header|Mathematica}}== |
=={{header|Mathematica}}== |
||
A built-in function can do this for us: |
A built-in function can do this for us: |
||
<lang Mathematica> |
<lang Mathematica>a = "thisisatest"; |
||
a = "thisisatest"; |
|||
b = "testing123testing"; |
b = "testing123testing"; |
||
LongestCommonSequence[a, b] |
LongestCommonSequence[a, b]</lang> |
||
</lang> |
|||
gives: |
gives: |
||
<lang Mathematica>tsitest</lang> |
<lang Mathematica>tsitest</lang> |
||
Line 517: | Line 499: | ||
return max(lcs(xstr, ys), lcs(xs, ystr), key=len)</lang> |
return max(lcs(xstr, ys), lcs(xs, ystr), key=len)</lang> |
||
Test it: |
Test it: |
||
<lang python> |
<lang python>if __name__=="__main__": |
||
⚫ | |||
if __name__=="__main__": |
|||
⚫ | |||
</lang> |
|||
===Dynamic Programming=== |
===Dynamic Programming=== |
||
Line 606: | Line 586: | ||
===Recursion=== |
===Recursion=== |
||
{{trans|Java}} |
{{trans|Java}} |
||
⚫ | |||
<lang slate> |
|||
⚫ | |||
[ |
[ |
||
s1 isEmpty \/ s2 isEmpty ifTrue: [^ {}]. |
s1 isEmpty \/ s2 isEmpty ifTrue: [^ {}]. |
||
Line 616: | Line 595: | ||
y: (s1 allButLast longestCommonSubsequenceWith: s2). |
y: (s1 allButLast longestCommonSubsequenceWith: s2). |
||
x length > y length ifTrue: [x] ifFalse: [y]] |
x length > y length ifTrue: [x] ifFalse: [y]] |
||
]. |
].</lang> |
||
</lang> |
|||
===Dynamic Programming=== |
===Dynamic Programming=== |
||
{{trans|Ruby}} |
{{trans|Ruby}} |
||
⚫ | |||
<lang slate> |
|||
⚫ | |||
[| lengths | |
[| lengths | |
||
lengths: (ArrayMD newWithDimensions: {s1 length `cache. s2 length `cache} defaultElement: 0). |
lengths: (ArrayMD newWithDimensions: {s1 length `cache. s2 length `cache} defaultElement: 0). |
||
Line 646: | Line 623: | ||
index2: index2 - 1]] |
index2: index2 - 1]] |
||
] writingAs: s1) reverse |
] writingAs: s1) reverse |
||
]. |
].</lang> |
||
</lang> |
|||
=={{header|Tcl}}== |
=={{header|Tcl}}== |