2012-05-23 13 views
8

Lo que me gustaría hacer es tomar una cadena y devolver todas las subcadenas posibles que son mayores que la longitud 2. Así, utilizando el welcome ejemplo:¿Cómo encontrar todas las subcadenas posibles en una cadena?

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

La única manera de que pudiera pensar de hacerlo era algo como esto (totalmente no probado):

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)); 
    } 
} 

Pero me pregunto si hay una mejor manera de hacer esto (usando LINQ posiblemente) que yo no sepa?

+2

Esa es la forma exacta que lo haría ... Aunque, no habría que desee comenzar yo en cero? – jahroy

+0

Eso es cierto para el primer ciclo. Tendría que hacer una prueba para estar seguro del resto, pero creo que ya que no quiero subcadenas de 1 letra, necesito comenzar en 2. –

+3

Definir "mejor" :) – dzendras

Respuesta

11

¿Cómo está esto para un enfoque simple, legible?

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

Puede deshacerse del 'where' si realiza su segundo' .Range' desde '2' – AakashM

+0

(o algo por el estilo) – AakashM

+0

@AakashM - Ciertamente podría haber eliminado' where j> = 2' cambiando el segundo 'Rango' es' Enumerable.Range (2, text.Length - i - 1) ', pero eso hace que la función de esta consulta sea menos obvia. Sería un corto circuito de algunas iteraciones, pero está todo en la memoria y es muy rápido de cualquier manera. – Enigmativity

3

Esta solución LINQ debería funcionar:

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 ... aquí es donde encuentro que el enfoque basado en loop es más claro y legible :-) Aunque Linq podría funcionar en este problema, no es tan legible (que es uno de los puntos fuertes de Linq) como enfoque basado en bucle – Hao

+1

@Hao ¡Absolutamente! La solución de LINQ a un problema tan simple es una mera curiosidad, solo para mostrar que LINQ es lo suficientemente poderoso como para hacerlo. – dasblinkenlight

0

El código es el siguiente:

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; 
    } 
Cuestiones relacionadas