15

次のステートメントを実行すると:

string.Compare("mun", "mün", true, CultureInfo.InvariantCulture)

結果は「-1」で、「mun」の数値が「mün」よりも小さいことを示します。

ただし、このステートメントを実行すると:

string.Compare("Muntelier, Schweiz", "München, Deutschland", true, CultureInfo.InvariantCulture)

「1」が表示され、「Muntelier, Schewiz」が最後になることを示します。

これは比較のバグですか?または、アクセント付きを含む文字列をソートするときに考慮すべきルールはありますか


これが問題である理由は、リストを並べ替えてから、「xxx」で始まるすべての文字列を取得するための手動のバイナリ フィルターを実行しているためです。

以前は Linq の 'Where' メソッドを使用していましたが、別の人が作成したこのカスタム関数を使用する必要があります。

しかし、カスタム関数は、.NET の「ユニコード」ルールを考慮していないようです。そのため、「mün」でフィルタリングするように指示すると、リストに「mun」で始まるアイテムがあるにもかかわらず、アイテムが見つかりません。

これは、アクセント付きの文字の後に続く文字によって、アクセント付きの文字の順序に一貫性がないためと思われます。


OK、問題は解決したと思います。

フィルタの前に、各文字列の最初のn文字に基づいて並べ替えを行います。nは検索文字列の長さです。

4

3 に答える 3

23

動作中のタイブレーク アルゴリズムがあります。http: //unicode.org/reports/tr10/を参照してください。

言語依存の並べ替えの複雑さに対処するために、マルチレベル比較アルゴリズムが採用されています。たとえば、2 つの単語を比較する場合、最も重要な特徴は基本文字 (A と B の違いなど) です。通常、基本文字に違いがある場合、アクセントの違いは無視されます。大文字と小文字の違い (大文字と小文字) は、ベースまたはアクセントに違いがある場合、通常は無視されます。句読点は可変です。状況によっては、句読点文字が基本文字のように扱われることがあります。他の状況では、ベース、アクセント、または大文字と小文字の違いがある場合は無視する必要があります。また、最終的なタイブレーク レベルが存在する場合もあります。これにより、文字列に他の違いがまったくない場合は、(正規化された) コード ポイントの順序が使用されます。

つまり、"Munt..." と "Münc..." はアルファベット順で異なり、"t" と "c" に基づいて並べ替えられます。

一方、「mun」と「mün」はアルファベット順で同じなので (「u」は失われた言語の「ü」に相当します)、文字コードを比較します。

于 2009-09-03T07:26:04.550 に答える
6

アクセント付きの文字は、一種の「タイブレーク」の状況でのみ使用されているようです。つまり、文字列が他の点で等しい場合です。

デモ用のサンプル コードを次に示します。

using System;
using System.Globalization;

class Test
{
    static void Main()
    {
        Compare("mun", "mün");
        Compare("muna", "münb");
        Compare("munb", "müna");
    }

    static void Compare(string x, string y)
    {
        int result = string.Compare(x, y, true, 
                                   CultureInfo.InvariantCulture));

        Console.WriteLine("{0}; {1}; {2}", x, y, result);
    }
}

(「n」の後にスペースを追加して、単語の境界で行われたかどうかを確認しましたが、そうではありません。)

結果:

mun; mün; -1
muna; münb; -1
munb; müna; 1

これは、さまざまな複雑な Unicode 規則によって正しいと思われますが、それらについて十分に知りません。

これを考慮に入れる必要があるかどうかについては...私はそうは思わない. あなたはこれによって投げられて何をしていますか?

于 2009-09-03T07:21:10.243 に答える
4

私がこれを理解しているように、それはまだいくらか一貫しています。CultureInfo.InvariantCultureウムラウト文字を使用して比較すると、üアクセントのない文字のように扱われuます。

最初の例の文字列は明らかに等しくないため、結果は 0 ではなく -1 になります (これはデフォルト値のようです)。2 番目の例では、アルファベットでtがcに続くため、 Muntelierが最後になります。

これらのルールを説明する明確なドキュメントは MSDN に見つかりませんでしたが、

string.Compare("mun", "mün", CultureInfo.InvariantCulture,  
    CompareOptions.StringSort);

string.Compare("Muntelier, Schweiz", "München, Deutschland", 
    CultureInfo.InvariantCulture, CompareOptions.StringSort);

望ましい結果が得られます。

とにかく、現在のユーザーの文化などの特定の文化に基づいて並べ替えを行う方がよいと思います (可能であれば)。

于 2009-09-03T07:21:16.700 に答える