2012-05-23 32 views
8

Quello che vorrei fare è prendere una stringa e restituire tutte le possibili stringhe che sono maggiori di lunghezza 2. Quindi, utilizzando il welcome esempio:Come trovare tutte le sottostringhe possibili in una stringa?

we 
el 
lc 
co 
me 
wel 
elc 
lco 
com 
ome 
welc 
elco 
lcom 
come 
and so on..... 

L'unico modo ho potuto pensare di fare era qualcosa di simile (totalmente non testata):

for (int i = 0; i < word.Length; i++) //i is starting position 
{ 
    for (int j = 2; j + i < word.Length; j++) //j is number of characters to get 
    { 
     wordList.Add(word.SubString(i, j)); 
    } 
} 

Ma mi chiedo se c'è un modo migliore per fare questo (utilizzando LINQ forse) che io non so?

+2

Questo è il modo esatto lo farei ... Anche se, non si vuole iniziare io a zero? – jahroy

+0

Questo vale per il primo ciclo. Dovrei testare per essere sicuro del resto, ma penso che dal momento che non voglio sottostringhe da 1 lettera devo iniziare da 2. –

+3

Definire "meglio" :) – dzendras

risposta

11

Come sta questo per un approccio semplice, leggibile?

var text = "welcome"; 

var query = 
    from i in Enumerable.Range(0, text.Length) 
    from j in Enumerable.Range(0, text.Length - i + 1) 
    where j >= 2 
    select text.Substring(i, j); 

Produce:

we 
wel 
welc 
welco 
welcom 
welcome 
el 
elc 
elco 
elcom 
elcome 
lc 
lco 
lcom 
lcome 
co 
com 
come 
om 
ome 
me 
+0

Puoi sbarazzarti di 'where' se fai il tuo secondo' .Range' start da '2' – AakashM

+0

(o qualcosa del genere) – AakashM

+0

@AakashM - Certamente ho potuto rimuovere' where j> = 2' cambiando il secondo 'Range' deve essere' Enumerable.Range (2, text.Length - i - 1) ', ma questo rende la funzione di questa query meno ovvia. Potrebbe cortocircuitare alcune iterazioni, ma è tutto in memoria ed è molto veloce in entrambi i casi. – Enigmativity

3

Questa soluzione LINQ dovrebbe funzionare:

var str = "welcome"; 
var items = Enumerable 
    .Range(0, str.Length) 
    .SelectMany(i => Enumerable.Range(2, str.Length-i-1).Select(j => str.Substring(i, j))) 
    .Distinct() 
    .OrderBy(s => s.Length); 
foreach (var s in items) { 
    Console.WriteLine(s); 
} 
+1

Hmm .. questo è dove trovo che l'approccio basato su loop è più chiaro e leggibile :-) Anche se Linq potrebbe funzionare in questo problema, non è leggibile (che è uno dei punti di forza di Linq) come approccio basato su loop – Hao

+1

@Hao Assolutamente! La soluzione LINQ a un problema così semplice è una semplice curiosità - solo per dimostrare che LINQ è abbastanza potente per farlo. – dasblinkenlight

0

Il codice è il seguente:

internal static List<string> GetAllSubstring(String mainString) 
    { 
     try 
     { 
      var stringList = new List<string>(); 
      if(!string.IsNullOrEmpty(mainString)) 
      { 
       for (int i = 0; i < mainString.Length; i++) //i is starting position 
       { 
        for (int j = 2; j + i < mainString.Length; j++) //j is number of characters to get 
        { 
         if(!stringList.Contains(mainString.Substring(i, j))) 
         { 
          stringList.Add(mainString.Substring(i, j)); 
         } 
        } 
       } 

      } 

      return stringList; 
     } 
     catch(Exception ex) 
     { 

     } 

     return null; 
    } 
Problemi correlati