2012-05-23 6 views
8

Что я хотел бы сделать, это взять строку и возвращает все возможные подстроки, которые больше длины 2. Таким образом, используя welcome пример:Как найти все возможные подстроки в строке?

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

Единственный способ, которым я мог думать, чтобы сделать это было что-то вроде этого (совершенно непроверенные):

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

Но мне интересно, если есть лучший способ сделать это (с помощью LINQ, возможно), что я не знаю о?

+2

Это точно так, как я бы это сделать ... Хотя, вы не хотели бы, чтобы начать i в нуле? – jahroy

+0

Это верно для первого цикла. Я должен был проверить, чтобы быть уверенным в остальном, но я думаю, так как мне не нужны 1 подстроки букв, мне нужно начинать с 2. –

+3

Определить «лучше» :) – dzendras

ответ

11

Как это для простого, читаемого подхода?

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

Он производит:

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

Вы можете избавиться от 'where', если вы сделаете свой второй запуск .Range' из' 2' – AakashM

+0

(или что-то в этом роде) – AakashM

+0

@AakashM - Я, конечно, мог бы удалить 'where j> = 2', изменив второй «диапазон» должен быть «Enumerable.Range (2, text.Length - i - 1)», но это делает функцию этого запроса менее очевидной. Это приведет к короткому замыканию нескольких итераций, но все это в памяти, и это очень быстро в любом случае. – Enigmativity

3

Этого решение LINQ должно работать:

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

Хм .. вот где я нахожу, что петлевый подход более понятен и читабельен :-) Хотя Linq может работать в этой проблеме это не так читаемо (что является одной из сильных сторон Linq), как петлевой подход – Hao

+1

@Hao Абсолютно! Решение LINQ для решения этой проблемы простое любопытство - просто для того, чтобы показать, что LINQ достаточно эффективен для этого. – dasblinkenlight

0

Код выглядит следующим образом:

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; 
    } 
Смежные вопросы