3

簡単に言えば、Soundex Algorithm は一連の文字をコードに変更します。同じ Soundex コードを生成する文字は、同じように聞こえると言われます。

  • コードは 4 文字幅です
  • コードの最初の文字は常に単語の最初の文字です

アルファベットの各文字は、特定のグループに属しています (少なくともこの例とその後のコードでは、これが私が固執するルールです):

  • b、p、v、f = 1
  • c、g、j、k、q、s、x、z = 2
  • d、t = 3
  • l = 4
  • メートル、n = 5
  • r = 6
  • アルファベットの 1 文字おきにグループ 0 に属します。

その他の注目すべきルールは次のとおりです。

  • グループ 0 に属するすべての文字は、指定された単語の文字が不足しない限り無視されます。この場合、残りのコードは 0 で埋められます。
  • 同じ数字を 2 回以上連続して使用することはできないため、文字は無視されます。唯一の例外は、複数の 0 を持つ上記のルールです。

たとえば、"Ray" という単語は、次の Soundex コードを生成します: R000 (R は提供された単語の最初の文字です。a はグループ 0 の一部であるため無視されます。y はグループ 0 の一部であるため無視されます。コード内の残りの 3 文字は 0 です)。

1) Soundex コードの作成に使用される 128 文字の配列と、2) 関数の完了時に Soundex コードを格納するために使用される空の 5 文字の配列 (およびほとんどの配列が私のプログラムで使用するために行うように、参照によって返されます)。

ただし、私の問題は変換プロセスにあります。上記で提供したロジックは、私のコードでは正確に機能していません。そして私はなぜだか分からない。

// CREATE A SOUNDEX CODE
// * Parameter list includes the string of characters that are to be converted to code and a variable to save the code respectively.
void SoundsAlike(const char input[], char scode[])
{
    scode[0] = toupper(input[0]); // First character of the string is added to the code

    int matchCount = 1;
    int codeCount = 1;
    while((matchCount < strlen(input)) && (codeCount < 4))
    {
        if(((input[matchCount] == 'b') || (input[matchCount] == 'p') || (input[matchCount] == 'v') || (input[matchCount] == 'f')) && (scode[codeCount-1] != 1))
        {
            scode[codeCount] = 1;
            codeCount++;
        }
        else if(((input[matchCount] == 'c') || (input[matchCount] == 'g') || (input[matchCount] == 'j') || (input[matchCount] == 'k') || (input[matchCount] == 'q') || (input[matchCount] == 's') || (input[matchCount] == 'x') || (input[matchCount] == 'z')) && (scode[codeCount-1] != 2))
        {
            scode[codeCount] = 2;
            codeCount++;
        }
        else if(((input[matchCount] == 'd') || (input[matchCount] == 't')) && (scode[codeCount-1] != 3))
        {
            scode[codeCount] = 3;
            codeCount++;
        }
        else if((input[matchCount] == 'l') && (scode[codeCount-1] != 4))
        {
            scode[codeCount] = 4;
            codeCount++;
        }
        else if(((input[matchCount] == 'm') || (input[matchCount] == 'n')) && (scode[codeCount-1] != 5))
        {
            scode[codeCount] = 5;
            codeCount++;
        }
        else if((input[matchCount] == 'r') && (scode[codeCount-1] != 6))
        {
            scode[codeCount] = 6;
            codeCount++;
        }
        matchCount++;
    }

    while(codeCount < 4)
    {
        scode[codeCount] = 0;
        codeCount++;
    }
    scode[4] = '\0';

    cout << scode << endl;
}

strlen の使いすぎが原因かどうかはわかりませんが、何らかの理由でプログラムが最初の while ループ内で実行されている間、文字が実際にコードに変換されません (つまり、if ステートメントが実際に実行されません)。

それで、私は何を間違っていますか?どんな助けでも大歓迎です。

4

4 に答える 4

3

それ以外の

scode[codeCount] = 1;

あなたは書くべきです

scode[codeCount] = '1';

char配列を形成しているため、前者は実際には最初のASCII文字であり、後者は文字「1」です。

于 2009-04-22T12:05:30.377 に答える
0

C++ は、使用しようとしているように見える動的配列をサポートしていません。std::string クラスの使用を調査する必要があります。私は本質的にあなたのループが次のようになります:

void Soundex( const string & input, string & output ) {
   for ( int i = 0; i < input.length(); i++ ) {
       char c = input[i];        // get character from input
       if ( c === .... ) {       // if some decision
            output += 'X';       // add some character to output
       }
       else if ( ..... )  {       // more tests
       }
   }
}
于 2009-04-22T10:24:26.113 に答える
0

これは実際には C 実装であり、C++ ではありません。とにかく、あなたの文字列がヌルで終わっていると確信していますか? そうしないと、strlen は機能しません。

コードを読みやすく、デバッグしやすくするためのアドバイスを次に示します。

  • 開始する前に、入力を小文字に変換してください。不正な文字をテストします。
  • 変数を定義し、input[matchCount] に設定して、これを使用します。コードが読みやすくなります。
  • if-else ステートメントを switch-case ステートメントに置き換えることをお勧めします。
  • デフォルトのケースに対応する (if-else または case ステートメントが呼び出されない)
于 2009-04-22T10:42:45.693 に答える
0

文字列に null char 終端を追加せずに strlen() を呼び出しています。したがって、 strlen() の戻り値は何でもかまいません。開始する前に「scode」に「\0」を入力することでこれを修正できますが、そのための別のカウンターを用意し、完了したら「\0」を追加する方がよいでしょう。

于 2009-04-22T10:41:35.680 に答える