web-dev-qa-db-ja.com

多くの言語で比較関数からの戻り値が大まかに定義されているのはなぜですか?

多くの言語では、比較関数は負の値、ゼロ、または正の値を返す必要があると定義されています。 -1 0と1として明確に定義されるべきではない理由はありますか?可能な戻り値の範囲が広いと、より高度なアルゴリズムがより効率的に機能するのに役立ちますか?もしそうなら、どのアルゴリズムがこのように機能しますか?

4
Shane

比較関数が正確に-1ではなくany負の値を返すことを許可すると、実装が簡単になります。たとえば、あなたは書くことができます

return this.position - that.position;

書く代わりに

if(this.position == that.position) {
    return 0;
}
else if(this.position < that.position) {
    return -1;
} else
    return 1;
}

(別の方法は、Perlの<=>のように、正確に-1、0、または1を生成する演算子を使用することです。ただし、言語に新しい演算子を組み込むよりも、寛大なAPIを定義する方が簡単です。ラリーウォール。)

7
Kilian Foth

単純な使用例の場合、非常に簡単な実装が可能です。

_public int compare(Child a, Child b) {
    return a.age - b.age;
}
//sort children by age to determine who babysits 
_

一方、より複雑なロジックが必要な場合でも、順序が決まったら、マジックナンバー_-1_、_0_、または_1_を返すのは簡単です。


CodesInChaosがコメントで述べているように、減算メソッドは発生する可能性のあるオーバーフローに対応できません。汎用ライブラリは、比較においてより高い堅牢性と複雑さを必要とします。

戦闘でテストされた実装のいくつかを次に示します。

  1. Javaの Integer.compare()

    _public static int compare(int x, int y) {
        return (x < y) ? -1 : ((x == y) ? 0 : 1);
    }
    _
  2. モノの Int32.CompareTo()

    _public int CompareTo (object value)
    {
        if (value == null)
            return 1;
    
        if (!(value is System.Int32))
            throw new ArgumentException (Locale.GetText ("Value is not a System.Int32"));
    
        int xv = (int) value;
        if (m_value == xv)
            return 0;
        if (m_value > xv)
            return 1;
        else
            return -1;
    }
    _

ご覧のとおり、これらの両方が必要なロジックを適用してから、適切なマジックナンバーを返します。

3
Kelly Thomas

戻り値のセマンティクスは、実装とはほとんど関係がありません。この仕様は、不特定の動作のためのスペースを残さず、静的に検証可能です。

戻り値が任意の数に指定されている場合、これは静的にチェックできます。コンパイラは、関数が文字列を返さないことを簡単に確認できます。そうしないと、静的検証が不可能になります。指定された範囲外の値は、列挙型以外の場合は静的に削除できません。したがって、呼び出しコードは実行時に不特定の値を処理する必要があり、より不特定の動作を放出します。

この決定は、Jörgのコメントで説明されている動作を模倣するために行われたと言っても過言ではありません。完全な仕様であり、すべてのオプションがカバーされています。

0
Basilevs