3

CompareTo()メソッドが内部でどのように機能するかを理解しようとしてきましたが、失敗しました。このサイトを検索していくつかの投稿を読みましたが、この件に関して MSDN で見るべきものはすべて見たと思いますが、理解できないようです。MSDN の例:

public int CompareTo(object obj)
{
    if (obj == null)
    {
        return 1;
    }

    Temperature otherTemperature = obj as Temperature;
    if (otherTemperature != null)
    {
        return this.temperatureC.CompareTo(otherTemperature.temperatureC);
    }
    else
    {
        throw new ArgumentException("the object is not a temperature");
    }
}

これは、CompareTo()メソッドの実装の MSDN の例です。私はこれを理解しています、私はインターフェースがどのように機能するかを理解しています。私が正しく理解していれば、メソッドIComparableを使用するときにこれが呼び出されます。ArrayList.Sort()

私が理解していないのは、プログラムがCompareTo(object obj)メソッドの引数を渡すのはいつですか? 言い換えれば、Sort()メソッドはどのように機能しますか? つまり、このコードは温度のインスタンスを温度の別のインスタンスと比較していますが、比較を行うために、プログラムはいつ、またはどのようにして 2 番目の温度インスタンスを取得するのでしょうか? 私の質問が理にかなっていることを願っています。

プロセスを画面に出力しようとしたCompareTo()ので、出力をリバースエンジニアリングできるかもしれませんが、さらに混乱しました。

編集:一歩一歩進んだら、自分自身をよりよく説明できるかもしれません。3 つの温度オブジェクトがあるとします: 34、45、21ArrayListです。を呼び出すArrayList.Sort()と、CompareTo()メソッドは のように呼び出され34.CompareTo(45)ますか? そして45.CompareTo(21)?返される整数は、最初の比較では 1 で、2 番目の比較では -1 でしょうか? CompareTo()また、obj (パラメーター) が null の場合にのみ 1 を返すようにメソッドを定義した場合、これらの整数はどのように返されるのでしょうか? -1 または 0 を返すものは何も定義していません。既に実装されているメソッドを実装しているようなものです。CompareTo()-1、0、および 1 を返すように定義済みのメソッドを定義する。

4

5 に答える 5

9

基本的な考え方から始めましょう。

CompareTo の目的は何ですか?

42 から 1337 とは何ですか? 42... は1337より大きいですか、それ以下ですか?

この質問とその回答は、およびインターフェイスのCompareToメソッドによってモデル化されています。の場合、メソッドは以下を返すことができます。IComparable<T>IComparableA.CompareTo(B)

  • A はBより大きい: 0 より大きい整数値。
  • A はBより小さい: 0 より小さい整数値。
  • A はB と等しい: 0 に等しい整数値。

もちろん、IComparable整数に限定されません。IComparable比較できると思われる任意の 2 つのオブジェクトを比較するために実装できます。たとえば、文字列:

"Zodiac" に対する "Armadillo" とは何ですか: "Armadillo" は... "Zodiac"より大きいですか、それ以下ですか?

答えは、より大きい、より小さい、等しいの定義によって異なります。文字列の通常の順序は、辞書で後に出現する単語が前に出現する単語よりも大きくなるというものです。

CompareTo は並べ替えにどのように役立ちますか?

これで、任意の 2 つのオブジェクトを比較する方法がわかりました。これは多くのアルゴリズムで役立ちますが、ほとんどの場合、並べ替えと順序付けのアルゴリズムです。たとえば、非常に単純なソート アルゴリズム、愚かなソートを考えてみましょう。アイデアは次のとおりです。

配列内の 2 つの隣接する要素 A と B を見てください
。A <= B の場合: 次のペアに進みます。
A > B の場合: A と B を入れ替えて、前のペアに戻ります。
最後まで来たら終わりです。

並べ替えを行うには、2 つの要素のうちどちらが大きいかを判断する方法が必要です。そこでIComparable<T>出番です。

public static void StupidSort<T>(T[] array)
            where T : IComparable<T>
{
    int index = 0;
    while (index < array.Length)
    {
        if (index == 0 ||
            array[index - 1].CompareTo(array[index]) <= 0)
        {
            index++;
        }
        else
        {
            Swap(array, index - 1, index);
            index--;
        }
    }
}

CompareTo が常に 1 を返すとどうなりますか?

もちろん、必要なものを返すようにプログラムCompareToすることもできます。しかし、失敗すると、あなたのメソッドは何をthisするのobjかという質問に答えなくなります。常に 1 を返すということは、任意の A と B について、A が常に B よりも大きいことを意味します。これは、20 は 10 よりも大きく、10 は20よりも大きいと言っているようなものです。 do も意味がありません。ガベージイン...ガベージアウト。

ゲームのルールは、与えられた 3 つのオブジェクト A、B、C について次のとおりです。

  • A.CompareTo(A)0 を返す必要があります ( A は A と等しい)。
  • 0 を返す場合A.CompareTo(B)は 0 をB.CompareTo(A)返します ( A が B と等しい場合、 B は A と等しくなります)。
  • IfA.CompareTo(B)は 0 をB.CompareTo(C)返し、0 を返し、次に 0 をA.CompareTo(C)返します ( A が B と等しく、B が C と等しい場合、A は C と等しくなります)。
  • IfA.CompareTo(B)は 0 より大きい値をB.CompareTo(A)返し、次に 0 より小さい値を返します ( A が B より大きい場合、 B は A より小さい)。
  • IfA.CompareTo(B)は 0 より小さい値をB.CompareTo(A)返し、次に 0 より大きい値を返します ( A が B より小さい場合、 B は A より大きい)。
  • IfA.CompareTo(B)は 0 よりも大きい値をB.CompareTo(C)返し、0 よりも大きい値を返し、次に 0 よりも大きい値をA.CompareTo(C)返します ( A が B よりも大きく、B が C よりも大きい場合、 A は C よりも大きくなります)。
  • IfA.CompareTo(B)は 0 未満の値をB.CompareTo(C)返し、0 未満の値を返し、0 未満の値をA.CompareTo(C)返します ( A が B 未満であり、B が C 未満の場合、A は C 未満です)。
  • nullは常に、null 以外のオブジェクトよりも小さくなります。

実装がこれらの (単純で論理的な) 原則に準拠していない場合、並べ替えアルゴリズムは文字通り何でもでき、期待した結果が得られない可能性があります。

于 2013-03-05T23:03:11.793 に答える
0

aと比較したいときはb、次のように言います。

int result=a.CompareTo(b);

つまり、最初の比較オペランドはthisで、2 番目の比較オペランドは関数に渡されるパラメーターです。

次に、配列をソートするときは、使用するアルゴリズムに関係なく、要素を比較して、それらを asthisおよびobjto object.CompareTo(またはこの関数の実行可能なオーバーロード) に送信する必要があります。

于 2013-03-05T20:23:45.783 に答える
0

つまり、Sort は ArrayList の 2 つの要素を取り、最初の要素に対して CompareTo を呼び出し、次のように 2 番目の要素を引数として渡します。

element1.CompareTo(element2)

CompareTo は、element1 が element2 より小さい場合は負の値を返し、等しい場合は 0、そうでない場合は正の値を返します。Sort はこの戻り値を使用して、ええと、何らかのソートを行います。次に、次の 2 つの要素に対してこのプロセスを繰り返し、さらに並べ替えを行い、ArrayList が並べ替えられるまで繰り返します。このプロセスの詳細については、「ソート アルゴリズム」を検索してください。

于 2013-03-05T20:25:22.380 に答える
0

並べ替え方法は方法に依存しませんCompareTo。どのソートアルゴリズムが使用されているかはわかりませんが、クイックソートのようなものだと思います(明らかにバブルソートではありません)。これらのアルゴリズムに興味がある場合は、ウィキペディアで詳細に説明されています。

このCompareToメソッドは、同じタイプのオブジェクトを比較する手段にすぎません。最初は一般的な .NET 型の多くに対して定義されており、オーバーライドしてカスタム オブジェクト (作成したもの) 間の比較を行うことができます。基本的に、タイプ A のオブジェクトから呼び出して、タイプ A の 2 番目のオブジェクトを渡します。戻り値は、2 つが等しいか、または一方が他方より大きいかを示します。

CompareToユーティリティ関数と考えるのが最善です。これは、一般的な .NET データ構造で提供される並べ替え方法を使用してカスタム比較を行うために存在します。そのようなものがなければ、作成した型を比較す​​るためにソート アルゴリズムを自分で作成する必要があります。その目的は、ソート方法を再利用可能/拡張可能にすることです。

于 2013-03-05T20:30:49.057 に答える