Movatterモバイル変換


[0]ホーム

URL:


Jump to content
Rosetta Code
Search

Longest substrings without repeating characters

From Rosetta Code
Longest substrings without repeating characters is adraft programming task. It is not yet considered ready to be promoted as a complete task, for reasons that should be found in itstalk page.
Task

Given a string,   find the  longest substring   without any repeating characters.


Other tasks related to string operations:
Metrics
Counting
Remove/replace
Anagrams/Derangements/shuffling
Find/Search/Determine
Formatting
Song lyrics/poems/Mad Libs/phrases
Tokenize
Sequences



11l

Translation of:Python: Some optimisation
F longest_substring2(s)   V max_subs = [s[0.<1]] * 0   V mx = 0   L(x) 0 .< s.len      L(y) x + 1 .. s.len         V sub = s[x .< y]         I y - x >= mx & sub.len == Set(Array(sub)).len            I y - x == mx & sub !C max_subs               max_subs.append(sub)            E               max_subs = [sub]               mx = y - x   R max_subsL(s) [‘xyzyabcybdfd’, ‘xyzyab’, ‘zzzzz’, ‘a’, ‘’]   print(s‘ => ’longest_substring2(s))V arr = [1, 2, 3, 4, 1, 2, 5, 6, 1, 7, 8, 1, 0]print(arr‘ => ’longest_substring2(arr))
Output:
xyzyabcybdfd => [zyabc, cybdf]xyzyab => [zyab]zzzzz => [z]a => [a] => [][1, 2, 3, 4, 1, 2, 5, 6, 1, 7, 8, 1, 0] => [[3, 4, 1, 2, 5, 6], [2, 5, 6, 1, 7, 8]]

Action!

BYTE FUNC GetLength(CHAR ARRAY s BYTE start)  BYTE ARRAY tab(256)  BYTE i  CHAR c  Zero(tab,256)  i=start  WHILE i<=s(0)  DO    c=s(i)    tab(c)==+1    IF tab(c)>1 THEN      EXIT    FI    i==+1  ODRETURN (i-start)PROC LongestSubstrings(CHAR ARRAY s)  CHAR ARRAY tmp(256)  BYTE count,maxLen,i,len  IF s(0)=0 THEN    RETURN  FI  i=1 maxLen=0  FOR i=1 TO s(0)  DO    len=GetLength(s,i)    IF len>maxLen THEN      maxLen=len    FI  OD  count=0  FOR i=1 TO s(0)  DO    len=GetLength(s,i)    IF len=maxLen THEN      IF count>0 THEN        Print(", ")      FI      SCopyS(tmp,s,i,i+maxlen-1)      PrintF("""%S""",tmp)      count==+1    FI  ODRETURNPROC Test(CHAR ARRAY s)  PrintF("Input: ""%S""%E",s)  Print("Result: [")  LongestSubstrings(s)  PrintE("]") PutE()RETURNPROC Main()  Test("xyzyabcybdfd")  Test("xyzyab")  Test("zzzzz")  Test("a")  Test("thisisastringtest")  Test("")RETURN
Output:

Screenshot from Atari 8-bit computer

Input: "xyzyabcybdfd"Result: ["zyabc", "cybdf"]Input: "xyzyab"Result: ["zyab"]Input: "zzzzz"Result: ["z", "z", "z", "z", "z"]Input: "a"Result: ["a"]Input: "thisisastringtest"Result: ["astring", "ringtes"]Input: ""Result: []

Ada

withAda.Text_IO;procedureLongest_SubstringisfunctionLongest(Item:String)returnStringisHist:array(Character)ofNatural:=(others=>0);First:Natural:=Item'First;Last:Natural:=Item'First-1;Longest_First:Natural:=Item'First;Longest_Last:Natural:=Item'First-1;procedureAdjustisbeginifLast-First>Longest_Last-Longest_FirstthenLongest_First:=First;Longest_Last:=Last;endif;endAdjust;beginifItem=""thenreturnItem;endif;forIndexinItem'RangeloopLast:=Index;Hist(Item(Index)):=Hist(Item(Index))+1;ifHist(Item(Index))=1thenAdjust;elseforAinFirst..Indexloopif(forallEofHist=>E<=1)thenFirst:=A;Adjust;exit;endif;Hist(Item(A)):=Hist(Item(A))-1;endloop;endif;endloop;returnItem(Longest_First..Longest_Last);endLongest;procedureTest(Item:String)isuseAda.Text_IO;beginPut("original : '");Put(Item);Put_Line("'");Put("longest  : '");Put(Longest(Item));Put_Line("'");endTest;beginTest("");Test("a");Test("xyzyabcybdfd");Test("thisisastringtest");Test("zzzzz");endLongest_Substring;
Output:
original : ''longest  : ''original : 'a'longest  : 'a'original : 'xyzyabcybdfd'longest  : 'zyabc'original : 'thisisastringtest'longest  : 'astring'original : 'zzzzz'longest  : 'z'

APL

Works with:Dyalog APL
lswrc{sfx,¨,\∘wrc(/⍨)(\=)ls(/⍨)(/=⊢)(¨)lswrc¨sfx}
Output:
      lswrc¨ 'xyzyabcybdfd' 'xyzyab' 'zzzzz' 'a' ''┌─────────────┬──────┬───────────┬───┬┐│┌─────┬─────┐│┌────┐│┌─┬─┬─┬─┬─┐│┌─┐││││cybdf│zyabc│││zyab│││z│z│z│z│z│││a││││└─────┴─────┘│└────┘│└─┴─┴─┴─┴─┘│└─┘││└─────────────┴──────┴───────────┴───┴┘

Arturo

unrepeatableSubstrings:function[s][result:[["",0]]ifzero?s->return[]ifone? s -> return @[s]loop0..decsizes'a[if(a+1)=<decsizes[loopa..decsizes'b[substr:to:stringslicesabss:sizesubstrifand?->ss>=lastmaximumresult'x->lastx->substr=uniquesubstr[result:(selectresult'x->ss=lastx)++@[@[substr,ss]]]]]]result:uniquemapresult'x->firstxreturnresult]loop["xyzyabcybdfd","xyzyab","zzzzz","a",""]'str->print[str"=> longest unrepeatable substring:"unrepeatableSubstringsstr]
Output:
xyzyabcybdfd => longest unrepeatable substring: [zyabc cybdf] xyzyab => longest unrepeatable substring: [zyab] zzzzz => longest unrepeatable substring: [z] a => longest unrepeatable substring: [a]  => longest unrepeatable substring: []

AutoHotkey

LSWRC(str){found:=[],result:=[],maxL:=0if(StrLen(str)=1)result[str]:=trueelsewhile(StrLen(str)>=2){s:=strwhileStrLen(s)>=maxL{if!(s~="(.).*\1"){found[s]:=truemaxL:=maxL<StrLen(s)?StrLen(s):maxLbreak}s:=SubStr(s,1,StrLen(s)-1); trim last chr}str:=SubStr(str,2); trim 1st chr and try again}maxL:=0forstrinfoundmaxL:=maxL<StrLen(str)?StrLen(str):maxLforstrinfoundif(StrLen(str)=maxL)result[str]:=truereturnresult}

Examples:

db=(xyzyabcybdfdxyzyabzzza)fori,lineinStrSplit(db,"`n","`r"){result:="[",i:=0forstrinLSWRC(line)result.=str", "output.=line"`t> "Trim(result,", ")"]`n"}MsgBox%outputreturn
Output:
xyzyabcybdfd> [cybdf, zyabc]xyzyab> [zyab]zzz> [z]a> [a]

BCPL

get "libhdr"// Fills up 'v' with words where w%0 is the start and w%1 is the end // of each longest substringlet lswrc(s, v) = valof$(  let seen = vec 255    let start = 1 and i = 1 and maxStart = 1 and maxEnd = 1 and n = 0        for i=0 to 255 do i!seen := false    while i <= s%0    $(  test (s%i)!seen            while (s%i)!seen            $(  (s%start)!seen := false                start := start + 1            $)        or        $(  (s%i)!seen := true            if i - start >= maxEnd - maxStart             $(  maxStart := start                maxEnd := i                while n>0 & (v+n-1)%1 - (v+n-1)%0 < i-start                    do n := n-1                (v+n)%0 := start                 (v+n)%1 := i                 n := n+1            $)            i := i + 1        $)    $)    resultis n$)let substr(s, start, end, buf) = valof$(  buf%0 := end - start + 1    for i = start to end do        buf%(i-start+1) := s%i    resultis buf$)let example(s) be$(  let v = vec 32 and b = vec 32    let n = lswrc(s, v)    writef("Original string: '%s'*N", s)    writes("Longest substrings: ")        test n=0 do        writes("<empty>")     or for i = 0 to n-1 do        writef("'%s' ", substr(s, (v+i)%0, (v+i)%1, b))    wrch('*N')$)let start() be$(  example("xyzyabcybdfd")    example("xyzyab")    example("zzzzz")    example("a")    example("")$)
Output:
Original string: 'xyzyabcybdfd'Longest substrings: 'zyabc' 'cybdf'Original string: 'xyzyab'Longest substrings: 'zyab'Original string: 'zzzzz'Longest substrings: 'z' 'z' 'z' 'z' 'z'Original string: 'a'Longest substrings: 'a'Original string: ''Longest substrings: <empty>

BQN

LongUniq´=(¨)/`/¨

Alternative:

LongUniq´(¨)0¨

Test:

LongUniq¨"a""""zzz""xyzyab""xyzyabcybdfd"
Output:
┌─· ⟨ "a" ⟩ ⟨ ⟨⟩ ⟩ ⟨ "z" "z" "z" ⟩ ⟨ "zyab" ⟩ ⟨ "zyabc" "cybdf" ⟩                                                            ┘

C

#include<stdio.h>#include<stdlib.h>#include<string.h>#include<stdbool.h>structsubstr{constchar*start;size_tlength;};structsubstr*lswrc(constchar*str){size_tlength=strlen(str);structsubstr*arr=malloc(sizeof(structsubstr)*(length+1));if(!arr)returnNULL;size_tstart=0,i=0,maxStart=0,maxEnd=0,n=0;boolused[256]={false};for(i=0;i<length;i++){while(used[(unsignedchar)str[i]])used[(unsignedchar)str[start++]]=false;used[(unsignedchar)str[i]]=true;if(i-start>=maxEnd-maxStart){maxStart=start;maxEnd=i;size_tlen=maxEnd-maxStart+1;while(n>0&&arr[n-1].length<len)n--;arr[n].start=&str[start];arr[n].length=len;n++;}}arr[n].start=NULL;arr[n].length=0;returnrealloc(arr,sizeof(structsubstr)*(n+1));}intmain(){char*examples[]={"xyzyabcybdfd","xyzyab","zzzzz","a","",NULL};for(size_ti=0;examples[i];i++){printf("Original string:\"%s\"\n",examples[i]);printf("Longest substrings: ");structsubstr*ls=lswrc(examples[i]);for(size_tj=0;ls[j].start;j++)printf("\"%.*s\" ",(int)ls[j].length,ls[j].start);printf("\n");free(ls);}return0;}
Output:
Original string: "xyzyabcybdfd"Longest substrings: "zyabc" "cybdf"Original string: "xyzyab"Longest substrings: "zyab"Original string: "zzzzz"Longest substrings: "z" "z" "z" "z" "z"Original string: "a"Longest substrings: "a"Original string: ""Longest substrings:

C++

#include<iostream>#include<fstream>#include<set>#include<sstream>#include<string>#include<vector>std::vector<std::string>longest_substrings_without_repeats(conststd::string&str){size_tmax_length=0;std::vector<std::string>result;size_tlength=str.size();for(size_toffset=0;offset<length;++offset){std::set<char>characters;size_tlen=0;for(;offset+len<length;++len){if(characters.find(str[offset+len])!=characters.end())break;characters.insert(str[offset+len]);}if(len>max_length){result.clear();max_length=len;}if(len==max_length)result.push_back(str.substr(offset,max_length));}returnresult;}voidprint_strings(conststd::vector<std::string>&strings){std::cout<<"[";for(size_ti=0,n=strings.size();i<n;++i){if(i>0)std::cout<<", ";std::cout<<'\''<<strings[i]<<'\'';}std::cout<<"]";}voidtest1(){for(std::stringstr:{"xyzyabcybdfd","xyzyab","zzzzz","a","thisisastringtest",""}){std::cout<<"Input: '"<<str<<"'\nResult: ";print_strings(longest_substrings_without_repeats(str));std::cout<<"\n\n";}}std::stringslurp(std::istream&in){std::ostringstreamout;out<<in.rdbuf();returnout.str();}voidtest2(conststd::string&filename){std::ifstreamin(filename);if(!in){std::cerr<<"Cannot open file '"<<filename<<"'.\n";return;}std::cout<<"Longest substring with no repeats found in '"<<filename<<"': ";print_strings(longest_substrings_without_repeats(slurp(in)));std::cout<<"\n";}intmain(){test1();test2("unixdict.txt");}
Output:
Input: 'xyzyabcybdfd'Result: ['zyabc', 'cybdf']Input: 'xyzyab'Result: ['zyab']Input: 'zzzzz'Result: ['z', 'z', 'z', 'z', 'z']Input: 'a'Result: ['a']Input: 'thisisastringtest'Result: ['astring', 'ringtes']Input: ''Result: []Longest substring with no repeats found in 'unixdict.txt': ['mboweldisgrunt']

EasyLang

func$[] longstr s$ .   subr maxtest      if len sub$ >= max         if len sub$ > max            max = len sub$            max$[] = [ ]         .         max$[] &= sub$      .   .   s$[] = strchars s$   len empty[] 255   len pos[] 255   pos = 1   while pos <= len s$[]      c = strcode s$[pos]      if pos[c] > 0         maxtest         pos = pos[c] + 1         pos[] = empty[]         sub$ = ""         c = strcode s$[pos]      .      pos[c] = pos      sub$ &= strchar c      pos += 1   .   maxtest   return max$[].for s$ in [ "xyzyabcybdfd" "xyzyab" "zzzzz" "a" "thisisastringtest" "" ]   print longstr s$.
Output:
[ "zyabc" "cybdf" ][ "zyab" ][ "z" "z" "z" "z" "z" ][ "a" ][ "astring" "ringtes" ][ "" ]

Factor

Works with:Factor version 0.99 2021-06-02
USING:formattinggroupingiokernelmathsequencessets;:unique-substrings(seqn--newseq)tuck<clumps>[cardinality=]withfilter;:longest-unique-substring(seq--newseq)duplength{}[2dupempty?swap0>and][drop2dupunique-substrings[1-]dip]while2nip[""like]mapmembers;:test(seq--)duplongest-unique-substring"%u -> %u\n"printf;"Longest substrings without repeating characters:"print{"xyzyabcybdfd""xyzyab""zzzzz""a"""}[test]each
Output:
Longest substrings without repeating characters:"xyzyabcybdfd" -> { "zyabc" "cybdf" }"xyzyab" -> { "zyab" }"zzzzz" -> { "z" }"a" -> { "a" }"" -> { }

FreeBASIC

dimasstringexample="antidisestablishmentarianism is a long word and so is flibbertigibbet."functionnrls(tasstring)asstringdimasintegerbest=0,best_length=-100,i=1,j,k,curr_lengthdimasstringcfori=1tolen(t)+1curr_length=0forj=i+1tolen(t)+1curr_length+=1c=mid(t,j,1)fork=itoj-1ifc=mid(t,k,1)thengotonextinextknextjnexti:ifcurr_length>best_lengththenbest_length=curr_lengthbest=iendifnextireturnmid(t,best,best_length)endfunctionprint">";nrls(example);"<"print">";nrls("My spoon is too big.");"<"print">";nrls("Rosetta Code.");"<"print">";nrls("AAAAA");"<"print">";nrls("abcdefghijklmnopqrstuvwxyz");"<"print">";nrls("aaa aeiou uuu");"<"
Output:

>blishmentar<>My spo<>ta Code.<>A<>abcdefghijklmnopqrstuvwxyz<> aeiou<

FutureBasic

local fn substrings( t as CFStringRef )  int beg, c, f, rpt, max = 0  for beg = 0 to len(t) - 1    rpt = instr( beg+1, t, mid(t, beg, 1), NSCaseInsensitiveSearch )    if rpt < 0 then rpt = len(t)    c = beg + 1    while c < rpt      f = instr(c + 1, t, mid(t, c, 1), NSCaseInsensitiveSearch)      if f < 0 then f = len(t) else if f < rpt then rpt = f      c++    wend    if rpt - beg < max then continue    if rpt - beg > max then max = rpt - beg : mda_clear    mda_add(0) = mid(t, beg, max)  next  print @"\n   The string: \"";t;@"\"\n  Substring/s: ";  for c = 0 to mda_count(0) -1    print @"\"";mda(c);@"\"  ";  next  printend fnwindow 1, @"Longest Substring/s Without Repeated Letters"fn substrings(@"xyzyabcybdfd")fn substrings(@"thisisastringtest")fn substrings(@"My spoon is too big.")fn substrings(@"Rosetta Code")fn substrings(@"AaAaA")fn substrings(@"abcdefghijklmnopqrstuvwxyz")fn substrings(@"aaa aeiou uuu")fn substrings(@"abcdABCD")handleevents
Output:

File:Longest Substrings without Repeated Letters.png

Go

Translation of:Wren
packagemainimport"fmt"funcsubstrings(sstring)[]string{n:=len(s)ifn==0{return[]string{""}}varss[]stringfori:=0;i<n;i++{forle:=1;le<=n-i;le++{ss=append(ss,s[i:i+le])}}returnss}funcdistinctRunes(chars[]rune)[]rune{m:=make(map[rune]bool)for_,char:=rangechars{m[char]=true}varl[]runefork:=rangem{l=append(l,k)}returnl}funcdistinctStrings(strings[]string)[]string{m:=make(map[string]bool)for_,str:=rangestrings{m[str]=true}varl[]stringfork:=rangem{l=append(l,k)}returnl}funcmain(){fmt.Println("The longest substring(s) of the following without repeating characters are:\n")strs:=[]string{"xyzyabcybdfd","xyzyab","zzzzz","a",""}for_,s:=rangestrs{varlongest[]stringlongestLen:=0for_,ss:=rangesubstrings(s){iflen(distinctRunes([]rune(ss)))==len(ss){iflen(ss)>=longestLen{iflen(ss)>longestLen{longest=longest[:0]longestLen=len(ss)}longest=append(longest,ss)}}}longest=distinctStrings(longest)fmt.Printf("String = '%s'\n",s)fmt.Println(longest)fmt.Printf("Length = %d\n\n",len(longest[0]))}}
Output:
The longest substring(s) of the following without repeating characters are:String = 'xyzyabcybdfd'[zyabc cybdf]Length = 5String = 'xyzyab'[zyab]Length = 4String = 'zzzzz'[z]Length = 1String = 'a'[a]Length = 1String = ''[]Length = 0

J

Implementation:

longnorep=:{{c=.#ywhile.ss=.c]\ydo.cnt=.#@~."1ssif.ce.cntdo.~.ss#~c=cntreturn.end.c=.c-1end.}}

Examples:

longnorep'xyzyabcybdfd'zyabccybdflongnorep'xyzyab'zyablongnorep'zzzzz'zlongnorep''longnorep'astring'astringlongnorep'thisisastringtest'astringringteslongnorep'Thequickbrownfoxjumpsoverthelazydog'Thequickbrownf

This also works on sequences of numbers (though the character representation of the sequences of numbers may contain repeated characters, the represented numbers will not contain repetitions):

longnorep1234125617810341256256178

Java

importjava.util.ArrayList;importjava.util.HashSet;importjava.util.List;importjava.util.Set;publicfinalclassLongestSubstringsWithoutRepeatingCharacters{publicstaticvoidmain(String[]args){System.out.println("The longest substring(s) of the following without repeating characters are:");System.out.println();List<String>tests=List.of("xyzyabcybdfd","xyzyab","zzzzz","a","");tests.forEach(test->{List<String>result=newArrayList<String>();intlongestLength=0;for(Stringsubstring:allSubstrings(test)){if(substring.length()==substring.chars().distinct().count()){if(substring.length()>=longestLength){if(substring.length()>longestLength){result.clear();longestLength=substring.length();}result.addLast(substring);}}}System.out.println("String = '"+test+"' => "+result+" with length = "+result.getFirst().length());});}privatestaticSet<String>allSubstrings(Stringtext){Set<String>result=newHashSet<String>();result.add("");for(inti=0;i<text.length();i++){for(intj=i+1;j<=text.length();j++){result.add(text.substring(i,j));}}returnresult;}}
Output:
The longest substring(s) of the following without repeating characters are:String = 'xyzyabcybdfd' => [cybdf, zyabc] with length = 5String = 'xyzyab' => [zyab] with length = 4String = 'zzzzz' => [z] with length = 1String = 'a' => [a] with length = 1String = '' => [] with length = 0

jq

Adapted fromJulia

Works with:jq

Works with gojq, the Go implementation of jq

# Use a dictionary for speed in case of very long stringsdef alluniquehead:  length as $n  | if $n <= 1 then .    else . as $in    | {ix: -1}    | until(.i or (.ix == $n);         .ix += 1         | $in[.ix:.ix+1] as $x | if .dict[$x] then .i = .ix   else .dict[$x] = true           end )    | $in[: .ix]    end ;    def maximal_substring_with_distinct_characters:  . as $in  | length as $n  | {i: -1}  | until( .i == $n or .stop;      .i += 1      | if .max and .max > $n - .i then .stop = true        else ($in[.i:] | alluniquehead) as $head| if ($head|length) > .max  then .ans = $head  | .max = ($head|length)  else .  endend)  | .ans;

Test Cases

"xyzyabcybdfd","xyzyab","zzzzz","a", "α⊆϶α϶",""| "\"\(.)\" => \"\(maximal_substring_with_distinct_characters)\""
Output:
"xyzyabcybdfd" => "zyabc""xyzyab" => "zyab""zzzzz" => "z""a" => "a""α⊆϶α϶" => "α⊆϶""" => ""

Julia

Works on any array, treating a character string as a character array.

functionalluniquehead(arr)len=length(arr)iflen>1foriin2:lenifarr[i]in@viewarr[1:i-1]returnarr[1:i-1]endendendreturnarr[:]endfunctionmaxuniques(arr)length(arr)<2&&returnarramax=[alluniquehead(@viewarr[i:end])foriin1:length(arr)]maxlen=maximum(map(length,amax))returnfilter(a->length(a)==maxlen,amax)endforsin["xyzyabcybdfd","xyzyab","zzzzz","a","α⊆϶α϶","",[1,2,3,4,1,2,5,6,1,7,8,1,0]]uarray=maxuniques(collect(s))!isempty(uarray)&&length(uarray[1])>1&&uarray[1][1]isaChar&&(uarray=String.(uarray))println("\"$s\" => ",uarray)end
Output:
"xyzyabcybdfd" => ["zyabc", "cybdf"]"xyzyab" => ["zyab"]"zzzzz" => [['z'], ['z'], ['z'], ['z'], ['z']]"a" => ['a']"α⊆϶α϶" => ["α⊆϶", "⊆϶α"]"" => Char[]"[1, 2, 3, 4, 1, 2, 5, 6, 1, 7, 8, 1, 0]" => [[3, 4, 1, 2, 5, 6], [2, 5, 6, 1, 7, 8]]

Miranda

main :: [sys_message]main = [ Stdout (show test ++ " -> " ++ show (lswrc test) ++ "\n")       | test <- tests]tests :: [[char]]tests = ["xyzyabcybdfd", "xyzyab", "zzz", "a"]lswrc :: [*]->[[*]]lswrc s = nub [s' | s'<-noreps; #s' = maxlen]          where maxlen            = max (map (#) noreps)                noreps            = [norep (drop n s) | n<-[0..#s-1]]                norep             = reverse . norep' []                norep' mem []     = mem                norep' mem (a:as) = mem, if a $in mem                                  = norep' (a:mem) as, otherwisein :: *->[*]->boolin item []     = Falsein item (a:as) = a = item \/ item $in asnub :: [*]->[*]nub = reverse . nub' []      where nub' mem []     = mem            nub' mem (a:as) = nub' mem as,     if a $in mem                            = nub' (a:mem) as, otherwise
Output:
"xyzyabcybdfd" -> ["zyabc","cybdf"]"xyzyab" -> ["zyab"]"zzz" -> ["z"]"a" -> ["a"]

Modula-2

MODULELSWRC;FROMInOutIMPORTWriteString,WriteLn;FROMStringsIMPORTLength,Copy;TYPERange=RECORDstart,length:CARDINAL;END;(* Returns start and length of every longest substring *)PROCEDURElswrc(in:ARRAYOFCHAR;VARout:ARRAYOFRange):CARDINAL;VARi,num,start,strlen,len,maxStart,maxEnd:CARDINAL;used:ARRAY[0..255]OFBOOLEAN;BEGINFORi:=0TO255DOused[i]:=FALSE;END;strlen:=Length(in);start:=0;maxStart:=0;maxEnd:=0;i:=0;num:=0;WHILEi<strlenDOIFNOTused[ORD(in[i])]THENused[ORD(in[i])]:=TRUE;IF(i-start)>=(maxEnd-maxStart)THENmaxStart:=start;maxEnd:=i;len:=(maxEnd-maxStart+1);WHILE(num>0)AND(out[num-1].length<len)DODEC(num);END;out[num].start:=start;out[num].length:=len;INC(num);END;INC(i);ELSEWHILEused[ORD(in[i])]DOused[ORD(in[start])]:=FALSE;INC(start);END;END;END;RETURNnum;ENDlswrc;PROCEDUREExample(s:ARRAYOFCHAR);VARbuf:ARRAY[0..127]OFCHAR;ranges:ARRAY[0..127]OFRange;i,n:CARDINAL;BEGINWriteString("Original string: ");WriteString(s);WriteLn();n:=lswrc(s,ranges);WriteString("Longest substrings: ");IFn=0THENWriteString("<empty>");ELSEFORi:=0TOn-1DOCopy(s,ranges[i].start,ranges[i].length,buf);buf[ranges[i].length]:=CHR(0);WriteString(buf);WriteString(" ");END;END;WriteLn();ENDExample;BEGINExample("xyzyabcybdfd");Example("xyzyab");Example("zzzzz");Example("a");Example("");ENDLSWRC.
Output:
Original string: xyzyabcybdfdLongest substrings: zyabc cybdfOriginal string: xyzyabLongest substrings: zyabOriginal string: zzzzzLongest substrings: z z z z zOriginal string: aLongest substrings: aOriginal string:Longest substrings: <empty>

Nim

This version converts strings to sequences of runes.

importsequtils,strutils,unicodetypeRunes=seq[Rune]funclongestSubstrings(str:string):seq[string]=varrunes=str.toRunesvarcurrent:Runesvarres:seq[Runes]# Result as a list of Runes.varmaxlen=0forcinrunes:letidx=current.find(c)ifidx>=0:ifcurrent.len>maxlen:res=@[current]maxlen=current.lenelifcurrent.len==maxlenandcurrentnotinres:res.addcurrentcurrent.delete(0,idx)current.addc# Process the last current string.ifcurrent.len>maxlen:res=@[current]elifcurrent.len==maxlenandcurrentnotinres:res.addcurrentresult=res.mapIt($it)forstrin["xyzyabcybdfd","xyzyab","zzzzz","a","α⊆϶α϶",""]:echo'"',str,'"'," → ",longestSubstrings(str)echo"\nLongest substrings in concatenated list of words from “unixdict.txt”: ",longestSubstrings(toSeq("unixdict.txt".lines).join())
Output:
"xyzyabcybdfd" → @["zyabc", "cybdf"]"xyzyab" → @["zyab"]"zzzzz" → @["z"]"a" → @["a"]"α⊆϶α϶" → @["α⊆϶", "⊆϶α"]"" → @[""]Longest substrings in concatenated list of words from “unixdict.txt”: @["mboweldisgrunt"]

Perl

Gets the same answer that raku does when run against unixdict.txt

#!/usr/bin/perlusestrict;# Longest_substrings_without_repeating_charactersusewarnings;formy$string(qw( xyzyabcybdfd xyzyab zzzzz a thisisastringtest )){local$_=$string;my@sub;length$+>=$#suband++$sub[length$+]{$+}whiles/.*(.)(.*\K\1.*)|(.+)//s;printf"%20s -> %s\n",$string,join' ',sortkeys%{pop@sub};}
Output:
        xyzyabcybdfd -> cybdf zyabc              xyzyab -> zyab               zzzzz -> z                   a -> a   thisisastringtest -> astring ringtes

Phix

Single pass, maintains a start position and a table of seen character positions.
If the current character has occurred after start, move that along, then add any longer/equal length start..i to the result set.
Note that having moved start along we certainly won't be any longer than but may still beequal to maxlen.
Should be exponentially faster than collecting all possible substrings and eliminating those with duplicate characters or too short.
It will however collect duplicates (when long enough) before weeding them out at the end.

withjavascript_semanticsfunctionlongest_substrings(sequences)--    -- s can be a normal 8-bit acsii/ansi string or a    -- 32-bit unicode sequence from eg utf8_to_utf32().    -- It will not complain if given utf-8, but may    -- chop up multibyte characters inappropriately.    -- s must not contain any 0 or non-integers.    --sequenceres={},found=repeat(0,256)-- (ansi, position)integerstart=1,maxlen=0fori=1tolength(s)dointegersi=s[i]-- (deliberate typecheck)ifsi>length(found)then-- (must be unicode then)assert(si<=#10FFFF)-- (limit size to valid chars)found&=repeat(0,si-length(found))elseintegerfi=found[si]iffi>=startthenstart=fi+1endifendiffound[si]=iintegernewlen=i-start+1ifnewlen>=maxlenthenifnewlen>maxlenthenres={}maxlen=newlenendifres=append(res,s[start..i])endifendforres=unique(res,"STABLE")returnresendfunction?longest_substrings("xyzyabcybdfd")?longest_substrings("xyzyab")?longest_substrings("zzzzz")?longest_substrings("a")?longest_substrings("")
Output:
{"zyabc","cybdf"}{"zyab"}{"z"}{"a"}{}

A quick test on unixdict.txt yielded the same results as Raku.

Python

The following algorithm works but is not terribly efficient for long strings.

deflongest_substring(s="xyzyab"):substr=[s[x:y]forxinrange(len(s))foryinrange(x+1,len(s)+1)]no_reps=[]forsubinsubstr:iflen(sub)==len(set(sub))andsubnotinno_reps:no_reps.append(sub)max_len=max(len(sub)forsubinno_reps)ifno_repselse0max_subs=[subforsubinno_repsiflen(sub)==max_len]returnmax_subsif__name__=='__main__':forsin["xyzyabcybdfd","xyzyab","zzzzz","a","α⊆϶α϶","",[1,2,3,4,1,2,5,6,1,7,8,1,0]]:print(f"{s} =>{longest_substring(s)}")
Output:
xyzyabcybdfd => ['zyabc', 'cybdf']xyzyab => ['zyab']zzzzz => ['z']a => ['a']α⊆϶α϶ => ['α⊆϶', '⊆϶α'] => [][1, 2, 3, 4, 1, 2, 5, 6, 1, 7, 8, 1, 0] => [[3, 4, 1, 2, 5, 6], [2, 5, 6, 1, 7, 8]]

Python: Some optimisation

The following algorithm only accrues the longest so far.

deflongest_substring2(s="xyzyab"):max_subs,mx=[],0forxinrange(len(s)):foryinrange(x+1,len(s)+1):sub=s[x:y]ify-x>=mxandlen(sub)==len(set(sub)):ify-x==mxandsubnotinmax_subs:max_subs.append(sub)else:max_subs,mx=[sub],y-xreturnmax_subs
Output:

It gives the same output as functionlongest_substring() above.

Raku

Detectsany character when checking for repeated characters, even multi-byte composite characters, control sequences and whitespace.

Note that there is no requirement that the substrings be unique, only that each has no repeated characters internally.

Not going to bother handling arrays since an array is not a string, and the task descriptionspecifically says 'Given a string'.

subabbreviate ($_) { .chars >80 ??"(abbreviated)\n" ~ .substr(0,35) ~' ... ' ~ .substr(*-35) !!$_ }sublongest ($string) {return0 => []unless$string.chars;my ($start,$end,@substr) =0,0;while ++$end <$string.chars {my$sub =$string.substr($start,$end -$start);if$sub.contains:my$next =$string.substr:$end,1 {@substr[$end -$start].push($sub)if$end -$start >=@substr.end;$start +=1 +$sub.index($next);       }   }@substr[$end -$start].push:$string.substr($start);@substr.pairs.tail}# Testingsay"\nOriginal string: {abbreviate $_}\nLongest substring(s) chars: ", .&longest# Standard testsforflatqww<xyzyabcybdfdxyzyabzzzzza'' >,# multibyte Unicode< 👒🎩🎓👩‍👩‍👦‍👦🧢🎓👨‍👧‍👧👒👩‍👩‍👦‍👦🎩🎓👒🧢α⊆϶α϶ >,# check a fileslurp'unixdict.txt';
Output:
Original string: xyzyabcybdfdLongest substring(s) chars: 5 => [zyabc cybdf]Original string: xyzyabLongest substring(s) chars: 4 => [zyab]Original string: zzzzzLongest substring(s) chars: 1 => [z z z z z]Original string: aLongest substring(s) chars: 1 => [a]Original string: Longest substring(s) chars: 0 => []Original string: 👒🎩🎓👩‍👩‍👦‍👦🧢🎓👨‍👧‍👧👒👩‍👩‍👦‍👦🎩🎓👒🧢Longest substring(s) chars: 6 => [🧢🎓👨‍👧‍👧👒👩‍👩‍👦‍👦🎩]Original string: α⊆϶α϶Longest substring(s) chars: 3 => [α⊆϶ ⊆϶α]Original string: (abbreviated)10th1st2nd3rd4th5th6th7th8t ... rianzoundszucchinizurichzygoteLongest substring(s) chars: 15 => [mboweldisgrunt]

REXX

/*REXX pgm finds the longest substring (in a given string) without a repeating character*/parsearg$/*obtain optional argument from the CL.*/if$==''|$==","then$='xyzyabcybdfd'/*Not specified?  Then use the default.*/L=length($)/*L:    the length of the given string.*/maxL=0/*MAXL: max length substring  (so far).*/@.=/*array to hold the max len substrings.*/doj=1forL;b=substr($,j,1)/*search for max length substrings.    */x=/*X:   the substring, less the 1st char*/dok=j+1toL;x=x||substr($,k,1)/*search for the max length substrings.*/if\OKx(x)theniteratej/*Are there an replications?  Skip it. */_=length(x);if_<maxLtheniterate/*is length less then the current max? */@._=@._x;maxL=_/*add this substring to the max list.  */end/*k*/end/*j*/say'longest substring's(words(@.maxL))"in "$' ───► '@.maxLexit0/*stick a fork in it,  we're all done. *//*──────────────────────────────────────────────────────────────────────────────────────*/s:ifarg(1)==1thenreturnarg(3);returnword(arg(2)'s',1)/*simple pluralizer*//*──────────────────────────────────────────────────────────────────────────────────────*/OKx:procedure;parseargy;dor=1forlength(y)-1/*look for duplicate chars.*/ifpos(substr(y,r,1),y,r+1)>0thenreturn0end/*r*/;return1
output  when using the default input:
longest substrings in  xyzyabcybdfd  ───►   zyabc cybdf

Ring

see "working..." + nlsee "Longest substrings without repeating characters are:" + nlstr = "xyzyabcybdfd"see "Input: " + str + nllenStr = len(str)strOk = []lenOk = 0for n = 1 to lenStr    for m = 1 to lenStr-n+1        temp = substr(str,n,m)        add(strOk,temp)    nextnextfor n = len(strOk) to 1 step -1    if len(strOK[n]) = 1       del(strOK,n)    oknextfor n = 1 to len(strOK)    for m = 1 to len(strOK)-1        if len(strOK[m+1]) > len(strOK[m])           temp = strOK[m]           strOK[m] = strOK[m+1]           strOK[m+1] = temp        ok    nextnextfor n = 1 to len(strOK)    flag = 1    for m = 1 to len(strOK[n])        for p = m+1 to len(strOK[n])            if strOK[n][m] = strOK[n][p]               flag = 0               exit            ok        next    next    if flag = 1       if len(strOK[n]) >= lenOk          see "len = " + len(strOK[n]) + " : " + strOK[n] + nl          lenOK = len(strOK[n])       ok    oknextsee "done..." + nl
Output:
working...Longest substrings without repeating characters are:Input: xyzyabcybdfdlen = 5 : zyabclen = 5 : cybdfdone...

Rust

useitertools::Itertools;usestd::fs;fnnonrepeating(s:&str)->Vec<String>{letmutmax_subs:Vec<String>=vec![];letmutmx=0_usize;foriin0..s.len(){forjini+1..=s.len(){letsub=&s[i..j];letsubbytes=sub.chars().sorted().dedup();ifj-i>=mx&&sub.len()==subbytes.collect_vec().len(){ifj-i==mx&&!max_subs.contains(&sub.to_string()){max_subs.push(sub.to_string());}else{max_subs=vec![sub.to_string()];mx=j-i;}}}}returnmax_subs;}fnmain(){letwordsfile=fs::read_to_string("unixdict.txt").unwrap().to_lowercase();letresults=wordsfile.split_whitespace().map(|w|format!("{} ==> {:?}",w,nonrepeating(w)));forsinresults{println!("{}",s);}}
Output:
10th ==> ["10th"]1st ==> ["1st"]2nd ==> ["2nd"]3rd ==> ["3rd"]4th ==> ["4th"]5th ==> ["5th"]6th ==> ["6th"]7th ==> ["7th"]8th ==> ["8th"]9th ==> ["9th"]a ==> ["a"]a&m ==> ["a&m"]a&p ==> ["a&p"]a's ==> ["a's"]aaa ==> ["a"]aaas ==> ["as"]aarhus ==> ["arhus"]aaron ==> ["aron"]    ... many lines ...zone ==> ["zone"]zoo ==> ["zo"]zoology ==> ["logy"]zoom ==> ["zo", "om"]zorn ==> ["zorn"]zoroaster ==> ["roaste", "oaster"]zoroastrian ==> ["oastri", "strian"]zounds ==> ["zounds"]zucchini ==> ["chin"]zurich ==> ["zurich"]zygote ==> ["zygote"]

VBScript

functionnrls(byvals1)dimi,xiflen(s1)<2thennlrs=s:exitfunctions=lcase(replace(s1," ",""))redima(127)dimls:ls=len(s)start=1so=""ml=1a(asc(left(s,1)))=1fori=2tols+1ifi>lsthenrep=trueelsex=asc(mid(s,i,1))rep=a(x)<>0endififa(x)<>0thenif(i-start)>mlthenso=mid(s,start,i-start)ml=(i-start)elseif(i-start)=mlthenso=so&" "&mid(s,start,i-start)endifxx=a(x)forj=96to122:ifa(j)<=xthena(j)=0nextstart=xx+1endifa(x)=inextnrls=trim(so)eraseaendfunctionsubtest(f)wscript.stdout.writeline"Original:   "&fwscript.stdout.writeline"Substrings: "&nrls(f)&vbcrlfendsubtest"dabale arroz a la zorra el abad"test"The quick brown fox jumps over the lazy dog"test"ae"test"aa"test"abdefghij"
Output:
Original:   dabale arroz a la zorra el abadSubstrings: rozal lazorOriginal:   The quick brown fox jumps over the lazy dogSubstrings: thequickbrownfOriginal:   aeSubstrings: aeOriginal:   aaSubstrings: a aOriginal:   abdefghijSubstrings: abdefghij

V (Vlang)

Translation of:go
fn substrings(s string) []string {    n := s.len    if n == 0 {        return [""]    }    mut ss := []string{}    for i in 0..n {        for le := 1; le <= n-i; le++ {            ss << s[i..i+le]        }    }    return ss} fn distinct_runes(chars []rune) []rune {    mut m := map[rune]bool{}    for c in chars {        m[c] = true    }    mut l := []rune{}    for k,_ in m {        l << k    }    return l} fn distinct_strings(strings []string) []string {    mut m := map[string]bool{}    for str in strings {        m[str] = true    }    mut l := []string{}    for k,_ in m {        l << k    }    return l} fn main() {    println("The longest substring(s) of the following without repeating characters are:\n")    strs := ["xyzyabcybdfd", "xyzyab", "zzzzz", "a", ""]    for s in strs {        mut longest := []string{}        mut longest_len := 0        for ss in substrings(s) {            if distinct_runes(ss.runes()).len == ss.len {                if ss.len >= longest_len {                    if ss.len > longest_len {                        longest = longest[..0]                        longest_len = ss.len                    }                    longest << ss                }            }        }        longest = distinct_strings(longest)        println("String = '$s'")        println(longest)        println("Length = ${longest[0].len}\n")    }}
Output:
Same as Wren entry

Wren

Library:Wren-seq
import"./seq"forLstvarsubstrings=Fn.new{|s|varn=s.countif(n==0)return[""]varss=[]for(iin0...n){for(lenin1..n-i)ss.add(s[i...i+len])}returnss}System.print("The longest substring(s) of the following without repeating characters are:\n")varstrs=["xyzyabcybdfd","xyzyab","zzzzz","a",""]for(sinstrs){varlongest=[]varlongestLen=0for(ssinsubstrings.call(s)){if(Lst.distinct(ss.toList).count==ss.count){if(ss.count>=longestLen){if(ss.count>longestLen){longest.clear()longestLen=ss.count}longest.add(ss)}}}longest=Lst.distinct(longest)System.print("String = '%(s)'")System.print(longest)System.print("Length =%(longest[0].count)\n")}
Output:
The longest substring(s) of the following without repeating characters are:String = 'xyzyabcybdfd'[zyabc, cybdf]Length = 5String = 'xyzyab'[zyab]Length = 4String = 'zzzzz'[z]Length = 1String = 'a'[a]Length = 1String = ''[]Length = 0
Retrieved from "https://rosettacode.org/wiki/Longest_substrings_without_repeating_characters?oldid=375047"
Categories:
Hidden category:
Cookies help us deliver our services. By using our services, you agree to our use of cookies.

[8]ページ先頭

©2009-2025 Movatter.jp