Kürzeste eindeutige Teilzeichenfolgen

29

Eingang

Eine alphanumerische Zeichenfolge s.

Ausgabe

Die kürzeste Zeichenfolge, die genau einmal als (zusammenhängende) Teilzeichenfolge in vorkommt s. Überlappende Vorkommen werden als unterschiedlich gezählt. Wenn es mehrere Kandidaten gleicher Länge gibt, müssen Sie alle in der Reihenfolge ihres Auftretens ausgeben. Bei dieser Herausforderung kommt die leere Zeichenfolge n + 1einige Male in einer Zeichenfolge mit einer Länge vor n.

Beispiel

Betrachten Sie die Zeichenfolge

"asdfasdfd"

Die leere Zeichenfolge kommt zehnmal in der Zeichenfolge vor, sodass sie nicht für ein eindeutiges Vorkommen in Frage kommt. Jeder der Buchstaben "a", "s", "d", und "f"tritt mindestens zweimal, so dass sie nicht entweder Kandidaten. Die Teilzeichenfolgen "fa"und "fd"kommen nur einmal und in dieser Reihenfolge vor, während alle anderen Teilzeichenfolgen der Länge 2 zweimal vorkommen. Somit ist die korrekte Ausgabe

["fa","fd"]

Regeln

Es sind sowohl Funktionen als auch vollständige Programme zulässig und Standardlücken nicht. Die genaue Formatierung der Ausgabe ist innerhalb des Rahmens flexibel. Insbesondere ist es zulässig, für die leere Zeichenfolge keine Ausgabe zu erzeugen, für das Auslösen eines Fehlers jedoch nicht. Die niedrigste Byteanzahl gewinnt.

Testfälle

"" -> [""]
"abcaa" -> ["b","c"]
"rererere" -> ["ererer"]
"asdfasdfd" -> ["fa","fd"]
"ffffhhhhfffffhhhhhfffhhh" -> ["hffff","fffff","hhhhh","hfffh"]
"asdfdfasddfdfaddsasadsasadsddsddfdsasdf" -> ["fas","fad","add","fds"]

Bestenliste

Hier ist die Bestenliste nach Sprachen, die ich versprochen habe.

Um sicherzustellen, dass Ihre Antwort angezeigt wird, beginnen Sie Ihre Antwort mit einer Überschrift. Verwenden Sie dazu die folgende Markdown-Vorlage:

# Language Name, N bytes

Wo Nist die Größe Ihres Beitrags? Wenn Sie Ihren Score zu verbessern, Sie können alte Rechnungen in der Überschrift halten, indem man sich durch das Anschlagen. Zum Beispiel:

# Ruby, <s>104</s> <s>101</s> 96 bytes

<script src='https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js'></script><script>site = 'meta.codegolf',postID = 5314,isAnswer = true,QUESTION_ID = 45056;jQuery(function(){var u='https://api.stackexchange.com/2.2/';if(isAnswer)u+='answers/'+postID+'?order=asc&sort=creation&site='+site+'&filter=!GeEyUcJFJeRCD';else u+='questions/'+postID+'?order=asc&sort=creation&site='+site+'&filter=!GeEyUcJFJO6t)';jQuery.get(u,function(b){function d(s){return jQuery('<textarea>').html(s).text()};function r(l){return new RegExp('<pre class="snippet-code-'+l+'\\b[^>]*><code>([\\s\\S]*?)<\\/code><\/pre>')};b=b.items[0].body;var j=r('js').exec(b),c=r('css').exec(b),h=r('html').exec(b);if(c!==null)jQuery('head').append(jQuery('<style>').text(d(c[1])));if (h!==null)jQuery('body').append(d(h[1]));if(j!==null)jQuery('body').append(jQuery('<script>').text(d(j[1])))})})</script>

Zgarb
quelle
Gibt es Einschränkungen für kombinatorische integrierte Funktionen?
Martin Ender
3
@ MartinBüttner Bei dieser Herausforderung geht alles. Wenn dies ausreichend beantwortet wird, stelle ich eine Rangliste nach Sprachen auf, damit auch die schlecht ausgestatteten Sprachen einen bedeutenden Wettbewerb haben können.
Zgarb
Möchten Sie mein Code-Golf-Leaderboard-Snippet verwenden ? Dann müssten Sie nicht alle Änderungen überwachen, um die Bestenliste auf dem neuesten Stand zu halten. Wenn Sie dies tun, kann ich es für Sie hinzufügen, und ich würde die Antworten durchgehen, um sicherzustellen, dass sie mit dem Kopfzeilenformat übereinstimmen.
Martin Ender
@ MartinBüttner Danke, das würde ich begrüßen!
Zgarb
Alles erledigt! Lassen Sie mich wissen, wenn etwas nicht funktioniert. (Fühlen Sie sich frei, es für Ihre Herausforderungen in der Zukunft wiederzuverwenden.)
Martin Ender

Antworten:

3

Pyth, 27 26 Bytes

&zhfTmf!/>zhxzYYm<>zkdUzUz

Probieren Sie es hier aus.

Beachten Sie, dass aufgrund eines Fehlers im Online-Compiler die Groß- und Kleinschreibung für leere Zeichenfolgen nur in der Befehlszeilenversion korrekt funktioniert, die gefunden werden kann hier.

Sie können den Fehler auch beheben, indem Sie eine neue Zeile als Eingabe für den Online-Compiler angeben.

Erläuterung:

                                   z = input(), implicit.
&z                                 Prints empty string if input is empty.
  hfT                              Take the first non-empty list from
     m                  Uz         A list of list of substrings of z, divided by length
                m<>zkdUz           with some shorter strings repeated later, to no effect.
      f                            Where the substrings are filtered on
       !/      Y                   There being 0 occurrences of the substring in
         >z                        The slice of z
           hxzY                    from the character after the first character
                                   of the first occurrence of the substring in z
                                   to the end of z.
isaacg
quelle
Fehler bei der Eingabe einer leeren Zeichenfolge.
Optimierer
@Optimizer Ich denke, das ist eigentlich ein Fehler im Online-Compiler. Es funktioniert auf der Kommandozeilenversion. Tatsächlich zschlägt keine Eingabe online fehl, so dass es definitiv ein Fehler im Interpreter ist.
Isaacg
Gibt es keine EOF?
Optimierer
@Optimizer Pyth erwartet eine Eingabe mit Zeilenumbruch, was möglicherweise falsch läuft.
Isaacg
Eine leere Zeichenfolge zu übergeben ist also nicht einmal möglich?
Optimierer
13

Python 3, 124 123 111 96 Bytes

f=lambda s,n=1:[x for x in[s[i:i+n]for i in range(len(s)+1)]if s.find(x)==s.rfind(x)]or f(s,n+1)

Sucht nach Zeichenfolgen, sodass das erste Vorkommen von links dem ersten Vorkommen von rechts entspricht. Das +1in der rangeist für den leeren String unterzubringen.

Wenn nur Python überlappende Übereinstimmungen .count()gezählt hätte, wäre dies ein gutes Stück kürzer gewesen.

Sp3000
quelle
6

Mathematica, 95 94 79 Bytes

Cases[Tally@StringCases[#,___,Overlaps->All],{s_,1}:>s]~MinimalBy~StringLength&

StringCasesholt mir alle möglichen Teilstrings, filtert die Tallyund Casesdie, die mehrmals vorkommen und MinimalByfindet die, die am kürzesten sind.

Martin Ender
quelle
Gibt es &am Ende des Codes kein Extra ?
David G. Stork
Junge, du bist schnell!
David G. Stork
4

GolfScript, 44 Bytes

:S;-1:x{;S,x):x-),{S>x<}%:^1/{^\/,2=},.!}do`

Übernimmt die Eingabe als Zeichenfolge für stdin und gibt sie in einer Double-Array-Syntax aus: z [["b"] ["c"]].Online-Demo

Präparation

:S;          # Store input in S and pop it
-1:x         # Store -1 in x
{            # do-while loop
  ;          #   Pop x the first time and [] every subsequent time
  S,x):x-),  #   Increment x and build an array [0 1 ... len(S)-x]
  {S>x<}%    #   Map that array to [substr(S,0,x) substr(S,1,x) ...]
  :^         #   Store in ^ (to avoid the token coalescing with the next char)
  1/         #   Split by length 1 to iterate over 1-elt arrays rather than strings
  {^\/,2=},  #   Filter to arrays which occur exactly once as a subarray of ^
  .!         #   Duplicate and test emptiness
}do          # end do-while loop: loop if the filtered array is empty
`            # Stringify for output

Dies ist so angeordnet, dass für die leere Zeichenfolge (die ich als Testfall in die oben verlinkte Online-Demo aufgenommen habe) kein Sonderfall erforderlich ist.

Peter Taylor
quelle
3

CJam, 52 43 40 Bytes

]]q:Q,,{)Q,1$-),f{Q><}:R{R\a/,2=},}%{}=p

Eingabe ist die Zeichenfolge ohne Anführungszeichen

Erklärung :

]]                                       "For empty string input case";
  q:Q                                    "Read the input and store in Q";
     ,,                                  "Take length of input and 0 to length array";
       {                          }%     "Map the above array on this code block";
        )Q                               "Increment the number in the current iteration, L";
         Q,1$                            "Take input's length and copy the above number";
             -)                          "Get upper limit of next loop to get substrings";
               ,f{   }                   "Get 0 to above number array and for each";
                  Q><                    "Get the L length substring at Ith index where";
                                         "I loops from 0 to Q, - L + 1";
                      :R                 "Store this list of substring of length L in R";
                        {R\a/,2=},       "Filter to get unique substrings";
                                    {}=  "Get the first non empty substring array";
                                         "This leaves nothing on stack if all are empty";
                                       p "Print the top stack element. At this point, its";
                                         "Either the first non empty substring array or";
                                         "the ]] i.e. [""] which we added initially";

Beispiel:

asdfdfasddfdfaddsasadsasadsddsddfdsasdf

Ausgabe

["fas" "fad" "add" "fds"]

Probieren Sie es hier online aus

Optimierer
quelle
3

Scala, 120 Bytes

readLine.inits.flatMap(_.tails).toList.groupBy(l=>l).filter(x=>x._2.length<2).map(_._1).groupBy(_.length).minBy(_._1)._2

Ich habe mit 140 angefangen, was zumindest schon in einen Tweet passt.

(                                        // added for comments
 readLine                                // input
.inits.flatMap(_.tails).toList           // get all substrings of that string
.groupBy(l=>l).filter(x=>x._2.length<2)  // remove substrings that occur more than once
.map(_._1).groupBy(_.length)             // take the substring and group by length
.minBy(_._1)._2                          // take the list of shortest substrings
)
Dominik Müller
quelle
Ich wundere mich? Warum funktioniert das nicht nur (_)als Identität statt l=>l?
stolzer Haskeller
Ich frage mich auch. Ist irgendwie list.groupBy(_)das selbe wie x => list.groupBy(x). Ich habe keine Ahnung, warum sie es so implementiert haben.
Dominik Müller
3

JavaScript (ES6), 109 110

Bearbeiten Suche anstelle von indexOf, da die Eingabezeichenfolge alphanumerisch ist. Danke @IsmaelMiguel

Rekursive Funktion, die nach Teilzeichenfolgen sucht, die mit der Länge 1 beginnen und nach oben gehen.

F=(s,n=1,r)=>
s?[...s].map((a,i)=>~s.indexOf(a=s.substr(i,n),s.search(a)+1)?r:r=[...r||[],a])&&r||F(s,n+1):[s]

Ungolfed und erklärte

 F = function(s, n=1) { // start with length 1
   var i, a, p, r;
   if (s == "") // special case for empty input string
     return [s];
   for (i = 0; i < s.length; i++) 
   // for each possibile substring of length n
   // (should stop at s.length-n+1 but going beyond is harmless)
   // Golfed: "[...s].map((a,i)" ... using i, a is overwrittem
   {
     a = s.substr(i, n); // substring at position i
     p = s.search(a); // p is the first position of substring found, can be i or less
     p = s.indexOf(a, p + 1) // p is now the position of a second instance of substring, or -1 if not found
     if (~p) // ~p is 0 if p is -1
     {
       ; // found more than once, do nothing
     }
     else
     {
       r = r || []; // if r is undefined, then it becomes an empty array
       r.push(a); // save substring 
       // Golfed: "r=[...r||[],a]"
     }
   }
   if (r) // if found some substring, saved in r
   {
     return r;
   }
   return F(s, n+1) // recursive retry for a bigger length
 }

Test In FireFox / Firebug - Konsole

;["", "abcaa", "rererere", "asdfasdfd", "ffffhhhhfffffhhhhhfffhhh", 
 "asdfdfasddfdfaddsasadsasadsddsddfdsasdf"]
.forEach(x=>console.log(x,F(x)))

Ausgabe

 [""]
abcaa ["b", "c"]
rererere ["ererer"]
asdfasdfd ["fa", "fd"]
ffffhhhhfffffhhhhhfffhhh ["hffff", "fffff", "hhhhh", "hfffh"]
asdfdfasddfdfaddsasadsasadsddsddfdsasdf ["fas", "fad", "add", "fds"]
edc65
quelle
Verwenden Sie .searchstatt .indexOfund Sie sparen 2 Bytes.
Ismael Miguel
@IsmaelMiguel nein, weil 1) die Suche keinen Offset-Parameter hat 2) die Suche einen regulären Ausdruck erwartet und mit Sonderzeichen wie. * [] Und so weiter
fehlschlägt
1
Aber auf der ersten können Sie es sicher ersetzen (auf Ihrem s.indexOf(a)+1). Mit diesen Zeichen funktioniert es zwar nicht, aber Sie müssen sich keine Sorgen machen! Zitat der OP: " Input: An alphanumeric string s."
Ismael Miguel
@ IsmaelMiguel richtig, danke. Verpasste die 'alphanumerische' Einschränkung
edc65
1
@ IsmaelMiguel Ich habe keinen Weg gefunden ... Ich brauche wahr oder falsch, und jedes Array (auch leer []) ist ein wahrer Wert in Javascript
edc65
3

Java, 168 176 233

Hier ist ein ziemlich einfaches Beispiel für eine verschachtelte Schleife.

void n(String s){for(int l=0,i=0,t=s.length(),q=0;l++<t&q<1;i=0)for(String b;i<=t-l;)if(s.indexOf(b=s.substring(i,i+++l),s.indexOf(b)+1)<0){System.out.println(b);q++;}}

Oder etwas besser lesbar:

void t(String s){
    for(int l=0,i=0,t=s.length(),q=0;l++<t&q<1;i=0)
        for(String b;i<=t-l;)
            if(s.indexOf(b=s.substring(i,i++ +l),s.indexOf(b)+1)<0){
                System.out.println(b);
                q++;
            }
}
Geobits
quelle
Wenn Sie Lesbarkeit wünschen, eine Aufteilung, +++um zu zeigen, ob dies hilfreich ist + ++oder ++ +wäre ... Und wenn Sie ein paar weitere Bytes sparen möchten, gibt es möglicherweise eine Möglichkeit, dies durch Initialisieren q=1, Ersetzen q++durch q=tund Ersetzen l++<t&q<1durch etwas Ähnliches zu erreichen t>l+=q. Möglicherweise müssen ein oder zwei andere Offsets angepasst werden, damit es funktioniert.
Peter Taylor
@ Peter Naja, mit lesbar meinte ich meistens "ich muss nicht horizontal scrollen", aber ich habe das geklärt +++. Ich habe versucht, es zu optimieren (vor allem q, was sich etwas verschwenderisch anfühlt), aber noch nichts Festes gefunden.
Geobits
@ PeterTaylor Aufgrund der Lexing-Regeln von Java, +++löst immer auf ++ +.
FUZxxl
@FUZxxl, ich bezweifle, dass selbst die meisten Java-Benutzer das wissen, und es gibt viele Leute auf dieser Site, die Java nicht kennen.
Peter Taylor
1
Die Verwendung von indexOf mit offset anstelle von lastIndexOf sollte 1 Byte reduzieren (siehe meine Javascript-Antwort).
edc65
3

Haskell, 169, 162, 155 153 151 138 120 115

import Data.List
l=length
q k=filter$(==)k.l
p y=q(minimum.map l$y)$y
f x=p$concat$q 1$group$sort$(tails x>>=inits)

Um es zu benutzen:

f "asdfdfasddfdfaddsasadsasadsddsddfdsasdf"

Welches gibt:

["add","fad","fas","fds"]

Btw. Ich hasse die letzte Zeile meines Codes (Wiederholung von h y). Jemand Hinweise, um es loszuwerden?

RobAu
quelle
1
Wie wäre es mit Ihrer Definition g y=q(minimum.(map l)$y)$y(sind die Klammern map lwirklich erforderlich?) Und dann f=g.concat.q 1.group.sort.concatMap inits.tails?
FUZxxl
1
Verwenden >>=statt concatMap, dh f x=p$concat$q 1$group$sort$(tails x>>=inits)spart 2 Bytes. Warum der Data.OrdImport?
nimi
1
Die Klammern in qsind nicht erforderlich, da Sie schreiben können filter$(==)k.l, ebenso wie das letzte $und die Leerzeichen vor dem ys in p. Sie können die Semikolons auch nach dem Import entfernen ( Data.Ordscheint in der Tat unnötig zu sein).
Zgarb,
Der Leksah-Compiler akzeptiert kein $gefolgt von einem Nicht-Leerzeichen. Es wird einige Bytes rasieren, aber ist es in der Sprachspezifikation?
RobAu
1
GHC wird das akzeptieren.
Zgarb
3

J, 61 58 44 42 40 38 37 Bytes

[:>@{.@(#~#@>)#\<@(~.#~1=#/.~)@(]\)]

Hier ist eine Version aufgeteilt in die einzelnen Komponenten der Lösung:

unqs =. ~. #~ 1 = #/.~               NB. uniques; items that appear exactly once
allsbsq =. #\ <@unqs@(]\) ]        NB. all unique subsequences
shrtsbsq =. [: >@{.@(#~ #@>) allsbsq NB. shortest unique subsequence
  • x #/. yberechnet für jedes einzelne Element, xwie oft es in vorkommt y. Wenn wir dies als verwenden y #/. y, erhalten wir die yAnzahl für jedes einzelne Element . Zum Beispiel a #/. afür a =. 1 2 2 3 4 4Renditen 1 2 1 2.
  • 1 = yprüft, welche Gegenstände ygleich sind 1. Zum Beispiel 1 = a #/. aErträge 1 0 1 0.
  • u~ist das Reflexiv eines monadischen Verbs u. Dies ist u~ ydasselbe wie y u y. So #/.~ yist das gleiche wie #/.~ y. Wenn es auf ein dyadisches Verb angewendet wird, u~ist es das Passiv von u. Das heißt, x u~ yist das gleiche wie y u x. Diese werden an vielen anderen Stellen verwendet, die ich nicht ausdrücklich erwähne.
  • ~. yist die Noppe von y, ein Vektor mit Duplikaten entfernt. Zum Beispiel ~. aErträge1 2 3 4 .
  • x # y( copy ) wählt aus yden Einträgen in den Indizes aus, in denen a xenthalten ist1 .
  • So (1 = y #/. y) # (~. y)entsteht ein Vektor aus diesen Elementen vony denen nur einmal vorkommen. In der stillschweigenden Notation wird dieses Verb als geschrieben ~. #~ 1 = #/.~; Nennen wir diesen Satz unqsfür den Rest der Erklärung.
  • x ]\ yschafft eine xvon 1 + y - xArray aller Infixe des Vektors yder Länge x. Zum Beispiel 3 ]\ 'asdfasdfdErträge

    asd
    sdf
    dfa
    fas
    asd
    sdf
    dfd
    
  • # yist die Bilanz der y, dass die Anzahl der Elemente in ist y.

  • u\ ygilt ufür jedes Präfix von y. Übrigens,#\ y einen Vektor von ganzen Zahlen von 1bis #y.
  • < y setzt y in eine box. Dies ist erforderlich, da Arrays nicht uneinheitlich sein können und wir ein Array mit Suffixen unterschiedlicher Länge berechnen. Ein umrahmtes Array zählt als Skalar.
  • Somit (i. # y) <@:unqs@(]\) yerzeugt einen Vektor von #ygeschachtelten Arrays der Länge k (für alle 0 ≤ k < #y) Infixe von y , die genau einmal vorkommen. Die implizite Form dieses Verbs ist i.@# <@unqs@(]\) ]oder i.@# <@(~. #~ 1 = #/.~)@(]\) ]wenn wir den unqsNamen nicht verwenden . Nennen wir diesen Ausdruck allsbsqfür den Rest dieser Erklärung. Zum Beispiel allsbsq 'asdfasdfd'ergibt:

    ┌┬─┬──┬───┬────┬─────┬──────┬───────┬────────┐
    ││ │fa│dfa│sdfa│asdfa│asdfas│asdfasd│asdfasdf│
    ││ │fd│fas│dfas│sdfas│sdfasd│sdfasdf│sdfasdfd│
    ││ │  │dfd│fasd│dfasd│dfasdf│dfasdfd│        │
    ││ │  │   │sdfd│fasdf│fasdfd│       │        │
    ││ │  │   │    │asdfd│      │       │        │
    └┴─┴──┴───┴────┴─────┴──────┴───────┴────────┘
    
  • (#@> y) # yNimmt aus dem Vektor der Boxed Arrays ydiejenigen, die nicht leer sind.

  • {. yNimmt das erste Element des Vektors y.
  • > yEntfernt die Box von y.
  • Somit > {. (#@> y) # yergibt sich das erste nicht leere Array ohne Box aus dem Vektor der Arrays mit Box y. Dieser Satz ist geschrieben>@{.@(#~ #@>) in stillschweigender Notation geschrieben.
  • Zum Schluss wird [: >@{.@(#~ #@>) allsbsqder vorherige Satz mit zusammengesetzt allsbsq, um eine Lösung für das vorliegende Problem zu finden. Hier ist die vollständige Phrase mit Leerzeichen:

    [: >@{.@(#~ #@>) i.@# <@(~. #~ 1 = #/.~)@(]\) ]
    
FUZxxl
quelle
2

Haskell, 135 Bytes

import Data.List
f ""=[""]
f g=map(snd)$head$groupBy(\a b->fst a==fst b)$sort[(length y,y)|[y]<-group$sort[x|x@(_:_)<-tails g>>=inits]]
nimi
quelle
2

PHP 171 152 134 125

function f($s){while(!$a&&++$i<strlen($s))for($j=0;$b=substr($s,$j++,$i);)strpos($s,$b)==strrpos($s,$b)&&($a[]=$b);return$a;}

http://3v4l.org/RaWTN

Stephen
quelle
Sie müssen nicht explizit definieren $j=0. Du hast es vor dir substr($s,$j++,$i). Ohne zu definieren $j, können Sie dies umschreiben substr($s,0+$j++,$i)und Sie sparen 2 Bytes. Warum das? Nun, das erste Mal $jwird es sein null. Und Sie werden effektiv nullan übergeben substr, was meiner Meinung nach nicht gut funktionieren wird. Mit 0+$j++wird die konvertieren nullzu 0. Wenn Sie sehen, dass es nicht benötigt wird, fahren Sie ohne es fort und entfernen Sie einfach das $j=0Teil.
Ismael Miguel
Versuchte das; Es funktioniert nicht, weil PHP keinen starken Geltungsbereich hat. Es wird daher $jnicht für jede Iteration der while()Schleife gelöscht und neu initialisiert . Während es also beim ersten Mal null ist (und daher 0durch einen $j++Aufruf konvertiert wird ), bleibt es bei zukünftigen Iterationen der äußeren Schleife bei dem Wert, der es zuvor war. Es ist nicht so sehr das Initialisieren als das Zurücksetzen. Vielen Dank für den Vorschlag :-)
Stephen
Hier biete ich Ihnen eine 141 Bytes lange Lösung: function f($s){$l=strlen($s);while(!$a&&++$i<$l)for($j=0;$j<$l;)($b=substr($s,$j++,$i))&(strpos($s,$b)==strrpos($s,$b)&&($a[]=$b));return$a;}Änderungen: Entfernte ALL Ihre ||1, benutzte die bitweise &( AND) anstelle &&an einer Stelle, verschob den $j<$l&&[...]Teil außerhalb der for(spart 2 Bytes) und entfernte einige unnötige Klammern.
Ismael Miguel
1
Ein 134 Bytes langes Geschenk für Sie: Am function f($s){$l=strlen($s);while(!$a&&++$i<$l)for($j=0;$j<$l;)strpos($s,$b=substr($s,$j++,$i))==strrpos($s,$b)&&($a[]=$b);return$a;}vorherigen Code vorgenommene Änderungen: Bewegen Sie den $b=substr($s,$j++,$i)in strpos($s,$b)Making It strpos($s,$b=substr($s,$j++,$i)), entfernen Sie unnötigere Klammern und entfernen Sie das nicht benötigte &.
Ismael Miguel
1
Geschafft, ein wenig mehr zu hacken :-) gibt substr($s,$j++,$i)zurück, ""wenn $jdie Länge der Zeichenfolge erreicht ist, und falsedanach, so dass die Zuweisung auch als Schleifenbedingungsunterbrechung dienen kann. Dann $lbleibt nur noch eine Verwendung übrig, sodass auch diese konsolidiert werden kann.
Stephen
2

Groovy (Java-Regex für Oracle-Implementierung), 124

c={m=it=~/(?=(.*?)(?=(.*))(?<=^(?!.*\1(?!\2$)).*))/;o=m.collect({it[1]});o.findAll({it.size()==o.min({it.size()}).size()});}

Getestet auf Groovy 2.4 + Oracle JRE 1.7. Der reguläre Ausdruck sollte für Java 6 bis Java 8 funktionieren, da der Fehler, durch den der obige Code funktioniert, nicht behoben ist. Nicht sicher für frühere Versionen, da es in Java 5 einen Look-Behind-Fehler gibt, der in Java 6 behoben wurde.

Der reguläre Ausdruck findet an jeder Position in der Eingabezeichenfolge die kürzeste Zeichenfolge, die an keiner anderen Stelle eine doppelte Teilzeichenfolge enthält. Der Code außerhalb kümmert sich um die Filterung.

(?=(.*?)(?=(.*))(?<=^(?!.*\1(?!\2$)).*))
  • Da sich die Saiten überlappen können, umgebe ich das Ganze im Voraus (?=...).
  • (.*?) sucht von der kürzesten Teilzeichenfolge
  • (?=(.*)) erfasst den Rest der Zeichenfolge, um die aktuelle Position zu markieren.
  • (?<=^(?!.*\1(?!\2$)).*)ist eine Emulation von Look-Behind mit variabler Länge, die den Implementierungsfehler ausnutzt, der es ermöglicht (?<=.*), die Längenprüfung zu bestehen.
  • (?!.*\1(?!\2$))Überprüft einfach, ob Sie den gleichen Teilstring an einer anderen Stelle finden. Das(?!\2$) verwirft die ursprüngliche Position, an der die Teilzeichenfolge übereinstimmt.

    Das Limit des äußeren Look-Around-Konstrukts gilt nicht für das verschachtelte Look-Around-Konstrukt. Daher (?!.*\1(?!\2$))prüft die verschachtelte negative Vorausschau tatsächlich die gesamte Zeichenfolge, nicht nur bis zur rechten Begrenzung der Rückschau.

n̴̖̋h̴̖̋ã̷͉h̷̭̿d̷̰̀ĥ̷̳
quelle
2

Rebol, 136 Bytes

f: func[s][repeat n length? b: copy s[unless empty? x: collect[forall s[unless find next find b t: copy/part s n t[keep t]]][return x]]]

Ungolfed:

f: func [s] [
    repeat n length? b: copy s [
        unless empty? x: collect [
            forall s [
                unless find next find b t: copy/part s n t [keep t]
            ]
        ][return x]
    ]
]

Anwendungsbeispiel:

>> f ""       
== none

>> f "abcaa"
== ["b" "c"]

>> f "rererere"
== ["ererer"]

>> f "asdfasdfd"
== ["fa" "fd"]

>> f "ffffhhhhfffffhhhhhfffhhh"
== ["hffff" "fffff" "hhhhh" "hfffh"]

>> f "asdfdfasddfdfaddsasadsasadsddsddfdsasdf"
== ["fas" "fad" "add" "fds"]


NB. Ich nehme an, der Kern des Codes ist, wie das findTeil funktioniert. Hoffentlich wird dies helfen zu erklären ...

>> find "asdfasdfd" "df"
== "dfasdfd"

>> next find "asdfasdfd" "df"
== "fasdfd"

>> find next find "asdfasdfd" "df" "df"
== "dfd"

>> ;; so above shows that "df" is present more than once - so not unique
>> ;; whereas below returns NONE because "fa" found only once - ie. bingo!

>> find next find "asdfasdfd" "fa" "fa"
== none
draegtun
quelle
1

Haskell, 119

f s=[r|n<-[1..length s],l<-[map(take n)$take(length s-n+1)$iterate(drop 1)s],r<-[[j|j<-l,[j]==[r|r<-l,r==j]]],r/=[]]!!0
stolzer haskeller
quelle
Sie können q = lengthirgendwo platzieren und verwenden q, rasiert sich einige Bytes
RobAu
1

Brachylog , 10 Bytes

sᶠ≡ᵍ~gˢlᵍt

Probieren Sie es online!

sᶠ            The list of every substring of the input
  ≡ᵍ          grouped by identity,
    ~gˢ       with length-1 groups converted to their elements and other groups discarded,
       lᵍ     and grouped by their length,
         t    has the output as its last group.

Obwohl nicht automatisch nach dem Wert sortiert wird, nach dem es gruppiert, sondern nach dem ersten Vorkommen jedes Werts, werden die ersten Vorkommen jeder Länge in absteigender Reihenfolge sortiert. Ich bin nicht zu 100% sicher, dass die Eindeutigkeitsfilterung dies nicht durcheinander bringen kann, aber ich habe noch keinen Testfall gefunden, bei dem dies noch fehlschlägt.

Nicht verwandte Zeichenfolge
quelle
1

05AB1E , 10 Bytes

Œʒ¢}é.γg}н

Gibt für eine leere Zeichenfolge nichts aus.

Probieren Sie es online aus oder überprüfen Sie alle Testfälle .

Erläuterung:

Π          # Get all substrings of the (implicit) input-String
 ʒ          # Filter it by:
  ¢         #  Count how many times the current substring occurs in the (implicit) input-String
            #  (only 1 is truthy in 05AB1E, so the filter will leave unique substrings)
          # After the filter: sort the remaining substrings by length
     g}   # Then group them by length as well
         н  # And only leave the first group containing the shortest substrings
            # (which is output implicitly as result)

Dies nutzt den Vorteil, dass 05AB1E nur den 1Wahrheitswert und alles andere den Falschwert hat. Es ist immer gewährleistet, dass die kürzeste eindeutige Teilzeichenfolge genau einmal für alle möglichen Eingabezeichenfolgen auftritt. (Für eine Eingabezeichenfolge, die nur die gleichen Zeichen enthält (dh aaaaa), kommen die Eingabezeichenfolgen selbst als Teilzeichenfolge nur einmal vor. Das Ergebnis ist also ["aaaaa"]. Für eine Eingabezeichenfolge mit sich wiederholendem Muster (dh "abcabc") gibt es immer noch eindeutige Teilzeichenfolgen, die nur einmal vorkommen ( ["abca","abcab","abcabc","bca","bcab","bcabc","ca","cab","cabc"]), so wird dies ergeben ["ca"].)

Kevin Cruijssen
quelle
0

Python 2, 150

import re
a=input()
r=range
l=len(a)
d=0
for i in r(l):
 if d:break
 for j in r(l-i):
  k=a[j:i+j+1]
  if len(re.findall("(?="+k+")",a))<2:d=1;print k
KSFT
quelle
Grauer Bereich, sollte es drucken "", aber Sie drucken nichts.
Jakube
1
@ Jakube "Die genaue Formatierung der Ausgabe ist flexibel"
KSFT
Sie haben aber überhaupt keine Ausgabe.
Jakube
2
@Jakube Die Ausgabe ist der leere String, genau wie er sein soll. Ich habe nur keine Anführungszeichen.
KSFT
1
@Jakube Ich erlaube das, da die leere Zeichenkette sowieso ein Sonderfall ist.
Zgarb