Longest common prefix: Difference between revisions
added Easylang
(added Ol) |
(added Easylang) |
||
(29 intermediate revisions by 16 users not shown) | |||
Line 27:
=={{header|11l}}==
<
I sa.empty
R ‘’
Line 53:
test([‘’])
test([‘prefix’, ‘suffix’])
test([‘foo’, ‘foobar’])</
{{out}}
Line 65:
[prefix, suffix] ->
[foo, foobar] -> foo
</pre>
=={{header|Action!}}==
<syntaxhighlight lang="action!">DEFINE PTR="CARD"
BYTE Func Equals(CHAR ARRAY a,b)
BYTE i
IF a(0)#b(0) THEN
RETURN (0)
FI
FOR i=1 TO a(0)
DO
IF a(i)#b(i) THEN
RETURN (0)
FI
OD
RETURN (1)
BYTE FUNC CommonLength(PTR ARRAY texts BYTE count)
CHAR ARRAY t
BYTE i,len
IF count=0 THEN
RETURN (0)
FI
len=255
FOR i=0 TO count-1
DO
t=texts(i)
IF t(0)<len THEN
len=t(0)
FI
OD
RETURN (len)
PROC Prefix(PTR ARRAY texts BYTE count CHAR ARRAY res)
CHAR ARRAY t(100)
BYTE i,len,found
IF count=1 THEN
SCopy(res,texts(0))
RETURN
FI
len=CommonLength(texts,count)
WHILE len>0
DO
SCopyS(res,texts(0),1,len)
found=1
FOR i=1 TO count-1
DO
SCopyS(t,texts(i),1,len)
IF Equals(res,t)#1 THEN
found=0 EXIT
FI
OD
IF found THEN
RETURN
FI
len==-1
OD
res(0)=0
RETURN
PROC Test(PTR ARRAY texts BYTE count)
BYTE i
CHAR ARRAY res(100)
Prefix(texts,count,res)
Print("lcp(")
IF count>0 THEN
FOR i=0 TO count-1
DO
PrintF("""%S""",texts(i))
IF i<count-1 THEN
Print(",")
FI
OD
FI
PrintF(")=""%S""%E",res)
RETURN
PROC Main()
CHAR ARRAY
t1="interspecies", t2="interstellar", t3="interstate",
t4="throne", t5="throne", t6="dungeon", t7="",
t8="prefix", t9="suffix", t10="foo", t11="foobar"
PTR ARRAY texts(20)
texts(0)=t1 texts(1)=t2 texts(2)=t3
Test(texts,3)
texts(0)=t4 texts(1)=t5
Test(texts,2)
texts(0)=t4 texts(1)=t6
Test(texts,2)
texts(0)=t4 texts(1)=t7 texts(2)=t5
Test(texts,3)
texts(0)=t7
Test(texts,1)
Test(texts,0)
texts(0)=t8 texts(1)=t9
Test(texts,2)
texts(0)=t10 texts(1)=t11
Test(texts,2)
RETURN</syntaxhighlight>
{{out}}
[https://gitlab.com/amarok8bit/action-rosetta-code/-/raw/master/images/Longest_common_prefix.png Screenshot from Atari 8-bit computer]
<pre>
lcp("interspecies","interstellar","interstate")="inters"
lcp("throne","throne")="throne"
lcp("throne","dungeon")=""
lcp("throne","","throne")=""
lcp("")=""
lcp()=""
lcp("prefix","suffix")=""
lcp("foo","foobar")="foo"
</pre>
=={{header|Ada}}==
<
with Ada.Strings.Unbounded;
Line 138 ⟶ 264:
Ada.Text_IO.Put_Line (Prefix);
end Longest_Prefix;</
=={{header|Aime}}==
<
{
integer n;
Line 170 ⟶ 296:
0;
}</
{{Out}}
<pre>"inters"
Line 184 ⟶ 310:
=={{header|ALGOL 68}}==
{{works with|ALGOL 68G|Any - tested with release 2.8.win32}}
<
PRIO COMMONPREFIX = 1;
OP COMMONPREFIX = ( STRING a, b )STRING:
Line 254 ⟶ 380:
test prefix( ( "prefix", "suffix" ), "" );
test prefix( ( "foo", "foobar" ), "foo" )
END</
{{out}}
<pre>
Line 270 ⟶ 396:
=={{header|AppleScript}}==
===AppleScriptObjC===
<
use framework "Foundation"
Line 301 ⟶ 427:
longestCommonPrefix({}) --> ""
longestCommonPrefix({"prefix", "suffix"}) --> ""
longestCommonPrefix({"foo", "foobar"}) --> "foo"</
----
===Functional===
and for more productivity, and higher re-use of existing library functions, we can write a functional definition (rather than a procedure).
<
Line 650 ⟶ 776:
set my text item delimiters to dlm
str
end unlines</
{{Out}}
<pre>['interspecies', 'interstellar', 'interstate'] -> 'inters'
Line 663 ⟶ 789:
=={{header|Arturo}}==
<
ret: ""
idx: 0
Line 686 ⟶ 812:
print lcp [""]
print lcp ["prefix" "suffix"]
print lcp ["foo" "foobar"]</
{{out}}
Line 700 ⟶ 826:
=={{header|AutoHotkey}}==
<
for num, v in StrSplit(data.1)
for i, word in data
Line 706 ⟶ 832:
return SubStr(word, 1, num-1)
return SubStr(word, 1, num)
}</
Examples:<
. "`n" lcp(["interspecies","interstellar","interstate"])
. "`n" lcp(["throne","throne"])
Line 717 ⟶ 843:
. "`n" lcp(["prefix","suffix"])
. "`n" lcp(["foo","foobar"])
return</
{{out}}
<pre>
Line 731 ⟶ 857:
=={{header|AWK}}==
<syntaxhighlight lang="awk">
# syntax: GAWK -f LONGEST_COMMON_PREFIX.AWK
BEGIN {
Line 778 ⟶ 904:
return(substr(str,1,lcp_leng))
}
</syntaxhighlight>
<p>Output:</p>
<pre>
Line 792 ⟶ 918:
=={{header|C}}==
<syntaxhighlight lang="c">
#include<stdarg.h>
#include<string.h>
Line 854 ⟶ 980:
return 0;
}
</syntaxhighlight>
Output:
<pre>
Line 870 ⟶ 996:
=={{header|C sharp|C#}}==
{{trans|Java}}
<
namespace LCP {
Line 913 ⟶ 1,039:
}
}
}</
{{out}}
<pre>inters
Line 926 ⟶ 1,052:
=={{header|C++}}==
<
#include <algorithm>
#include <string>
Line 1,003 ⟶ 1,129:
std::cout << "lcp( \"foo\" , \"foobar\" ) = " << lcp ( input ) << std::endl ;
return 0 ;
}</
Another more concise version (C++14 for comparing dissimilar containers):
<
#include <algorithm>
#include <string>
Line 1,045 ⟶ 1,171:
return 0 ;
}
</syntaxhighlight>
{{out}}
<pre>
Line 1,055 ⟶ 1,181:
lcp( "foo" , "foobar" ) = foo
</pre>
=={{header|CLU}}==
<syntaxhighlight lang="clu">lcp = proc (strs: ss) returns (string)
ss = sequence[string]
if ss$empty(strs) then return("") end
pfx: string := ss$bottom(strs)
for str: string in ss$elements(strs) do
if string$empty(pfx) then return("") end
if string$size(str) < string$size(pfx) then
pfx := string$substr(pfx, 1, string$size(str))
end
no_match: int := 1
while no_match <= string$size(pfx) cand
str[no_match] = pfx[no_match] do
no_match := no_match + 1
end
pfx := string$substr(pfx, 1, no_match-1)
end
return(pfx)
end lcp
start_up = proc ()
ss = sequence[string]
sss = sequence[ss]
po: stream := stream$primary_output()
tests: sss := sss$[
ss$["interspecies","interstellar","interstate"],
ss$["throne","throne"],
ss$["throne","dungeon"],
ss$["throne","","dungeon"],
ss$["cheese"],
ss$[""],
ss$[],
ss$["prefix","suffix"],
ss$["foo","foobar"]
]
for test: ss in sss$elements(tests) do
stream$putl(po, "\"" || lcp(test) || "\"")
end
end start_up</syntaxhighlight>
{{out}}
<pre>"inters"
"throne"
""
""
"cheese"
""
""
""
"foo"</pre>
=={{header|D}}==
{{trans|Java}}
<
string lcp(string[] list ...) {
Line 1,091 ⟶ 1,272:
writeln(lcp("prefix","suffix"));
writeln(lcp("foo","foobar"));
}</
{{out}}
<pre>inters
Line 1,106 ⟶ 1,287:
{{trans|C#}}
<
if sa.
return ""
}
var ret = ""
var idx = 0
while true {
var thisLetter = '\0'
for word in sa {
if idx == word.
return ret
}
Line 1,127 ⟶ 1,308:
}
}
ret += thisLetter
idx += 1
}
}
print(lcp("interspecies", "interstellar", "interstate"))
print(lcp("throne", "throne"))
Line 1,141 ⟶ 1,322:
print(lcp(nil))
print(lcp("prefix", "suffix"))
print(lcp("foo", "foobar"))</
{{out}}
Line 1,154 ⟶ 1,335:
foo</pre>
=={{header|EasyLang}}==
<syntaxhighlight>
func$ lcp list$[] .
if len list$[] = 0
return ""
.
shortest$ = list$[1]
for s$ in list$[]
if len s$ < len shortest$
shortest$ = s$
.
.
for i to len shortest$ - 1
sub$ = substr shortest$ 1 i
for s$ in list$[]
if substr s$ 1 i <> sub$
return substr shortest$ 1 (i - 1)
.
.
.
return shortest$
.
print lcp [ "interspecies" "interstellar" "interstate" ]
print lcp [ "throne" "throne" ]
print lcp [ "throne" "dungeon" ]
print lcp [ "throne" "" "throne" ]
print lcp [ "cheese" ]
print lcp [ ]
print lcp [ "foo" "foobar" ]
</syntaxhighlight>
{{out}}
<pre>
inters
throne
cheese
foo
</pre>
=={{header|EchoLisp}}==
<
;; find common prefix of two strings
(define (prefix s t ) (for/string ((u s) (v t)) #:break (not (= u v)) u))
Line 1,187 ⟶ 1,409:
("prefix" "suffix") → ""
</syntaxhighlight>
=={{header|Elixir}}==
<syntaxhighlight lang="elixir">
@data [
["interspecies", "interstellar", "interstate"],
["throne", "throne"],
["throne", "dungeon"],
["throne", "", "throne"],
["cheese"],
[""],
[],
["prefix", "suffix"],
["foo", "foobar"]
]
def main do
Enum.each(@data, fn strs ->
IO.puts("#{inspect(strs)} -> #{inspect(lcp(strs))}")
end)
end
defp lcp( [] ), do: ""
defp lcp(strs), do: Enum.reduce(strs, &lcp/2)
defp lcp(xs, ys), do: lcp(xs, ys, "")
defp lcp(<<x,xs>>, <<x,ys>>, pre), do: lcp(xs, ys, <<x,pre>>)
defp lcp( _, _, pre), do: String.reverse(pre)
end
</syntaxhighlight>
{{out}}
<pre>
</pre>
=={{header|Erlang}}==
<syntaxhighlight lang="erlang">
-module(lcp).
-export([ main/
data() -> [
["interspecies", "interstellar", "interstate"],
["throne", "throne"],
["throne", "dungeon"],
["throne", "", "throne"],
["cheese"],
[""],
[],
["prefix", "suffix"],
["foo", "foobar"]
].
main() -> [io:format("~p -> \"~s\"~n",[Strs,lcp(Strs)]) || Strs <- data()].
lcp([S|Strs]) -> lists:foldl( fun(X,Y) -> lcp(X,Y,[]) end, S, Strs).
lcp([X|Xs], [X|Ys], Pre) -> lcp(Xs, Ys, [X|Pre]);
lcp( _, _, Pre) -> lists:reverse(Pre).
</syntaxhighlight>
{{out}}
<pre>
["interspecies","interstellar","interstate"] -> "inters"
["throne","throne"] -> "throne"
[[]] -> ""
[] -> ""
["prefix","suffix"] -> ""
</pre>
=={{header|Factor}}==
<
IN: rosetta-code.lcp
Line 1,333 ⟶ 1,521:
} [ dup lcp "%u lcp = %u\n" printf ] each ;
MAIN: lcp-demo</
{{out}}
<pre>
Line 1,348 ⟶ 1,536:
=={{header|FreeBASIC}}==
<
Function lcp(s() As String) As String
Line 1,409 ⟶ 1,597:
Print
Print "Press any key to quit"
Sleep</
{{out}}
Line 1,425 ⟶ 1,613:
=={{header|Go}}==
<
import "fmt"
Line 1,478 ⟶ 1,666:
fmt.Printf("lcp(%q) = %q\n", l, lcp(l))
}
}</
{{out}}
<pre>
Line 1,494 ⟶ 1,682:
=={{header|Haskell}}==
This even works on infinite strings (that have a finite longest common prefix), due to Haskell's laziness.
<
lcp :: (Eq a) => [[a]] -> [a]
Line 1,517 ⟶ 1,705:
showPrefix :: [String] -> String
showPrefix = ((<>) . (<> " -> ") . show) <*> (show . lcp)</
{{Out}}
<pre>["interspecies","interstellar","interstate"] -> "inters"
Line 1,531 ⟶ 1,719:
=={{header|J}}==
<
In other words: compare adjacent strings pair-wise, combine results logically, find first mismatch in any of them, take that many characters from the first of the strings.
Line 1,541 ⟶ 1,729:
Examples:
<
inters
lcp 'throne',:'throne'
Line 1,554 ⟶ 1,742:
lcp 'prefix',:'suffix'
</syntaxhighlight>
=={{header|Java}}==
{{works with|Java|1.5+}}
<
public static String lcp(String... list){
if(list == null) return "";//special case
Line 1,593 ⟶ 1,781:
System.out.println(lcp("foo","foobar"));
}
}</
{{out}}
<pre>inters
Line 1,609 ⟶ 1,797:
===ES5===
<
'use strict';
Line 1,670 ⟶ 1,858:
];
})();</
{{Out}}
<
Line 1,685 ⟶ 1,873:
This functionally implemented zip is significantly slower than the iterative version used above:
<
// Accepts arrays or strings, and returns [[a]]
function zip() {
Line 1,705 ⟶ 1,893:
}, null)
} else return [];
}</
===ES6===
<
// -------------- LONGEST COMMON PREFIX --------------
// lcp :: (Eq a) => [[a]] -> [a]
const lcp = xs => {
const go =
[]
) :
go(ws.map(
);
return
)
.map(head)
.join("");
};
//
// main :: IO ()
const main = () => [
["interspecies", "interstellar", "interstate"],
["throne", "throne"],
["throne", "dungeon"],
["cheese"],
[""],
["prefix", "suffix"],
["foo", "foobar"]
].map(showPrefix).join("\n");
// showPrefix :: [String] -> String
const showPrefix = xs =>
//
// allSame :: [a] -> Bool
const allSame = xs =>
// in the tail
2 > xs.length ||
const [h, ...t] = xs;
return t.every(x => h === x);
})();
// head :: [a] -> a
const head = xs =>
xs.length ? (
xs[0]
) : undefined;
// isNull :: [a] -> Bool
// isNull :: String -> Bool
const isNull = xs =>
// show :: a -> String
const show = JSON.stringify;
// tail :: [a] -> [a]
const tail = xs =>
0 < xs.length ? (
xs.slice(1)
) : [];
// takeWhile :: (a -> Bool) -> [a] -> [a]
const
) : xs;
};
// MAIN ---
return main();
})();</
{{Out}}
<pre>["interspecies","interstellar","interstate"]
["throne","throne"]
["throne","dungeon"]
["cheese"]
[""]
["prefix","suffix"]
["foo","foobar"]
=={{header|jq}}==
Line 1,843 ⟶ 2,004:
See [[#Scala]] for a description of the approach used in this section.
<
# then feel free to omit the following definition:
def until(cond; next):
def _until: if cond then . else (next|_until) end; _until;</
<
if length == 0 then "" # by convention
elif length == 1 then .[0] # for speed
Line 1,859 ⟶ 2,020:
| $first[0:.]
end
end;</
'''Test Cases'''
<
(["interspecies","interstellar","interstate"] | check("inters")) and
Line 1,873 ⟶ 2,034:
(["prefix","suffix"] | check("")) and
(["foo","foobar"] | check("foo"))
</syntaxhighlight>
{{out}}
<
true</
=={{header|Julia}}==
{{works with|Julia|0.6}}
<
r = IOBuffer()
str = [str...]
Line 1,902 ⟶ 2,063:
@show lcp()
@show lcp("prefix","suffix")
@show lcp("foo","foobar")</
{{out}}
Line 1,916 ⟶ 2,077:
=={{header|Kotlin}}==
<
fun lcp(vararg sa: String): String {
Line 1,944 ⟶ 2,105:
println("""["prefix","suffix"] = "${lcp("prefix", "suffix")}"""")
println("""["foo","foobar"] = "${lcp("foo", "foobar")}"""")
}</
{{out}}
Line 1,963 ⟶ 2,124:
=={{header|Lobster}}==
{{trans|Go}}
<
def lcp(l):
Line 1,999 ⟶ 2,160:
["prefix", "suffix"],
["foo", "foobar"]]):
print("lcp" + _ + " = \"" + lcp(_) + "\"")</
{{out}}
<pre>lcp["interspecies", "interstellar", "interstate"] = "inters"
Line 2,013 ⟶ 2,174:
=={{header|Lua}}==
<
local shortest, prefix, first = math.huge, ""
for _, str in pairs(strList) do
Line 2,048 ⟶ 2,209:
pre = lcp(stringList)
if pre == "" then print(string.char(238)) else print(pre) end
end</
{{out}}
<pre>inters
Line 2,061 ⟶ 2,222:
=={{header|Maple}}==
<
local A:
if (arr = []) then return "": end if:
A := sort(arr):
return (A[1][1..(StringTools:-CommonPrefix(A[1],A[-1]))]):
end proc:</
'''Test Cases'''
<
lcp(["throne","throne"]);
lcp(["throne","dungeon"]);
Line 2,076 ⟶ 2,237:
lcp([]);
lcp(["prefix","suffix"]);
lcp(["foo","foobar"]);</
{{out}}
<pre>inters
Line 2,087 ⟶ 2,248:
""
foo</pre>
=={{header|Mathematica}}/{{header|Wolfram Language}}==
<syntaxhighlight lang="mathematica">ClearAll[LCP]
LCP[x_List] := Module[{l, s},
If[Length[x] > 0,
l = Min[StringLength /@ x];
s = Characters[StringTake[x, l]];
s //= Transpose;
l = LengthWhile[s, Apply[SameQ]];
StringTake[First[x], l]
,
""
]
]
LCP[{"interspecies", "interstellar", "interstate"}]
LCP[{"throne", "throne"}]
LCP[{"throne", "dungeon"}]
LCP[{"throne", "", "throne"}]
LCP[{"cheese"}]
LCP[{""}]
LCP[{}]
LCP[{"prefix", "suffix"}]
LCP[{"foo", "foobar"}]</syntaxhighlight>
{{out}}
<pre>"inters"
"throne"
""
""
"cheese"
""
""
""
"foo"</pre>
=={{header|MATLAB}} / {{header|Octave}}==
<syntaxhighlight lang="matlab">
function lcp = longest_common_prefix(varargin)
ca = char(varargin);
Line 2,097 ⟶ 2,291:
longest_common_prefix('aa', 'aa', 'aac')
</syntaxhighlight>
{{out}}
Line 2,106 ⟶ 2,300:
=={{header|MiniScript}}==
We find the shortest and longest strings (without sorting, which makes the code slightly longer but much more efficient), and then just compare those.
<
if not strList then return null
// find the shortest and longest strings (without sorting!)
Line 2,129 ⟶ 2,323:
print lcp(["cheese"])
print lcp([])
print lcp(["foo","foobar"])</
{{out}}
Line 2,139 ⟶ 2,333:
null
foo</pre>
=={{header|Miranda}}==
<syntaxhighlight lang="miranda">main :: [sys_message]
main = [Stdout (lay (map test tests))]
test :: [[char]]->[char]
test strings = show strings ++ " = " ++ show (lcp strings)
tests :: [[[char]]]
tests = [["interspecies","interstellar","interstate"],
["throne","throne"],
["throne","dungeon"],
["throne","","throne"],
[""],
[],
["prefix","suffix"],
["foo","foobar"]]
lcp :: [[char]]->[char]
lcp strings = map hd (takewhile same (transpose truncated))
where same (a:as) = and [c=a | c<-as]
truncated = map (take length) strings
length = min (map (#) strings)</syntaxhighlight>
{{out}}
<pre>main :: [sys_message]
main = [Stdout (lay (map test tests))]
test :: [[char]]->[char]
test strings = show strings ++ " = " ++ show (lcp strings)
tests :: [[[char]]]
tests = [["interspecies","interstellar","interstate"],
["throne","throne"],
["throne","dungeon"],
["throne","","throne"],
[""],
[],
["prefix","suffix"],
["foo","foobar"]]
lcp :: [[char]]->[char]
lcp strings = map hd (takewhile same (transpose truncated))
where same (a:as) = and [c=a | c<-as]
truncated = map (take length) strings
length = min (map (#) strings)</pre>
=={{header|Modula-2}}==
{{trans|C#}}
<
FROM Terminal IMPORT WriteString,WriteLn,ReadChar;
Line 2,213 ⟶ 2,452:
ReadChar
END LCP.</
{{out}}
<pre>inters
Line 2,222 ⟶ 2,461:
foo</pre>
=={{header|Nim}}==
<syntaxhighlight lang="nim">import sequtils, strformat, strutils
func lcp(list: varargs[string]): string =
if list.len == 0: return
result = list[0]
for i in 1..list.high:
var newLength = 0
for j in 0..result.high:
if j >= list[i].len or list[i][j] != result[j]:
break
inc newLength
result.setLen(newLength)
proc test(list: varargs[string]) =
let lst = list.mapIt('"' & it & '"').join(", ")
echo &"lcp({lst}) = \"{lcp(list)}\""
test("interspecies", "interstellar", "interstate")
test("throne", "throne")
test("throne", "dungeon")
test("cheese")
test("")
test()
test("prefix", "suffix")
test("foo", "foobar")</syntaxhighlight>
{{out}}
<pre>lcp("interspecies", "interstellar", "interstate") = "inters"
lcp("throne", "throne") = "throne"
lcp("throne", "dungeon") = ""
lcp("cheese") = "cheese"
lcp("") = ""
lcp() = ""
lcp("prefix", "suffix") = ""
lcp("foo", "foobar") = "foo"</pre>
=={{header|Ol}}==
<
(define (lcp . args)
(if (null? args)
Line 2,243 ⟶ 2,520:
(print "> " (lcp "prefix" "suffix"))
(print "> " (lcp "foo" "foobar"))
</syntaxhighlight>
{Out}
<pre>
Line 2,259 ⟶ 2,536:
==ooRexx==
{{trans|REXX}}
<
Call assert lcp(.list~of("throne","throne")),"throne"
Call assert lcp(.list~of("throne","dungeon")),""
Line 2,294 ⟶ 2,571:
Leave
End
Return left(arg(1),i-1)</
{{out}}
<pre>lcp(interspecies,interstellar,interstate)
Line 2,321 ⟶ 2,598:
If the strings are known not to contain null-bytes, we can let the regex backtracking engine find the longest common prefix like this:
<
(join("\0", @_) =~ /^ ([^\0]*) [^\0]* (?:\0 \1 [^\0]*)* $/sx)[0];
}</
Testing:
<
plan tests => 8;
Line 2,336 ⟶ 2,613:
is lcp(), "";
is lcp("prefix","suffix"), "";
is lcp("foo","foobar"), "foo";</
{{out}}
Line 2,342 ⟶ 2,619:
=={{header|Phix}}==
<!--<syntaxhighlight lang="phix">(phixonline)-->
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">lcp</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">strings</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">string</span> <span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">""</span>
<span style="color: #008080;">if</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">strings</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">then</span>
<span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">strings</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">2</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">strings</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
<span style="color: #004080;">string</span> <span style="color: #000000;">si</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">strings</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">j</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">res</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">j</span><span style="color: #0000FF;">></span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">si</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">or</span> <span style="color: #000000;">res</span><span style="color: #0000FF;">[</span><span style="color: #000000;">j</span><span style="color: #0000FF;">]!=</span><span style="color: #000000;">si</span><span style="color: #0000FF;">[</span><span style="color: #000000;">j</span><span style="color: #0000FF;">]</span> <span style="color: #008080;">then</span>
<span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">res</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">..</span><span style="color: #000000;">j</span><span style="color: #0000FF;">-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]</span>
<span style="color: #008080;">exit</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #008080;">if</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">res</span><span style="color: #0000FF;">)=</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span> <span style="color: #008080;">exit</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">return</span> <span style="color: #000000;">res</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #008080;">constant</span> <span style="color: #000000;">tests</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{{</span><span style="color: #008000;">"interspecies"</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"interstellar"</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"interstate"</span><span style="color: #0000FF;">},</span>
<span style="color: #0000FF;">{</span><span style="color: #008000;">"throne"</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"throne"</span><span style="color: #0000FF;">},</span>
<span style="color: #0000FF;">{</span><span style="color: #008000;">"throne"</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"dungeon"</span><span style="color: #0000FF;">},</span>
<span style="color: #0000FF;">{</span><span style="color: #008000;">"throne"</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">""</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"throne"</span><span style="color: #0000FF;">},</span>
<span style="color: #0000FF;">{</span><span style="color: #008000;">"cheese"</span><span style="color: #0000FF;">},</span>
<span style="color: #0000FF;">{</span><span style="color: #008000;">""</span><span style="color: #0000FF;">},</span>
<span style="color: #0000FF;">{</span><span style="color: #008000;">"prefix"</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"suffix"</span><span style="color: #0000FF;">},</span>
<span style="color: #0000FF;">{</span><span style="color: #008000;">"foo"</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"foobar"</span><span style="color: #0000FF;">}</span>
<span style="color: #0000FF;">}</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">tests</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
<span style="color: #0000FF;">?</span><span style="color: #000000;">lcp</span><span style="color: #0000FF;">(</span><span style="color: #000000;">tests</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">])</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<!--</syntaxhighlight>-->
{{out}}
<pre>
Line 2,388 ⟶ 2,668:
=={{header|PL/I}}==
{{trans|REXX}}
<
(subrg):
lcpt: Proc Options(main);
Line 2,440 ⟶ 2,720:
End;
End;</
{{out}}
<pre>"interspecies interstellar interstate"
Line 2,464 ⟶ 2,744:
=={{header|PowerShell}}==
<syntaxhighlight lang="powershell">
function lcp ($arr) {
if($arr){
Line 2,492 ⟶ 2,772:
show @("prefix","suffix")
show @("foo","foobar")
</syntaxhighlight>
<b>Output:</b>
<pre>
Line 2,508 ⟶ 2,788:
=={{header|Prolog}}==
{{works with|SWI Prolog}}
<
string_chars(String1, Chars1),
string_chars(String2, Chars2),
Line 2,542 ⟶ 2,822:
test([]),
test(["prefix", "suffix"]),
test(["foo", "foobar"]).</
{{out}}
Line 2,560 ⟶ 2,840:
Note: this makes use of the error in <code>os.path.commonprefix</code> where it computes the longest common prefix regardless of directory separators rather than [[Find common directory path#Python|finding the common directory path]].
<
def lcp(*s):
Line 2,571 ⟶ 2,851:
assert lcp("") == ""
assert lcp("prefix","suffix") == ""
assert lcp("foo","foobar") == "foo"</
===Python: Functional===
To see if all the n'th characters are the same I compare the min and max characters in the lambda function.
<
def lcp(*s):
Line 2,588 ⟶ 2,868:
assert lcp("") == ""
assert lcp("prefix","suffix") == ""
assert lcp("foo","foobar") == "foo"</
The above runs without output.
Line 2,594 ⟶ 2,874:
;Alternative Functional:
An alternative solution that takes advantage of the observation that the longest common prefix of a set of strings must be the same as the longest common prefix of the lexicographically minimal string and the lexicographically maximal string, since moving away lexicographically can only shorten the common prefix, never lengthening it. Finding the min and max could do a lot of unnecessary work though, if the strings are long and the common prefix is short.
<
def lcp(*s):
return ''.join(a for a,b in takewhile(lambda x: x[0] == x[1],
zip(min(s), max(s))))</
Or, defined in terms of a generic '''transpose''' function:
<
Line 2,651 ⟶ 2,931:
# TEST ---
if __name__ == '__main__':
main()</
{{Out}}
<pre>[interspecies, interstellar, interstate] -> inters
Line 2,660 ⟶ 2,940:
[prefix, suffix] ->
[foo, foobar] -> foo</pre>
=={{header|Quackery}}==
<syntaxhighlight lang="text"> [ dup [] = iff
[ drop true ] done
true swap
behead swap
witheach
[ over != if
[ dip not conclude ] ]
drop ] is allsame ( [ --> b )
[ dup [] = iff
[ drop 0 ] done
behead size swap
witheach [ size min ] ] is minsize ( [ --> n )
[ over [] = iff
drop done
[] unrot
swap witheach
[ over split
drop nested
rot swap join swap ]
drop ] is truncall ( [ n --> ] )
[ dup [] = if done
dup minsize truncall
[ dup allsame not while
-1 truncall
again ]
0 peek ] is commonprefix ( [ --> $ )
[ dup $ "" = if
[ drop
$ "** empty string" ]
echo$
cr ] is echoresult ( $ --> $ )
$ "interspecies interstellar interstate"
nest$ commonprefix echoresult
$ "throne throne"
nest$ commonprefix echoresult
$ "throne throne"
nest$ $ "" swap 1 stuff
commonprefix echoresult
$ "throne dungeon"
nest$ commonprefix echoresult
$ "cheese"
nest$ commonprefix echoresult
$ ""
nest$ commonprefix echoresult
' [ ] commonprefix echoresult
$ "prefix suffix"
nest$ commonprefix echoresult
$ "foo foobar"
nest$ commonprefix echoresult</syntaxhighlight>
{{out}}
<pre>inters
throne
** empty string
** empty string
cheese
** empty string
** empty string
** empty string
foo
</pre>
=={{header|Racket}}==
Line 2,665 ⟶ 3,023:
Note that there are three cases to the match, because <code>zip</code> needs at least one list, and <code>char=?</code> needs at least 2 characters to compare.
<syntaxhighlight lang="text">#lang racket
(require srfi/1)
Line 2,688 ⟶ 3,046:
(lcp ε) => ε
(lcp) => ε
(lcp "prefix" "suffix") => ε))</
All tests pass.
Line 2,696 ⟶ 3,054:
{{works with|rakudo|2015-11-28}}
This should work on infinite strings (if and when we get them), since <tt>.ords</tt> is lazy. In any case, it does just about the minimal work by evaluating all strings lazily in parallel. A few explanations of the juicy bits: <tt>@s</tt> is the list of strings, and the hyper operator <tt>»</tt> applies the <tt>.ords</tt> to each of those strings, producing a list of lists. The <tt>|</tt> operator inserts each of those sublists as an argument into an argument list so that we can use a reduction operator across the list of lists, which makes sense if the operator in question knows how to deal with list arguments. In this case we use the <tt>Z</tt> ('zip') metaoperator with <tt>eqv</tt> as a base operator, which runs <tt>eqv</tt> across all the lists in parallel for each position, and will fail if not all the lists have the same ordinal value at that position, or if any of the strings run out of characters. Then we count up the leading matching positions and carve up one of the strings to that length.
<syntaxhighlight lang="raku"
multi lcp($s) { ~$s }
multi lcp(*@s) { substr @s[0], 0, [+] [\and] [Zeqv] |@s».ords }
Line 2,710 ⟶ 3,068:
is lcp(), '';
is lcp("prefix","suffix"), '';
is lcp("foo","foobar"), 'foo';</
{{out}}
<pre>1..8
Line 2,724 ⟶ 3,082:
=={{header|REXX}}==
===version 1===
<
Call assert lcp("interspecies","interstellar","interstate"),"inters"
Call assert lcp("throne","throne"),"throne"
Line 2,764 ⟶ 3,122:
Leave
End
Return left(arg(1),i-1)</
{{out}}
<pre>test lcp("interspecies","interstellar","interstate")
Line 2,795 ⟶ 3,153:
===version 2===
This REXX version makes use of the '''compare''' BIF.
<
say LCP('interspecies', "interstellar", 'interstate')
say LCP('throne', "throne") /*2 strings, they are exactly the same.*/
Line 2,817 ⟶ 3,175:
m= t - 1; @= left(@, max(0, m) ) /*define maximum. */
end /*j*/
return ' longest common prefix=' @ /*return answer. */</
{{out|output|text= when using the default inputs:}}
<pre>
Line 2,864 ⟶ 3,222:
===version 3===
This REXX version explicitly shows ''null'' values and the number of strings specified.
<
say LCP('interspecies', "interstellar", 'interstate')
say LCP('throne', "throne") /*2 strings, they are exactly the same.*/
Line 2,890 ⟶ 3,248:
return ' longest common prefix=' shownull(@) /*return answer. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
showNull: procedure; parse arg z; if z=='' then z= "«null»"; return z</
{{out|output|text= when using the default inputs:}}
<pre>
Line 2,946 ⟶ 3,304:
=={{header|Ring}}==
<
# Project : Longest common prefix
Line 2,977 ⟶ 3,335:
see comp + nl
ok
</syntaxhighlight>
Output:
<pre>
inters
</pre>
=={{header|RPL}}==
≪ DUP SIZE → n
≪ '''CASE'''
n NOT '''THEN''' DROP "" '''END'''
n 1 == '''THEN''' 1 GET '''END'''
DUP ≪ SIZE ≫ DOLIST ≪ MIN ≫ STREAM <span style="color:grey">@ get the size of the smallest string</span>
'''IF''' DUP NOT '''THEN''' DROP2 "" '''ELSE'''
1 OVER '''FOR''' j
OVER 1 ≪ 1 j SUB ≫ DOLIST
'''IF''' ≪ == ≫ DOSUBS 1 + ΠLIST NOT '''THEN'''
j 1 - SWAP ‘j’ STO '''END'''
'''NEXT'''
SWAP 1 GET 1 ROT SUB
'''END END'''
≫ ≫ '<span style="color:blue">LCP</span>' STO
{ { "interspecies" "interstellar" "interstate" } { "throne" "throne" } { "throne" "dungeon" }{ "throne" "" "throne" } { "cheese" } { "" } { } { "prefix" "suffix" } { "foo" "foobar" } } ≪ <span style="color:blue">LCP</span> ≫ DOLIST
{{out}}
<pre>
1: { "inters" "throne" "" "" "cheese" "" "" "" "foo" }
</pre>
=={{header|Ruby}}==
<
return "" if strs.empty?
min, max = strs.minmax
Line 3,005 ⟶ 3,385:
data.each do |set|
puts "lcp(#{set.inspect[1..-2]}) = #{lcp(*set).inspect}"
end</
{{out}}
Line 3,024 ⟶ 3,404:
Rust String by default is utf-8 encoded. Since utf-8 is variable width, indexing in constant time is not possible. This example therefore uses byte strings (slices of u8) for the strings. The implementation shown here is similar to the Java implementation.
<syntaxhighlight lang="rust">
fn main() {
let strs: [&[&[u8]]; 7] = [
Line 3,067 ⟶ 3,447:
}
}
</syntaxhighlight>
'''Output:'''
Line 3,086 ⟶ 3,466:
> zip takeWhile: (i,i), (n,n), (t,t), (e,e), (r,r), (s,s) unzip < > "inters"
"intesteller" / \ i, n, t, e, r, s
</pre><
test("shared start") {
assert(lcp("interspecies","interstellar","interstate") === "inters")
Line 3,099 ⟶ 3,479:
def lcp(list: String*) = list.foldLeft("")((_,_) =>
(list.min.view,list.max.view).zipped.takeWhile(v => v._1 == v._2).unzip._1.mkString)
}</
=={{header|sed}}==
<syntaxhighlight lang="sed">$q
N
s/^\(.*\).*\(\n\)\1.*/\2\1/
D</syntaxhighlight>
{{out}}
<pre>
$ printf '%s\n' interspecies interstellar interstate | sed -f lcp.sed
inters
$ printf '%s\n' throne throne | sed -f lcp.sed
throne
$ printf '%s\n' throne dungeon | sed -f lcp.sed
$ printf '%s\n' throne '' throne | sed -f lcp.sed
$ printf '%s\n' cheese | sed -f lcp.sed
cheese
$ printf '%s\n' '' | sed -f lcp.sed
$ printf '%s\n' prefix suffix | sed -f lcp.sed
$ printf '%s\n' foo foobar | sed -f lcp.sed
foo
</pre>
=={{header|Sidef}}==
<
func find_common_prefix(hash, acc) {
if (hash.len == 1) {
Line 3,130 ⟶ 3,535:
return find_common_prefix(hash, '')
}</
Demonstration:
<
["interspecies","interstellar","interstate"],
["throne","throne"],
Line 3,147 ⟶ 3,552:
data.each { |set|
say "lcp(#{set.dump.substr(1,-1)}) = #{lcp(set...).dump}";
};</
{{out}}
<pre>
Line 3,164 ⟶ 3,569:
{{works with|Smalltalk/X}}
There is already a longestCommonPrefix method in Collection; however, if there wasn't, the following will do:
<
|end|
end := (a size) min:(b size).
Line 3,192 ⟶ 3,597:
) do:[:eachList |
Transcript show:eachList storeString; show:' ==> '; showCR:(lcp value:eachList)
]</
{{out}}
<pre>#('interspecies' 'interstellar' 'interstate') ==> inters
Line 3,205 ⟶ 3,610:
=={{header|Standard ML}}==
<
let
val longerFirst = fn pair as (a, b) =>
Line 3,215 ⟶ 3,620:
in
fn [] => "" | x :: xs => foldl (commonPrefix o longerFirst) x xs
end</
;Test<nowiki>:</nowiki>
<
["interspecies", "interstellar", "interstate"],
["throne", "throne"],
Line 3,229 ⟶ 3,634:
]
val () = (print o concat o map (fn lst => "'" ^ lcp lst ^ "'\n")) test</
{{out}}
<pre>'inters'
Line 3,242 ⟶ 3,647:
=={{header|Swift}}==
<
return String(zip(string1, string2).prefix(while: {$0 == $1}).map{$0.0})
}
Line 3,269 ⟶ 3,674:
printLongestCommonPrefix([])
printLongestCommonPrefix(["prefix", "suffix"])
printLongestCommonPrefix(["foo", "foobar"])</
{{out}}
Line 3,288 ⟶ 3,693:
Since [http://www.tcl.tk/cgi-bin/tct/tip/195.html TIP#195] this has been present as a core command:
<
% prefix longest {interstellar interspecies interstate integer} ""
inte
</syntaxhighlight>
=={{header|UNIX Shell}}==
{{works with|bash}}
<syntaxhighlight lang="bash">#!/bin/bash
lcp () {
local i=0 word c longest
case $# in
0)
return 1
;;
1)
printf %s "$1"
return
;;
esac
while :; do
c=
for word; do
[[ $i == ${#word} ]] && break 2
[[ -z $c ]] && c="${word:i:1}"
[[ ${word:i:1} != "$c" ]] && break 2
done
longest+="$c"
((i++))
done
printf %s "$longest"
}
mapfile -t tests <<'TEST'
interspecies interstellar interstate
throne throne
throne dungeon
throne throne
cheese
prefix suffix
foo foobar
TEST
for test in "${tests[@]}"; do
mapfile -t -d $'\t' words <<<"$test"
words=("${words[@]%$'\n'}")
printf '%s -> "%s"\n' "$(declare -p words)" "$(lcp "${words[@]}")"
done
</syntaxhighlight>
{{out}}
<pre>
declare -a words=([0]="throne" [1]="throne") -> "throne"
declare -a words=([0]="throne" [1]="dungeon") -> ""
declare -a words=([0]="throne" [1]="" [2]="throne") -> ""
declare -a words=([0]="cheese") -> "cheese"
declare -a words=() -> ""
declare -a words=([0]="prefix" [1]="suffix") -> ""
declare -a words=([0]="foo" [1]="foobar") -> "foo"
</pre>
=={{header|VBScript}}==
<
'declare an array
str = Split(s,",")
Line 3,346 ⟶ 3,812:
WScript.StdOut.Write "Test case " & n & " " & test(n) & " = " & lcp(test(n))
WScript.StdOut.WriteLine
Next</
{{out}}
Line 3,358 ⟶ 3,824:
=={{header|Visual Basic .NET}}==
{{trans|C#}}
<
Function LongestCommonPrefix(ParamArray sa() As String) As String
Line 3,403 ⟶ 3,869:
End Sub
End Module</
{{out}}
<pre>inters
Line 3,414 ⟶ 3,880:
foo</pre>
=={{header|V (Vlang)}}==
{{trans|go}}
<syntaxhighlight lang="v (vlang)">// lcp finds the longest common prefix of the input strings.
fn lcp(l []string) string {
// Special cases first
match l.len {
0 {
return ""
}
1 {
return l[0]
}
else {}
}
// LCP of min and max (lexigraphically)
// is the LCP of the whole set.
mut min, mut max := l[0], l[0]
for s in l[1..] {
if s < min {
min = s
} else if s > max {
max = s
}
}
for i := 0; i < min.len && i < max.len; i++ {
if min[i] != max[i] {
return min[..i]
}
}
// In the case where lengths are not equal but all bytes
// are equal, min is the answer ("foo" < "foobar").
return min
}
// Normally something like this would be a TestLCP function in *_test.go
// and use the testing package to report failures.
fn main() {
for l in [
["interspecies", "interstellar", "interstate"],
["throne", "throne"],
["throne", "dungeon"],
["throne", "", "throne"],
["cheese"],
[""],
[]string{},
["prefix", "suffix"],
["foo", "foobar"],
] {
println("lcp($l) = ${lcp(l)}")
}
}</syntaxhighlight>
{{out}}
<pre>Same as Go entry</pre>
=={{header|Wren}}==
{{trans|Kotlin}}
{{libheader|Wren-fmt}}
<
var lcp = Fn.new { |sa|
Line 3,449 ⟶ 3,969:
for (sa in lists) {
Fmt.print(" $-46s = $q", Fmt.v("q", 0, sa), lcp.call(sa))
}</
{{out}}
Line 3,467 ⟶ 3,987:
=={{header|XProfan}}==
<
Parameters long liste
Declare int longest, j, L, string s,t
Line 3,513 ⟶ 4,033:
ClearList 0
WaitKey
end</
{{out}}
<pre>
Line 3,528 ⟶ 4,048:
=={{header|zkl}}==
The string method prefix returns the number of common prefix characters.
<
Or, without using prefix:
{{trans|Scala}}
<
vm.arglist.reduce(fcn(prefix,s){ Utils.Helpers.zipW(prefix,s) // lazy zip
.pump(String,fcn([(a,b)]){ a==b and a or Void.Stop })
})
}</
<
tester.testRun(lcp.fp("interspecies","interstellar","interstate"),Void,"inters",__LINE__);
tester.testRun(lcp.fp("throne","throne"),Void,"throne",__LINE__);
Line 3,543 ⟶ 4,063:
tester.testRun(lcp.fp(""),Void,"",__LINE__);
tester.testRun(lcp.fp("prefix","suffix"),Void,"",__LINE__);
tester.stats();</
The fp (partial application) method is used to delay running lcp until the tester actually tests.
{{out}}
|