2011-10-04 9 views
7

Algorytm ten jest ustawiony tak, aby działał nad pierwszym słowem lub dopóki nie wypełni czterech zakodowanych ciągów. Na przykład wynik wejścia "Horrible Great" to: H612. Pomija drugie słowo, lub innymi słowy, zajmuje tylko pierwszą literę z drugiego słowa, aby wypełnić zakodowany ciąg.Niektóre zmiany w algorytmie Soundex

Chciałbym to zmienić, biorąc pierwsze słowo i znaleźć jego zakodowany ciąg, a następnie wziąć drugie słowo i znaleźć jego zakodowany ciąg; wyjście powinno być "H614 G600". Uprzejmie chciałbym wiedzieć, czy jest sposób na zrobienie tego poprzez zmianę ** na ten kod .
Dziękuję bardzo :)

private string Soundex(string data) 
    { 
     StringBuilder result = new StringBuilder(); 
     if (data != null && data.Length > 0) 
     { 
      string previousCode = "", currentCode = "", currentLetter = ""; 
      result.Append(data.Substring(0, 1)); 
      for (int i = 1; i < data.Length; i++) 
      { 
       currentLetter = data.Substring(i,1).ToLower(); 
       currentCode = ""; 

       if ("bfpv".IndexOf(currentLetter) > -1) 
        currentCode = "1"; 
       else if ("cgjkqsxz".IndexOf(currentLetter) > -1) 
        currentCode = "2"; 
       else if ("dt".IndexOf(currentLetter) > -1) 
        currentCode = "3"; 
       else if (currentLetter == "l") 
        currentCode = "4"; 
       else if ("mn".IndexOf(currentLetter) > -1) 
        currentCode = "5"; 
       else if (currentLetter == "r") 
        currentCode = "6"; 

       if (currentCode != previousCode) 
        result.Append(currentCode); 

       if (result.Length == 4) break; 

       if (currentCode != "") 
        previousCode = currentCode; 
      } 
     } 

     if (result.Length < 4) 
      result.Append(new String('0', 4 - result.Length)); 

     return result.ToString().ToUpper(); 
    } 

Odpowiedz

4

Oczywiście, oto rozwiązanie, które wymyśliłem. Zapakowałem istniejący algorytm inną metodą, która dzieli ciągi i wywołuje oryginalną metodę. Aby użyć tego, nazwałbyś SoundexByWord ("Horrible Great") zamiast wywoływać Soundex ("Horrible Great") i uzyskiwać wyjście "H614 G630".

private string SoundexByWord(string data) 
{ 
    var soundexes = new List<string>(); 
    foreach(var str in data.Split(' ')){ 
     soundexes.Add(Soundex(str)); 
    } 
#if Net35OrLower 
    // string.Join in .Net 3.5 and before require the second parameter to be an array. 
    return string.Join(" ", soundexes.ToArray()); 
#endif 
    // string.Join in .Net 4 has an overload that takes IEnumerable<string> 
    return string.Join(" ", soundexes); 
} 
+0

JUŻ NIESAMOWITE! dziękuję bardzo za dzielenie się. pozwala mi edytować kod napisałem powyżej: private String SoundexByWord danych (String) {var soundexes = new List (); foreach (var str w data.Split ('')) { soundexes.Add (Soundex (str)); } return string.Join ("", soundexes.ToArray()); // Konwertuj listę } // na tablicę, która łączy funkcję Fun. pobiera ciąg tablic [] :) – user979014

+0

To dobra uwaga. Oryginalna odpowiedź była oparta na .Net 4. W oparciu o Twoją sugestię, rozszerzyłem odpowiedź o wcześniejsze wersje. – jhamm

+0

Podziwiam twoją ostatnią edycję i sposób wyjaśnienia :) jeszcze raz dziękuję – user979014

0

tak - najpierw przeanalizować ciągu na tablicę słów (po odbiór separator)

następnie to zrobić na każdym słowie

następnie zmontować wyniki w pewien akceptowalny sposób i powrót.

+0

myślałem o ułamku ciąg następnie ciąg concat na indywidualne i zamontować je, ale chcę zmienić samego algorytmu jakoś . doceniam twoje anser choć :)) – user979014

0

Implementacja w pytaniu jest poprawna, ale tworzy nadmiar śmieci z operacjami łańcuchowymi. Oto implementacja oparta na tablicy szarej, która jest szybsza i tworzy bardzo mało śmieci. Jest zaprojektowany jako metodę rozszerzenia i obsługuje fraz (słów oddzielonych spacjami), a także:

public static String Soundex(this String input) 
    { 
     var words = input.Split(' '); 
     var result = new String[ words.Length ]; 
     for(var i = 0; i < words.Length; i++) 
      result[ i ] = words[ i ].SoundexWord(); 

     return String.Join(",", result); 
    } 

    private static String SoundexWord(this String input) 
    { 
     var result = new Char[ 4 ] { '0', '0', '0', '0' }; 
     var inputArray = input.ToUpper().ToCharArray(); 

     if(inputArray.Length > 0) 
     { 
      var previousCode = ' '; 
      var resultIndex = 0; 

      result[ resultIndex ] = inputArray[ 0 ]; 

      for(var i = 1; i < inputArray.Length; i++) 
      { 
       var currentLetter = inputArray[ i ]; 
       var currentCode = ' '; 

       if("BFPV".IndexOf(currentLetter) > -1) 
        currentCode = '1'; 
       else if("CGJKQSXZ".IndexOf(currentLetter) > -1) 
        currentCode = '2'; 
       else if("DT".IndexOf(currentLetter) > -1) 
        currentCode = '3'; 
       else if(currentLetter == 'L') 
        currentCode = '4'; 
       else if("MN".IndexOf(currentLetter) > -1) 
        currentCode = '5'; 
       else if(currentLetter == 'R') 
        currentCode = '6'; 

       if(currentCode != ' ' && currentCode != previousCode) 
        result[ ++resultIndex ] = currentCode; 

       if(resultIndex == 3) break; 

       if(currentCode != ' ') 
        previousCode = currentCode; 
      } 
     } 

     return new String(result); 
    } 
Powiązane problemy