Shell Glob Golf

11

Diese Aufgabe besteht darin, nach der Glob-Erweiterung den kürzesten Pfad zu einer Datei auszugeben.

Was ist Shell Globbing? In den meisten Shells können Sie das *Zeichen in einem Pfad verwenden, um alle Zeichen an der Position darzustellen. Beispiel: Wenn das Verzeichnis fooDateien enthält bar bazund asdf, foo/b*wird es auf erweitert foo/bar foo/baz.

Nehmen wir nun an, das aktuelle Verzeichnis enthält eine aufgerufene Datei ihavealongnameund sonst nichts. Wenn ich auf diese Datei verweisen möchte, gebe ich möglicherweise etwas ein *, das nur diese eine Datei darstellt, anstatt den vollständigen Namen einzugeben.

Wenn das Verzeichnis auch eine Datei namens enthält ialsohavealongname, kann ich das nicht tun *, da es mit beiden Dateien übereinstimmt. Das müsste ich zumindest tun , ih*.

Das *Muster funktioniert auch für übereinstimmende Verzeichnisse über der gesuchten Datei. Wenn es nur zwei Verzeichnisse foound bar, sondern fooenthält nur eine Datei bazund barenthält Datei asdf, kann ich überein foo/bazmit */baz. Oder noch prägnanter */b*. Wenn barleer */*wäre , würde funktionieren.

Ihre Aufgabe: Geben Sie bei einem String-Array von Pfaden, die das "aktuelle Verzeichnis" und einen einzelnen Zielpfad darstellen, den kürzestmöglichen String aus, der nach dem Erweitern von * s nur auf diesen Zielpfad erweitert wird.

Der Zielpfad kann als eigene Zeichenfolge, als Index für das Array von Pfaden, als erstes Element im Array der übergebenen Pfade oder auf eine andere bequeme Weise verwendet werden, die nicht fest codiert ist. Fragen Sie in Kommentaren, wenn Sie sich nicht sicher sind.

Der Zielpfad ist garantiert im "aktuellen Verzeichnis" vorhanden.

Sie können davon ausgehen, dass alle Pfade nur alphanumerische ASCII (und /s) enthalten. Sie können als Eingabepfade Roots (beginnend mit /) oder relativ (nicht beginnend mit /) verwenden.

Wenn es mehrere gleich kurze Möglichkeiten gibt, geben Sie eine oder alle zurück.

Das ist , die wenigsten Bytes gewinnen!

Testfälle dank Kevin Cruijssen .

Pavel
quelle
4
So können wir annehmen , Dateinamen enthalten keine Leerzeichen, Zeilenumbrüche, Schrägstriche, *, ?, [ etc? Es wäre vielleicht am einfachsten, wenn Sie nur
Ton Hospel
3
Der eigentliche Festplatten-E / A-Teil wird in vielen Sprachen langweilig. zB in Perl würde ich einfach den Dateinamen nehmen und alle Pfadkomponenten durch ersetzen *und Perl ausführen glob, um alle Dateinamen zu erhalten, die relevant sein können (zB foo/bar/bazwird */*/*). Danach wird es eine Herausforderung für die Zeichenfolgenverarbeitung. Und diese Herausforderung ist schon schwer genug. Ich denke, diese Herausforderung wäre sauberer, wenn "bei einer Liste alphanumerischer (und /) relativer Pfade der kürzeste Glob gefunden wird, der nur diesem vorhandenen
Zielpfad entspricht
1
@ KevinCruijssen Sicher, es ist eine lustige Herausforderung und sollte meistens die reinen Golfsprachen fernhalten. Ich denke, Sie brauchen ein echtes Programm (es sei denn, Sie generieren alle möglichen Saiten, bis Sie die kürzeste treffen, die funktioniert, die langweilig ist und exponentiell explodiert). Ihre aktuellen Beispiele Fangen Sie kaum an, die Fälle abzudecken, die Sie behandeln müssen. Hier ist anthere Fall: Verwendung a*fwählen azzfaus azzf, azzg, bzzf. Verlängern Sie nach Belieben bis a*b*cetc ..
Ton Hospel
2
@ TonHospel Ich bin überzeugt. Sie nehmen jetzt eine Reihe von Pfaden als Eingabe.
Pavel
4
@WeijunZhou Ich habe meine Meinung über Eingabe geändert. Sie können jetzt eine Reihe von Pfaden nehmen.
Pavel

Antworten:

8

Perl 5 , 136 107 102 Bytes

Beinhaltet +2fürn0

Geben Sie eine Liste der Dateien auf STDIN. Die erste wird als Zieldatei angenommen

perl -n0E '@a="";for$a(@a){s%%s/(?=$a
)/;/g;$$_//=push@a,map$_.$a,/./g,"\\w*";/^;/>/
;/&&1/!say$a=~s/\\w//gr%e}'
foo/barber/test
foo/barber/testing
foo/barber/coding
foo/test
foo/bar/test
^D

Nur der Code, ohne die Zeilenumbrüche wörtlich zu machen:

@a="";for$a(@a){s%%s/(?=$a\n)/;/g;$$_//=push@a,map$_.$a,/./g,"\\w*";/^;/>/\n;/&&1/!say$a=~s/\\w//gr%e}

Abstürze absichtlich nach dem Drucken der Lösung.

Scheint immer noch zu lang (die Verwendung von $aund 1/0ist sehr umständlich), aber es ist ein Anfang und sollte einigermaßen effizient sein.

Probieren Sie es online aus!

Wie es funktioniert

Das Programm erstellt Kandidaten-Globs, indem es sie von hinten nach vorne wächst, beginnend mit der leeren Zeichenfolge. Er tut dies in einer Breiten Weise so erste Klackse der Länge 0 ist erprobt (nur ``), dann Länge 1 (wie t, i, *), nächste Länge 2 (wie fb, i*, *g, **), nächste Länge 3 und so weiter , bis ein Es wurde ein Glob gefunden, der nur dem ersten Pfad entspricht. Dies ist dann der kürzeste Glob, der das Problem löst (andere mit derselben Länge können existieren).

Die Globs der Länge n+1werden aus den Globs der Länge generiert, nindem jedes Zeichen aus der Liste der Pfade und auch *vor jedem Glob der Länge vorangestellt wird n. So zB Länge 3 glob *i*wird dazu beitragen , Länge 4 Klackse f*i*, o*i*, o*i*, /*i*, b*i*... s*i*, t*i*und schließlich **i*. Beachten Sie, dass jedem Zeichen aus der Liste der Eingabepfade vorangestellt wird, auch wenn es mehrmals vorkommt oder überhaupt keinen Sinn ergibt, da es zu etwas führt, das niemals übereinstimmen kann.

Dies naiv zu tun würde zu einer kombinatorischen Explosion führen. Aus diesem Grund wird jeder Kandidaten-Glob dahingehend bewertet, wie nützlich er ist, indem ermittelt wird, an welchen Punkten in den Pfaden er übereinstimmen könnte, wenn der Glob am Ende eines vollständigen Glob verwendet würde. Dazu füge ich ;an jeder Stelle, an der eine Übereinstimmung möglich ist, ein ein. Zum Beispiel für den Glob t*bekomme ich den String:

foo/barber/;tes;t
foo/barber/;tes;ting
foo/barber/coding
foo/;tes;t
foo/bar/;tes;t

Dies repräsentiert die "Unterscheidungskraft" des Globus. Jeder Globus, der genau die gleiche Unterscheidungskraft hat, ist gleich gut. Wenn Sie sie am Ende eines vollständigen Globus durch andere ersetzen, stimmen sie alle genau mit denselben Pfaden überein. Sie können also genauso gut die kürzeste verwenden.

nWenn ich also die Länge der Globs betrachte, schaue ich zuerst auf ihre Unterscheidungskraft. Wenn es gesehen wurde, bevor es einen anderen Globus mit einer Länge noder kürzer gab, der bereits berücksichtigt und erweitert wurde, ist dieser Globus sinnlos und wird beschnitten. Dies wird zum Beispiel Kandidaten loswerden, **i*da die gleiche Unterscheidungskraft bereits als gesehen wurde *i*. Es beschneidet auch unmögliche Kandidaten wie, f*i*da die Unterscheidungszeichenfolge keine hat;und sei einfach die ursprüngliche Liste der Pfade. Nur der allererste unmögliche Glob wird akzeptiert, alle anderen haben die gleiche Unterscheidungskraft und werden beschnitten. Und selbst das erste wird nicht wirklich erweitert, da alle Erweiterungen immer noch unmöglich sind und beschnitten werden, wenn sie berücksichtigt werden. Wird gleichermaßen in*von i*etc. beschnitten .

Das Obige führt zu einem sehr aggressiven Beschneiden und das Programm ist daher in der Lage, komplexe Fälle in sehr kurzer Zeit zu bearbeiten. Eine große Ineffizienz besteht jedoch darin, dass den Kandidaten-Globs alle möglichen Zeichen vorangestellt werden, nicht nur diejenigen, die sich unmittelbar vor einem ;Teil der Unterscheidungszeichenfolge im Zielpfad befinden. Alle hinzugefügten Zeichen, die sich nicht vor einem ;befinden, sind kein Problem, da sie zu einem unmöglichen Glob führen, der bei Betrachtung beschnitten wird, die Zeichen jedoch noch kurz zuvor ;auf den anderen Pfaden belassen. Am Ende erstellt das Programm also auch Globs, die mit jeder Kombination der angegebenen Pfade übereinstimmen können. Es hat keine Ahnung, dass es sich auf den ersten Weg konzentrieren sollte.

Betrachten Sie nun eine Lösung für das Problem. Im gegebenen Beispiel könnte das sein */*er/t. Dies ergibt die folgende Unterscheidungszeichenfolge:

;f;o;o;/barber/test
foo/barber/testing
foo/barber/coding
foo/test
foo/bar/test

Ich erkenne eine Lösung, indem ich ein ;an der ersten Position habe (damit es mit dem ersten Pfad übereinstimmt) und kein ;am Anfang eines anderen Pfades (damit die anderen nicht übereinstimmen).

Mit dem erklärten Algorithmus komme ich nun zum eigentlichen Programm:

Die Kandidaten-Globs befinden sich in einem Array, @adas ich mit einer Variablen durchlaufe , $adie den aktuell betrachteten Glob enthält. Anstelle *im Glob werde ich jedoch verwenden, \w*so $aist eigentlich ein Regex anstelle eines Glob. Ich werde eine Verrücktheit der Perl-for-Schleife missbrauchen, bei der Sie Elemente an das Array anhängen können, das während der Schleife geloopt wird, und diese neuen Elemente in der Schleife aufgenommen werden. Da sich beim Generieren der Längen- n+1Globs bereits alle Längen- nGlobs im Array befinden, ist @adies die Breite zuerst.

Aufgrund der -n0Option (implizite Schleife über die gesamte Eingabe) wird die Liste der Pfade $_als eine große Zeichenfolge angezeigt, wobei jeder Pfad mit einer neuen Zeile abgeschlossen wird

@a="";                    Start everything with the length 0 glob
for$a(@a){    }           Loop over candidates in a breadth first way

Im Inneren { }haben wir:

s/(?=$a\n)/;/g            Loop over the paths and insert a ; at every
                          position that the suffix glob can match by
                          looking ahead and checking that the regex
                          under consideration can match up to the end of
                          the path we are in. The distinguishing sting is
                          now in `$_`.

Ups, ich habe es gerade zerstört $_und ich werde es für die nächste Schleife brauchen. Wickeln Sie also den eigentlichen Arbeitscode ein

s%%  ...code.. %e

Dies entspricht der leeren Zeichenfolge am Anfang von $_und ermöglicht es Ihnen, Code auszuführen, um zu bestimmen, durch was er ersetzt wird. Wenn ich sicher gehe, dass dieser Code als leere Zeichenfolge ausgewertet wird, $_bleibt er am Ende unverändert, auch wenn ich ihn $_während ändere code.

Zurück zu kurz nachdem ich durch $_die unterscheidende Zeichenfolge ersetzt wurde:

$$_//= expression

Das ist wie:

$seen{$_} //= expression

//in perl ist 'defined or. Es ist wie ein Kurzschluss, orbei dem das zweite Argument nur ausgewertet wird, wenn das erste Argument vorliegt undef. Und es kann wie +=in einigen anderen Sprachen mit einer Aufgabe kombiniert werden . Also , wenn sie Schlüssel $_in Hash %seenist undef(was ist das, was man bekommt , wenn ein nicht existierendes Element zugreifen) nur dann Ausdruck ausführen und als Wert Schlüssel zuweisen $_. Wenn ich also sicher expressiongehe , dass nicht zurückgegeben wird undef, bedeutet dies im Grunde "Ausdruck genau dann auswerten, wenn dies das erste Mal ist, dass wir diese bestimmte Unterscheidungszeichenfolge sehen". Und weil $_garantiert ein enthält \n, ist es in der Tat sicher, den globalen Perl-Hash zu missbrauchen, um die unterscheidenden Zeichenfolgen zu speichern, also $$_statt$seen{$_}

Für die expressionich benutze:

push@a,map$_.$a,/./g,"\\w*"

Grundsätzlich "Für jedes Zeichen (außer Zeilenumbruch) in der Unterscheidungszeichenfolge und stellen *Sie es auch dem aktuellen Glob voran und verschieben Sie dieses auf das Array der Kandidaten-Globs". Execpt Ich verwende \w*für *, um einen gültigen regulären Ausdruck zu erhalten (ich könnte ''anstelle ""eines Backslashs verwenden, aber dann konnte ich meinen Code nicht über die Befehlszeile ausführen). Beachten Sie, dass dies auch die aufnimmt ;und sie zu den Kandidaten-Globs hinzufügt, aber wenn Sie sie später zu den wiederhergestellten testen, die $_keine haben ;, wird dies wieder ein unmöglicher Glob sein und beschnitten werden.

/^;/>/\n;/ &&      If the distinguishing string corresponds to a solution

say$a=~s/\\w//gr   Then replace all \w* back to * and print the solution

1/!                Say returns 1 so this becomes a division by 0.
                   The program exits by crashing after solving it

Beachten Sie, dass /^;/>/\n;/der Wert der leeren Zeichenfolge entspricht, falls noch keine Lösung gefunden wurde. Dies fungiert also als leere Ersatzzeichenfolge und $_wird wiederhergestellt

Ton Hospel
quelle
Ich erhalte eine Fehlermeldung bei TIO, die jedoch lokal funktioniert. Weißt du warum das so ist?
Pavel
1
@Pavel -EAktiviert die neueste Sprachstufe. Sie benötigen mindestens Perl, 5.10.0um verwenden zu können say. Also use 5.10.0;in den Header-Bereich setzen und es wird funktionieren. Optionen zum Festlegen der Sprachstufe gelten sowieso als kostenlos, auch wenn Sie dies nicht mit verwenden können -E. Tatsächlich zählen heutzutage alle Optionen als kostenlos (also muss ich nicht einmal zählen n0), aber ich halte das für zu nachsichtig für Perl
Ton Hospel
2
Das Beenden mit einem Fehler ist in Ordnung , Ihre 1/Lösung ist also gültig! Ich muss mich auch daran erinnern ...
Dom Hastings
7

Java 10, 854 824 796 738 728 703 688 655 652 647 624 Bytes

import java.util.*;a->f->{var L=new Stack();List<String>s;int i=999,j,k;for(var t:f.split("/")){s=new java.util.concurrent.CopyOnWriteArrayList();s.add(t);for(k=1;k>0;){k=0;for(var x:s)for(j=0;j<x.length();)if(!s.contains(f=x.substring(0,j)+"~"+x.substring(++j))){s.add(f);k=1;}}for(var x:s)s.add(x.replaceAll("~+","\\*"));L.add(s);}p(L,s=new Stack(),0,f="");for(var y:s){k=0;for(var x:a)if(x.matches(y.replace("*",".*"))&x.split("/").length==y.split("/").length)k++;if(k==1&(j=y.length())<i){f=y;i=j;}}return f;};void p(List L,List r,int d,String c){if(d==L.size())r.add(c);else for(var o:(List)L.get(d))p(L,r,d+1,c+"/"+o);}

Was für ein Durcheinander. Dies ist sicherlich keine einfache Herausforderung in Java. Kann definitiv um ein paar hundert Bytes gespielt werden, aber ich bin nur froh, dass es jetzt endlich funktioniert. Erzählte dir. :)
-5 Bytes dank @ceilingcat .
-23 Bytes Umschalten von Java 8 auf Java 10

Eingabe als String-Array von Dateipfaden (mit Verzeichnissen als getrennten Elementen und allen Elementen, die einen führenden enthalten /) und als String mit Eingabedateipfad zum Abtasten.

Erläuterung:

Probieren Sie es online aus. (Die Testfälle mit ialsohavealongname/ ihavealongnameaswellsind leicht in der Länge reduziert und s.add(x.replaceAll("~+","\\*"));wurden durch ersetzt {s.remove(x);s.add(x.replaceAll("~+","\\*"));}, um in 5-10 Sekunden an TIO zu arbeiten, anstatt nach mehr als 60 Sekunden eine Zeitüberschreitung zu verursachen.)

import java.util.*;   // Required import for List and Stack

// Method with String-array and String parameters and String return-type
a->f->{
  var L=new Stack();  //  Create a List of Lists
  List<String>s;      //  List of Strings (uninitialized)
  int i=999,j,k;      //  Three integers (`i` starting at 999,
                      //   because 260 is the maximum file-path length in Windows)
  for(var t:f.split("/")){
                      //  Loop over the input file-path split by "/":
    s=new java.util.concurrent.CopyOnWriteArrayList();
                      //  Create a List (which we can modify while iterating it)
    s.add(t);         //  Add the input to this List
    for(k=1;k>0;){    //  Loop as long as there are new items added to the List
      k=0;            //   Reset the newAdded-flag to false
      for(var x:s)    //   And inner loop over the List
        for(j=0;j<t.length();)
                      //    Inner loop `j` in range [0,length-of-item):
          if(!s.contains(f=x.substring(0,j)+"~"+x.substring(++j))){
                      //     Replace the character at index `j` with a '~'
                      //     And if it's a new item:
            s.add(f); //      Add it to the List
            k=1;}}    //      And set the newAdded-flag to true
    for(var x:s)      //  Loop over the List again
      s.add(x.replaceAll("~+","\\*")));
                      //   And replace all 1 or more '~' with a single asterisk
                      //   (NOTE: To reduce bytes it doesn't remove the existing items)
    L.add(s);}        //   Add this List to the List of Lists
  p(L,s=new Stack(),0,"");
                      //  Generate all permutations of the groppings
                      //  (List `s` now contains all groppings of the given file-path)
  for(var y:s){       //  Loop over the groppings in the String-List:
    k=0;              //   Reset integer `k` to 0
    for(var x:a)      //   Inner loop over the input file-paths:
      if(x.matches(y.replace("*",".*"))
                      //    If the current file-path matches the current gropping
         x.split("/").length==y.split("/").length)
                      //    and the amount of slashes are the same:
         k++;         //     Increase integer `k` by 1
    if(k==1           //   If only one of the file-paths matched,
       &(j=y.length())<i){
                      //   and the length is shorter than `i`:
      f=y;            //    Replace the result with this gropping file-path
      i=j;}}          //    And also replace `i` with this shorter `j`
  return f;}          //  Finally return this shortest gropping file-path

// Separated method to generate gropping file-path permutations given a List of Lists
void p(List L,List r,int d,String c){
  if(d==L.size())     //  If we've reached the final depth
    r.add(c);         //   Add the current gropping-file path to the result-List
  else                //  Else:
    for(var o:(List)L.get(d))
                      //   Loop over the List of the current depth:
      p(L,r,d+1,      //    Recursive call with depth+1,
        c+"/"+o);}    //    and current + "/" + item of loop

Zusätzliche allgemeine Erklärung:

Beispiel: Nehmen wir /foo, /foo/bar, /foo/barber, /foo/bar/test, /foo/barber/test, /foo/barber/testing, /foo/barber/coding, /foo/testals gegebene Dateipfade und foo/bar/testals Eingabedateipfad zum Abtasten.

1) Ich /teile zunächst die Dateipfadeingabe durch auf und generiere alle Dateifänge dieser getrennten Wörter:

foo: [foo, *oo, f*o, fo*, *o, *o*, f*, *]
bar: [bar, *ar, b*r, ba*, *r, *a*, b*, *]
test: [test, *est, t*st, te*t, tes*, *st, *e*t, *es*, t*t, t*s*, te*, *t, *s*, *e*, t*, *]

2) Ich generiere dann alle Permutationen mit diesen Wörtern in der gleichen Reihenfolge (erneutes Anwenden der /dazwischen und vorne):

[/foo/bar/test, /foo/bar/*est, /foo/bar/t*st, /foo/bar/te*t, /foo/bar/tes*, /foo/bar/*st, /foo/bar/*e*t, /foo/bar/*es*, /foo/bar/t*t, /foo/bar/t*s*, /foo/bar/te*, /foo/bar/*t, /foo/bar/*s*, /foo/bar/*e*, /foo/bar/t*, /foo/bar/*, /foo/*ar/test, /foo/*ar/*est, /foo/*ar/t*st, /foo/*ar/te*t, /foo/*ar/tes*, /foo/*ar/*st, /foo/*ar/*e*t, /foo/*ar/*es*, /foo/*ar/t*t, /foo/*ar/t*s*, /foo/*ar/te*, /foo/*ar/*t, /foo/*ar/*s*, /foo/*ar/*e*, /foo/*ar/t*, /foo/*ar/*, /foo/b*r/test, /foo/b*r/*est, /foo/b*r/t*st, /foo/b*r/te*t, /foo/b*r/tes*, /foo/b*r/*st, /foo/b*r/*e*t, /foo/b*r/*es*, /foo/b*r/t*t, /foo/b*r/t*s*, /foo/b*r/te*, /foo/b*r/*t, /foo/b*r/*s*, /foo/b*r/*e*, /foo/b*r/t*, /foo/b*r/*, /foo/ba*/test, /foo/ba*/*est, /foo/ba*/t*st, /foo/ba*/te*t, /foo/ba*/tes*, /foo/ba*/*st, /foo/ba*/*e*t, /foo/ba*/*es*, /foo/ba*/t*t, /foo/ba*/t*s*, /foo/ba*/te*, /foo/ba*/*t, /foo/ba*/*s*, /foo/ba*/*e*, /foo/ba*/t*, /foo/ba*/*, /foo/*r/test, /foo/*r/*est, /foo/*r/t*st, /foo/*r/te*t, /foo/*r/tes*, /foo/*r/*st, /foo/*r/*e*t, /foo/*r/*es*, /foo/*r/t*t, /foo/*r/t*s*, /foo/*r/te*, /foo/*r/*t, /foo/*r/*s*, /foo/*r/*e*, /foo/*r/t*, /foo/*r/*, /foo/*a*/test, /foo/*a*/*est, /foo/*a*/t*st, /foo/*a*/te*t, /foo/*a*/tes*, /foo/*a*/*st, /foo/*a*/*e*t, /foo/*a*/*es*, /foo/*a*/t*t, /foo/*a*/t*s*, /foo/*a*/te*, /foo/*a*/*t, /foo/*a*/*s*, /foo/*a*/*e*, /foo/*a*/t*, /foo/*a*/*, /foo/b*/test, /foo/b*/*est, /foo/b*/t*st, /foo/b*/te*t, /foo/b*/tes*, /foo/b*/*st, /foo/b*/*e*t, /foo/b*/*es*, /foo/b*/t*t, /foo/b*/t*s*, /foo/b*/te*, /foo/b*/*t, /foo/b*/*s*, /foo/b*/*e*, /foo/b*/t*, /foo/b*/*, /foo/*/test, /foo/*/*est, /foo/*/t*st, /foo/*/te*t, /foo/*/tes*, /foo/*/*st, /foo/*/*e*t, /foo/*/*es*, /foo/*/t*t, /foo/*/t*s*, /foo/*/te*, /foo/*/*t, /foo/*/*s*, /foo/*/*e*, /foo/*/t*, /foo/*/*, /*oo/bar/test, /*oo/bar/*est, /*oo/bar/t*st, /*oo/bar/te*t, /*oo/bar/tes*, /*oo/bar/*st, /*oo/bar/*e*t, /*oo/bar/*es*, /*oo/bar/t*t, /*oo/bar/t*s*, /*oo/bar/te*, /*oo/bar/*t, /*oo/bar/*s*, /*oo/bar/*e*, /*oo/bar/t*, /*oo/bar/*, /*oo/*ar/test, /*oo/*ar/*est, /*oo/*ar/t*st, /*oo/*ar/te*t, /*oo/*ar/tes*, /*oo/*ar/*st, /*oo/*ar/*e*t, /*oo/*ar/*es*, /*oo/*ar/t*t, /*oo/*ar/t*s*, /*oo/*ar/te*, /*oo/*ar/*t, /*oo/*ar/*s*, /*oo/*ar/*e*, /*oo/*ar/t*, /*oo/*ar/*, /*oo/b*r/test, /*oo/b*r/*est, /*oo/b*r/t*st, /*oo/b*r/te*t, /*oo/b*r/tes*, /*oo/b*r/*st, /*oo/b*r/*e*t, /*oo/b*r/*es*, /*oo/b*r/t*t, /*oo/b*r/t*s*, /*oo/b*r/te*, /*oo/b*r/*t, /*oo/b*r/*s*, /*oo/b*r/*e*, /*oo/b*r/t*, /*oo/b*r/*, /*oo/ba*/test, /*oo/ba*/*est, /*oo/ba*/t*st, /*oo/ba*/te*t, /*oo/ba*/tes*, /*oo/ba*/*st, /*oo/ba*/*e*t, /*oo/ba*/*es*, /*oo/ba*/t*t, /*oo/ba*/t*s*, /*oo/ba*/te*, /*oo/ba*/*t, /*oo/ba*/*s*, /*oo/ba*/*e*, /*oo/ba*/t*, /*oo/ba*/*, /*oo/*r/test, /*oo/*r/*est, /*oo/*r/t*st, /*oo/*r/te*t, /*oo/*r/tes*, /*oo/*r/*st, /*oo/*r/*e*t, /*oo/*r/*es*, /*oo/*r/t*t, /*oo/*r/t*s*, /*oo/*r/te*, /*oo/*r/*t, /*oo/*r/*s*, /*oo/*r/*e*, /*oo/*r/t*, /*oo/*r/*, /*oo/*a*/test, /*oo/*a*/*est, /*oo/*a*/t*st, /*oo/*a*/te*t, /*oo/*a*/tes*, /*oo/*a*/*st, /*oo/*a*/*e*t, /*oo/*a*/*es*, /*oo/*a*/t*t, /*oo/*a*/t*s*, /*oo/*a*/te*, /*oo/*a*/*t, /*oo/*a*/*s*, /*oo/*a*/*e*, /*oo/*a*/t*, /*oo/*a*/*, /*oo/b*/test, /*oo/b*/*est, /*oo/b*/t*st, /*oo/b*/te*t, /*oo/b*/tes*, /*oo/b*/*st, /*oo/b*/*e*t, /*oo/b*/*es*, /*oo/b*/t*t, /*oo/b*/t*s*, /*oo/b*/te*, /*oo/b*/*t, /*oo/b*/*s*, /*oo/b*/*e*, /*oo/b*/t*, /*oo/b*/*, /*oo/*/test, /*oo/*/*est, /*oo/*/t*st, /*oo/*/te*t, /*oo/*/tes*, /*oo/*/*st, /*oo/*/*e*t, /*oo/*/*es*, /*oo/*/t*t, /*oo/*/t*s*, /*oo/*/te*, /*oo/*/*t, /*oo/*/*s*, /*oo/*/*e*, /*oo/*/t*, /*oo/*/*, /f*o/bar/test, /f*o/bar/*est, /f*o/bar/t*st, /f*o/bar/te*t, /f*o/bar/tes*, /f*o/bar/*st, /f*o/bar/*e*t, /f*o/bar/*es*, /f*o/bar/t*t, /f*o/bar/t*s*, /f*o/bar/te*, /f*o/bar/*t, /f*o/bar/*s*, /f*o/bar/*e*, /f*o/bar/t*, /f*o/bar/*, /f*o/*ar/test, /f*o/*ar/*est, /f*o/*ar/t*st, /f*o/*ar/te*t, /f*o/*ar/tes*, /f*o/*ar/*st, /f*o/*ar/*e*t, /f*o/*ar/*es*, /f*o/*ar/t*t, /f*o/*ar/t*s*, /f*o/*ar/te*, /f*o/*ar/*t, /f*o/*ar/*s*, /f*o/*ar/*e*, /f*o/*ar/t*, /f*o/*ar/*, /f*o/b*r/test, /f*o/b*r/*est, /f*o/b*r/t*st, /f*o/b*r/te*t, /f*o/b*r/tes*, /f*o/b*r/*st, /f*o/b*r/*e*t, /f*o/b*r/*es*, /f*o/b*r/t*t, /f*o/b*r/t*s*, /f*o/b*r/te*, /f*o/b*r/*t, /f*o/b*r/*s*, /f*o/b*r/*e*, /f*o/b*r/t*, /f*o/b*r/*, /f*o/ba*/test, /f*o/ba*/*est, /f*o/ba*/t*st, /f*o/ba*/te*t, /f*o/ba*/tes*, /f*o/ba*/*st, /f*o/ba*/*e*t, /f*o/ba*/*es*, /f*o/ba*/t*t, /f*o/ba*/t*s*, /f*o/ba*/te*, /f*o/ba*/*t, /f*o/ba*/*s*, /f*o/ba*/*e*, /f*o/ba*/t*, /f*o/ba*/*, /f*o/*r/test, /f*o/*r/*est, /f*o/*r/t*st, /f*o/*r/te*t, /f*o/*r/tes*, /f*o/*r/*st, /f*o/*r/*e*t, /f*o/*r/*es*, /f*o/*r/t*t, /f*o/*r/t*s*, /f*o/*r/te*, /f*o/*r/*t, /f*o/*r/*s*, /f*o/*r/*e*, /f*o/*r/t*, /f*o/*r/*, /f*o/*a*/test, /f*o/*a*/*est, /f*o/*a*/t*st, /f*o/*a*/te*t, /f*o/*a*/tes*, /f*o/*a*/*st, /f*o/*a*/*e*t, /f*o/*a*/*es*, /f*o/*a*/t*t, /f*o/*a*/t*s*, /f*o/*a*/te*, /f*o/*a*/*t, /f*o/*a*/*s*, /f*o/*a*/*e*, /f*o/*a*/t*, /f*o/*a*/*, /f*o/b*/test, /f*o/b*/*est, /f*o/b*/t*st, /f*o/b*/te*t, /f*o/b*/tes*, /f*o/b*/*st, /f*o/b*/*e*t, /f*o/b*/*es*, /f*o/b*/t*t, /f*o/b*/t*s*, /f*o/b*/te*, /f*o/b*/*t, /f*o/b*/*s*, /f*o/b*/*e*, /f*o/b*/t*, /f*o/b*/*, /f*o/*/test, /f*o/*/*est, /f*o/*/t*st, /f*o/*/te*t, /f*o/*/tes*, /f*o/*/*st, /f*o/*/*e*t, /f*o/*/*es*, /f*o/*/t*t, /f*o/*/t*s*, /f*o/*/te*, /f*o/*/*t, /f*o/*/*s*, /f*o/*/*e*, /f*o/*/t*, /f*o/*/*, /fo*/bar/test, /fo*/bar/*est, /fo*/bar/t*st, /fo*/bar/te*t, /fo*/bar/tes*, /fo*/bar/*st, /fo*/bar/*e*t, /fo*/bar/*es*, /fo*/bar/t*t, /fo*/bar/t*s*, /fo*/bar/te*, /fo*/bar/*t, /fo*/bar/*s*, /fo*/bar/*e*, /fo*/bar/t*, /fo*/bar/*, /fo*/*ar/test, /fo*/*ar/*est, /fo*/*ar/t*st, /fo*/*ar/te*t, /fo*/*ar/tes*, /fo*/*ar/*st, /fo*/*ar/*e*t, /fo*/*ar/*es*, /fo*/*ar/t*t, /fo*/*ar/t*s*, /fo*/*ar/te*, /fo*/*ar/*t, /fo*/*ar/*s*, /fo*/*ar/*e*, /fo*/*ar/t*, /fo*/*ar/*, /fo*/b*r/test, /fo*/b*r/*est, /fo*/b*r/t*st, /fo*/b*r/te*t, /fo*/b*r/tes*, /fo*/b*r/*st, /fo*/b*r/*e*t, /fo*/b*r/*es*, /fo*/b*r/t*t, /fo*/b*r/t*s*, /fo*/b*r/te*, /fo*/b*r/*t, /fo*/b*r/*s*, /fo*/b*r/*e*, /fo*/b*r/t*, /fo*/b*r/*, /fo*/ba*/test, /fo*/ba*/*est, /fo*/ba*/t*st, /fo*/ba*/te*t, /fo*/ba*/tes*, /fo*/ba*/*st, /fo*/ba*/*e*t, /fo*/ba*/*es*, /fo*/ba*/t*t, /fo*/ba*/t*s*, /fo*/ba*/te*, /fo*/ba*/*t, /fo*/ba*/*s*, /fo*/ba*/*e*, /fo*/ba*/t*, /fo*/ba*/*, /fo*/*r/test, /fo*/*r/*est, /fo*/*r/t*st, /fo*/*r/te*t, /fo*/*r/tes*, /fo*/*r/*st, /fo*/*r/*e*t, /fo*/*r/*es*, /fo*/*r/t*t, /fo*/*r/t*s*, /fo*/*r/te*, /fo*/*r/*t, /fo*/*r/*s*, /fo*/*r/*e*, /fo*/*r/t*, /fo*/*r/*, /fo*/*a*/test, /fo*/*a*/*est, /fo*/*a*/t*st, /fo*/*a*/te*t, /fo*/*a*/tes*, /fo*/*a*/*st, /fo*/*a*/*e*t, /fo*/*a*/*es*, /fo*/*a*/t*t, /fo*/*a*/t*s*, /fo*/*a*/te*, /fo*/*a*/*t, /fo*/*a*/*s*, /fo*/*a*/*e*, /fo*/*a*/t*, /fo*/*a*/*, /fo*/b*/test, /fo*/b*/*est, /fo*/b*/t*st, /fo*/b*/te*t, /fo*/b*/tes*, /fo*/b*/*st, /fo*/b*/*e*t, /fo*/b*/*es*, /fo*/b*/t*t, /fo*/b*/t*s*, /fo*/b*/te*, /fo*/b*/*t, /fo*/b*/*s*, /fo*/b*/*e*, /fo*/b*/t*, /fo*/b*/*, /fo*/*/test, /fo*/*/*est, /fo*/*/t*st, /fo*/*/te*t, /fo*/*/tes*, /fo*/*/*st, /fo*/*/*e*t, /fo*/*/*es*, /fo*/*/t*t, /fo*/*/t*s*, /fo*/*/te*, /fo*/*/*t, /fo*/*/*s*, /fo*/*/*e*, /fo*/*/t*, /fo*/*/*, /*o/bar/test, /*o/bar/*est, /*o/bar/t*st, /*o/bar/te*t, /*o/bar/tes*, /*o/bar/*st, /*o/bar/*e*t, /*o/bar/*es*, /*o/bar/t*t, /*o/bar/t*s*, /*o/bar/te*, /*o/bar/*t, /*o/bar/*s*, /*o/bar/*e*, /*o/bar/t*, /*o/bar/*, /*o/*ar/test, /*o/*ar/*est, /*o/*ar/t*st, /*o/*ar/te*t, /*o/*ar/tes*, /*o/*ar/*st, /*o/*ar/*e*t, /*o/*ar/*es*, /*o/*ar/t*t, /*o/*ar/t*s*, /*o/*ar/te*, /*o/*ar/*t, /*o/*ar/*s*, /*o/*ar/*e*, /*o/*ar/t*, /*o/*ar/*, /*o/b*r/test, /*o/b*r/*est, /*o/b*r/t*st, /*o/b*r/te*t, /*o/b*r/tes*, /*o/b*r/*st, /*o/b*r/*e*t, /*o/b*r/*es*, /*o/b*r/t*t, /*o/b*r/t*s*, /*o/b*r/te*, /*o/b*r/*t, /*o/b*r/*s*, /*o/b*r/*e*, /*o/b*r/t*, /*o/b*r/*, /*o/ba*/test, /*o/ba*/*est, /*o/ba*/t*st, /*o/ba*/te*t, /*o/ba*/tes*, /*o/ba*/*st, /*o/ba*/*e*t, /*o/ba*/*es*, /*o/ba*/t*t, /*o/ba*/t*s*, /*o/ba*/te*, /*o/ba*/*t, /*o/ba*/*s*, /*o/ba*/*e*, /*o/ba*/t*, /*o/ba*/*, /*o/*r/test, /*o/*r/*est, /*o/*r/t*st, /*o/*r/te*t, /*o/*r/tes*, /*o/*r/*st, /*o/*r/*e*t, /*o/*r/*es*, /*o/*r/t*t, /*o/*r/t*s*, /*o/*r/te*, /*o/*r/*t, /*o/*r/*s*, /*o/*r/*e*, /*o/*r/t*, /*o/*r/*, /*o/*a*/test, /*o/*a*/*est, /*o/*a*/t*st, /*o/*a*/te*t, /*o/*a*/tes*, /*o/*a*/*st, /*o/*a*/*e*t, /*o/*a*/*es*, /*o/*a*/t*t, /*o/*a*/t*s*, /*o/*a*/te*, /*o/*a*/*t, /*o/*a*/*s*, /*o/*a*/*e*, /*o/*a*/t*, /*o/*a*/*, /*o/b*/test, /*o/b*/*est, /*o/b*/t*st, /*o/b*/te*t, /*o/b*/tes*, /*o/b*/*st, /*o/b*/*e*t, /*o/b*/*es*, /*o/b*/t*t, /*o/b*/t*s*, /*o/b*/te*, /*o/b*/*t, /*o/b*/*s*, /*o/b*/*e*, /*o/b*/t*, /*o/b*/*, /*o/*/test, /*o/*/*est, /*o/*/t*st, /*o/*/te*t, /*o/*/tes*, /*o/*/*st, /*o/*/*e*t, /*o/*/*es*, /*o/*/t*t, /*o/*/t*s*, /*o/*/te*, /*o/*/*t, /*o/*/*s*, /*o/*/*e*, /*o/*/t*, /*o/*/*, /*o*/bar/test, /*o*/bar/*est, /*o*/bar/t*st, /*o*/bar/te*t, /*o*/bar/tes*, /*o*/bar/*st, /*o*/bar/*e*t, /*o*/bar/*es*, /*o*/bar/t*t, /*o*/bar/t*s*, /*o*/bar/te*, /*o*/bar/*t, /*o*/bar/*s*, /*o*/bar/*e*, /*o*/bar/t*, /*o*/bar/*, /*o*/*ar/test, /*o*/*ar/*est, /*o*/*ar/t*st, /*o*/*ar/te*t, /*o*/*ar/tes*, /*o*/*ar/*st, /*o*/*ar/*e*t, /*o*/*ar/*es*, /*o*/*ar/t*t, /*o*/*ar/t*s*, /*o*/*ar/te*, /*o*/*ar/*t, /*o*/*ar/*s*, /*o*/*ar/*e*, /*o*/*ar/t*, /*o*/*ar/*, /*o*/b*r/test, /*o*/b*r/*est, /*o*/b*r/t*st, /*o*/b*r/te*t, /*o*/b*r/tes*, /*o*/b*r/*st, /*o*/b*r/*e*t, /*o*/b*r/*es*, /*o*/b*r/t*t, /*o*/b*r/t*s*, /*o*/b*r/te*, /*o*/b*r/*t, /*o*/b*r/*s*, /*o*/b*r/*e*, /*o*/b*r/t*, /*o*/b*r/*, /*o*/ba*/test, /*o*/ba*/*est, /*o*/ba*/t*st, /*o*/ba*/te*t, /*o*/ba*/tes*, /*o*/ba*/*st, /*o*/ba*/*e*t, /*o*/ba*/*es*, /*o*/ba*/t*t, /*o*/ba*/t*s*, /*o*/ba*/te*, /*o*/ba*/*t, /*o*/ba*/*s*, /*o*/ba*/*e*, /*o*/ba*/t*, /*o*/ba*/*, /*o*/*r/test, /*o*/*r/*est, /*o*/*r/t*st, /*o*/*r/te*t, /*o*/*r/tes*, /*o*/*r/*st, /*o*/*r/*e*t, /*o*/*r/*es*, /*o*/*r/t*t, /*o*/*r/t*s*, /*o*/*r/te*, /*o*/*r/*t, /*o*/*r/*s*, /*o*/*r/*e*, /*o*/*r/t*, /*o*/*r/*, /*o*/*a*/test, /*o*/*a*/*est, /*o*/*a*/t*st, /*o*/*a*/te*t, /*o*/*a*/tes*, /*o*/*a*/*st, /*o*/*a*/*e*t, /*o*/*a*/*es*, /*o*/*a*/t*t, /*o*/*a*/t*s*, /*o*/*a*/te*, /*o*/*a*/*t, /*o*/*a*/*s*, /*o*/*a*/*e*, /*o*/*a*/t*, /*o*/*a*/*, /*o*/b*/test, /*o*/b*/*est, /*o*/b*/t*st, /*o*/b*/te*t, /*o*/b*/tes*, /*o*/b*/*st, /*o*/b*/*e*t, /*o*/b*/*es*, /*o*/b*/t*t, /*o*/b*/t*s*, /*o*/b*/te*, /*o*/b*/*t, /*o*/b*/*s*, /*o*/b*/*e*, /*o*/b*/t*, /*o*/b*/*, /*o*/*/test, /*o*/*/*est, /*o*/*/t*st, /*o*/*/te*t, /*o*/*/tes*, /*o*/*/*st, /*o*/*/*e*t, /*o*/*/*es*, /*o*/*/t*t, /*o*/*/t*s*, /*o*/*/te*, /*o*/*/*t, /*o*/*/*s*, /*o*/*/*e*, /*o*/*/t*, /*o*/*/*, /f*/bar/test, /f*/bar/*est, /f*/bar/t*st, /f*/bar/te*t, /f*/bar/tes*, /f*/bar/*st, /f*/bar/*e*t, /f*/bar/*es*, /f*/bar/t*t, /f*/bar/t*s*, /f*/bar/te*, /f*/bar/*t, /f*/bar/*s*, /f*/bar/*e*, /f*/bar/t*, /f*/bar/*, /f*/*ar/test, /f*/*ar/*est, /f*/*ar/t*st, /f*/*ar/te*t, /f*/*ar/tes*, /f*/*ar/*st, /f*/*ar/*e*t, /f*/*ar/*es*, /f*/*ar/t*t, /f*/*ar/t*s*, /f*/*ar/te*, /f*/*ar/*t, /f*/*ar/*s*, /f*/*ar/*e*, /f*/*ar/t*, /f*/*ar/*, /f*/b*r/test, /f*/b*r/*est, /f*/b*r/t*st, /f*/b*r/te*t, /f*/b*r/tes*, /f*/b*r/*st, /f*/b*r/*e*t, /f*/b*r/*es*, /f*/b*r/t*t, /f*/b*r/t*s*, /f*/b*r/te*, /f*/b*r/*t, /f*/b*r/*s*, /f*/b*r/*e*, /f*/b*r/t*, /f*/b*r/*, /f*/ba*/test, /f*/ba*/*est, /f*/ba*/t*st, /f*/ba*/te*t, /f*/ba*/tes*, /f*/ba*/*st, /f*/ba*/*e*t, /f*/ba*/*es*, /f*/ba*/t*t, /f*/ba*/t*s*, /f*/ba*/te*, /f*/ba*/*t, /f*/ba*/*s*, /f*/ba*/*e*, /f*/ba*/t*, /f*/ba*/*, /f*/*r/test, /f*/*r/*est, /f*/*r/t*st, /f*/*r/te*t, /f*/*r/tes*, /f*/*r/*st, /f*/*r/*e*t, /f*/*r/*es*, /f*/*r/t*t, /f*/*r/t*s*, /f*/*r/te*, /f*/*r/*t, /f*/*r/*s*, /f*/*r/*e*, /f*/*r/t*, /f*/*r/*, /f*/*a*/test, /f*/*a*/*est, /f*/*a*/t*st, /f*/*a*/te*t, /f*/*a*/tes*, /f*/*a*/*st, /f*/*a*/*e*t, /f*/*a*/*es*, /f*/*a*/t*t, /f*/*a*/t*s*, /f*/*a*/te*, /f*/*a*/*t, /f*/*a*/*s*, /f*/*a*/*e*, /f*/*a*/t*, /f*/*a*/*, /f*/b*/test, /f*/b*/*est, /f*/b*/t*st, /f*/b*/te*t, /f*/b*/tes*, /f*/b*/*st, /f*/b*/*e*t, /f*/b*/*es*, /f*/b*/t*t, /f*/b*/t*s*, /f*/b*/te*, /f*/b*/*t, /f*/b*/*s*, /f*/b*/*e*, /f*/b*/t*, /f*/b*/*, /f*/*/test, /f*/*/*est, /f*/*/t*st, /f*/*/te*t, /f*/*/tes*, /f*/*/*st, /f*/*/*e*t, /f*/*/*es*, /f*/*/t*t, /f*/*/t*s*, /f*/*/te*, /f*/*/*t, /f*/*/*s*, /f*/*/*e*, /f*/*/t*, /f*/*/*, /*/bar/test, /*/bar/*est, /*/bar/t*st, /*/bar/te*t, /*/bar/tes*, /*/bar/*st, /*/bar/*e*t, /*/bar/*es*, /*/bar/t*t, /*/bar/t*s*, /*/bar/te*, /*/bar/*t, /*/bar/*s*, /*/bar/*e*, /*/bar/t*, /*/bar/*, /*/*ar/test, /*/*ar/*est, /*/*ar/t*st, /*/*ar/te*t, /*/*ar/tes*, /*/*ar/*st, /*/*ar/*e*t, /*/*ar/*es*, /*/*ar/t*t, /*/*ar/t*s*, /*/*ar/te*, /*/*ar/*t, /*/*ar/*s*, /*/*ar/*e*, /*/*ar/t*, /*/*ar/*, /*/b*r/test, /*/b*r/*est, /*/b*r/t*st, /*/b*r/te*t, /*/b*r/tes*, /*/b*r/*st, /*/b*r/*e*t, /*/b*r/*es*, /*/b*r/t*t, /*/b*r/t*s*, /*/b*r/te*, /*/b*r/*t, /*/b*r/*s*, /*/b*r/*e*, /*/b*r/t*, /*/b*r/*, /*/ba*/test, /*/ba*/*est, /*/ba*/t*st, /*/ba*/te*t, /*/ba*/tes*, /*/ba*/*st, /*/ba*/*e*t, /*/ba*/*es*, /*/ba*/t*t, /*/ba*/t*s*, /*/ba*/te*, /*/ba*/*t, /*/ba*/*s*, /*/ba*/*e*, /*/ba*/t*, /*/ba*/*, /*/*r/test, /*/*r/*est, /*/*r/t*st, /*/*r/te*t, /*/*r/tes*, /*/*r/*st, /*/*r/*e*t, /*/*r/*es*, /*/*r/t*t, /*/*r/t*s*, /*/*r/te*, /*/*r/*t, /*/*r/*s*, /*/*r/*e*, /*/*r/t*, /*/*r/*, /*/*a*/test, /*/*a*/*est, /*/*a*/t*st, /*/*a*/te*t, /*/*a*/tes*, /*/*a*/*st, /*/*a*/*e*t, /*/*a*/*es*, /*/*a*/t*t, /*/*a*/t*s*, /*/*a*/te*, /*/*a*/*t, /*/*a*/*s*, /*/*a*/*e*, /*/*a*/t*, /*/*a*/*, /*/b*/test, /*/b*/*est, /*/b*/t*st, /*/b*/te*t, /*/b*/tes*, /*/b*/*st, /*/b*/*e*t, /*/b*/*es*, /*/b*/t*t, /*/b*/t*s*, /*/b*/te*, /*/b*/*t, /*/b*/*s*, /*/b*/*e*, /*/b*/t*, /*/b*/*, /*/*/test, /*/*/*est, /*/*/t*st, /*/*/te*t, /*/*/tes*, /*/*/*st, /*/*/*e*t, /*/*/*es*, /*/*/t*t, /*/*/t*s*, /*/*/te*, /*/*/*t, /*/*/*s*, /*/*/*e*, /*/*/t*, /*/*/*]

3) Dann durchlaufe ich die Elemente in dieser Liste oben und überprüfe, ob sie nur mit einem einzelnen Dateipfad im Eingabearray der Dateipfade übereinstimmen. (Ich überprüfe dazu zwei Dinge: Ist die Anzahl der Schrägstriche gleich und stimmt sie mit dem regulären Ausdruck überein, durch den jeder *ersetzt wird .*.)
Wenn dies der Fall ist: Behalte den (ersten) kürzesten, den wir am Ende zurückgeben.

Kevin Cruijssen
quelle
Was ist >>>? Ich weiß, >>ist bitweise Rechtsverschiebung.
Pavel
2
@Pavel Verhält sich bei positiven Ganzzahlen >>>genauso wie >>. Bei negativen Ganzzahlen wird das Paritätsbit jedoch auf 0 geändert (einige Beispiele finden Sie hier im Abschnitt " >> vs >>> " ). -1>>>1ist nur eine kürzere Variante von Integer.MAX_VALUE(und 1<<31wäre Integer.MIN_VALUE).
Kevin Cruijssen