Sottostringhe identificative univoche più brevi


23

Dato un elenco di stringhe, sostituire ogni stringa con una delle sue sottostringhe non vuote che non è una sottostringa di nessuna delle altre stringhe nell'elenco e il più breve possibile.

Esempio

Data la lista ["hello","hallo","hola"], "hello"dovrebbe essere sostituito da solo "e"in quanto ciò stringa non è contenuta in "hallo"e "hola"ed è il più corto possibile. "hallo"potrebbe essere sostituito da uno "ha"o "al"e "hola"da qualsiasi di "ho", "ol"o "la".

Regole

  • Puoi presumere che le stringhe saranno non vuote e contengano solo caratteri alfabetici dello stesso caso.
  • Si può presumere che una tale sottostringa esista per ogni stringa nell'elenco, cioè nessuna stringa nell'elenco sarà una sottostringa di una qualsiasi delle altre stringhe.
  • L'input e l'output possono essere in qualsiasi formato ragionevole.
  • Questo è , quindi cerca di usare il minor numero di byte possibile nella lingua che preferisci.

Casi test

Nella maggior parte dei casi viene fornito un solo output possibile.

["ppcg"] -> ["p"] (or ["c"] or ["g"])
["hello","hallo","hola"] -> ["e","ha","ho"]
["abc","bca","bac"] -> ["ab","ca","ba"]
["abc","abd","dbc"] -> ["abc","bd","db"]
["lorem","ipsum","dolor","sit","amet"] -> ["re","p","d","si","a"]
["abc","acb","bac","bca","cab","cba"] -> ["abc","acb","bac","bca","cab","cba"]

Correlati: Sottostringa identificativa più breve - idea simile, ma regole più coinvolte e formato ingombrante.


Perchéntnt ""(stringa vuota) si identifica in modo univoco per il singolo "ppcg"caso?
MooseBoys,

2
@MooseBoys Dato un elenco di stringhe, sostituisci ogni stringa con una delle sue sottostringhe non vuote
Mr. Xcoder,

Risposte:




4

Pyth , 12 byte

mhf!ts}LTQ.:

Provalo qui!

Come funziona

Filtra fondamentalmente le sottostringhe di ciascuna che si verificano solo in una delle stringhe nell'elenco (ovvero è unica per quella stringa) e ottiene la prima.

mhf!ts}LTQ.:     Full program, Q=eval(stdin_input())
m         .:     Map over Q and obtain all the substrings of each.
  f              And filter-keep those that satisfy (var: T)...
      }LTQ       ... For each string in Q, yield 1 if it contains T, else 0.
   !ts           ... Sum the list, decrement and negate. 
 h               Head. Yields the first valid substring, which is always the shortest.

4

Prolog (SWI) , 175 163 byte

S/L/R:-sub_string(S,_,L,_,R).
[H|T]+[I|R]:-string_length(H,L),between(1,L,X),H/X/I,T+R.
R+R.
L-R:-L+R,forall(member(E,L),findall(_,(member(F,R),\+ \+ E/_/F),[_])).

Provalo online!

La maggior parte delle cose qui dovrebbe essere abbastanza ovvia, ma:

Spiegazione

Firme: ( += input, ?= opzionale, -= output, := espressione)

  • sub_string(+String, ?Before, ?Length, ?After, ?SubString)
  • string_length(+String, -Length)
  • member(?Elem, ?List)
  • between(+Low, +High, ?Value)
  • findall(+Template, :Goal, -Bag)
  • forall(:Cond, :Action)

\+ \+è giusto not not(ovvero converte una corrispondenza in booleano (in questo caso, impedisce che corrisponda a entrambe le ps ppcgseparatamente))


Lo strumento giusto per il lavoro: P tranne per il fatto che è incredibilmente prolisso
solo ASCII il


4

J , 30 29 25 byte

1(|:(0{-.&,)"_1]\.)<\\.&>

Provalo online!

                   <\\.&>        a 3-dimensional array of substrings
1 |:                             transpose each matrix to sort the substrings by length
1              ]\.               all choices where one word is missing
    (0{-.&,)"_1                  for every matrix, flatten, remove substrings
                                  that are present in the corresponding complement,
                                  pick first


3

JavaScript (ES6), 93 byte

a=>a.map(s=>(L=s.length,g=n=>a.every(S=>S==s|!~S.search(u=s.substr(n%L,n/L+1)))?u:g(n+1))(0))

Provalo online!

Come?

Per ogni stringa s di lunghezza L nell'array di input a [] e iniziando con n = 0 , usiamo la funzione ricorsiva g () per generare tutte le sottostringhe u di s con:

u = s.substr(n % L, n / L + 1)

Ad esempio, con s = "abc" e L = 3 :

 n | n%L | floor(n/L+1) | u
---+-----+--------------+-------
 0 |  0  |       1      | "a"
 1 |  1  |       1      | "b"
 2 |  2  |       1      | "c"
 3 |  0  |       2      | "ab"
 4 |  1  |       2      | "bc"
 5 |  2  |       2      | "c"
 6 |  0  |       3      | "abc"
 7 |  1  |       3      | "bc"
 8 |  2  |       3      | "c"

Alcune sottostringhe vengono generate più volte, ma non importa. L'importante è che tutte le sottostringhe di lunghezza N siano state generate prima di qualsiasi sottostringa di lunghezza N + 1 .

Ci fermiamo il processo non appena u non può essere trovato in qualsiasi altra stringa di S in un [] , che è garantito per accadere quando u == s nel peggiore dei casi, come da regola sfida # 2:

nessuna stringa nell'elenco sarà una sottostringa di nessuna delle altre stringhe

Pertanto, nell'esempio precedente, i passaggi 7 e 8 non verranno mai effettivamente elaborati.


2

PowerShell , 107 byte

($a=$args)|%{$(for($i=0;$i++-lt($g=($s=$_)|% Le*)){0..($g-$i)|%{$s|% s*g $_ $i}|?{!($a-match$_-ne$s)}})[0]}

Provalo online!

Spiegazione

Per ogni stringa fornita (e assegnare l'intero array a $a):

  • Esegui un forciclo su ciascuna lunghezza della sottostringa (1 in base) della stringa (assegnando la stringa stessa $se la lunghezza a $g)
  • Per ogni lunghezza ( $i):
    • Crea un ciclo di indice, da 0 a lunghezza - $i, quindi per ciascun indice:
      • Ottieni la sottostringa della stringa corrente ( $s) in posizione $_(indice) e di lunghezza$i
      • Passare quella sottostringa a Where-Object( ?) e restituirla se:
        • Il sottoinsieme di array ( $a) che non contiene la stringa corrente $s, non ha una corrispondenza per la sottostringa corrente$_

A livello di stringa, abbiamo tutte le sottostringhe di questa stringa che non sono state trovate nelle altre, quindi prendi la prima [0]poiché ne abbiamo solo bisogno, quindi continua con la stringa successiva.


0

C # (compilatore interattivo Visual C #) , 149 byte

a=>a.Select(s=>{var t=s;for(int j=0,k,l=s.Length;j++<l;)for(k=-1;j+k++<l;)if(!a.Where(u=>s!=u&u.Contains(t=s.Substring(k,j))).Any())j=k=l;return t;})

Provalo online!

Meno golf ...

// a is an input array of strings
a=>
  // iterate over input array   
  a.Select(s=>{
    // t is the result string
    var t=s;
    // j is the substring length
    for(int j=0,k,l=s.Length;j++<l;)
      // k is the start index
      for(k=-1;j+k++<l;)
        // LINQ query to check if substring is valid
        // the tested string is collected in t
        if(!a.Where(u=>s!=u&u.Contains(t=s.Substring(k,j))).Any())
          // break loops
          j=k=l;
    // return result
    return t;
  })
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.