2012-05-23 13 views
8

Co chciałbym zrobić, to wziąć ciąg i powrócić wszystkich możliwych podciągów, które są większe niż długość 2. Tak więc na przykładzie welcome:Jak znaleźć wszystkie możliwe ciągi w ciągu znaków?

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

Jedynym sposobem mogłem myśleć zrobić to było coś takiego (całkowicie niesprawdzone):

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

Ale zastanawiam się, czy istnieje lepszy sposób to zrobić (przy użyciu LINQ ewentualnie), że nie wiem?

+2

To dokładny sposób bym go zrobić ... Chociaż, nie chcesz, aby rozpocząć mam zero? – jahroy

+0

Dotyczy to pierwszej pętli. Musiałbym przetestować, aby upewnić się co do reszty, ale myślę, że ponieważ nie chcę 1-literowego podciągu, muszę zacząć od 2. –

+3

Zdefiniuj "lepiej" :) – dzendras

Odpowiedz

11

Jak to jest na prostym, czytelnym podejście?

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

Produkuje:

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

Możesz pozbyć się 'where' jeśli zrobisz swoje drugie' .Range' zaczniesz od '2' – AakashM

+0

(lub coś w tym stylu) – AakashM

+0

@AakashM - Z pewnością mogę usunąć' where j> = 2' przez zmianę drugi "Range" to "Enumerable.Range (2, text.Length - i - 1)", ale to czyni tę funkcję mniej oczywistą. To spowodowałoby zwarcie kilku iteracji, ale wszystko jest w pamięci i jest bardzo szybkie w obu kierunkach. – Enigmativity

3

LINQ To rozwiązanie powinno działać:

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 .. to jest miejsce, w którym uważam, że podejście oparte na pętli jest bardziej przejrzyste i czytelne :-) Chociaż Linq może działać w tym problemie nie jest on tak czytelny (co jest jednym z mocnych punktów Linqa) jako podejście oparte na pętli – Hao

+1

@Hao Absolutnie! Rozwiązanie LINQ dla problemu tego prostego jest tylko ciekawostką - tylko po to, aby pokazać, że LINQ jest wystarczająco potężne, aby to zrobić. – dasblinkenlight

0

Kod jest w następujący sposób:

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; 
    } 
Powiązane problemy