これは、GetHashCodeをオーバーライドするための他の答えと少し似ていますが、私には別のアプローチがあります。式には文字列表現があるように見えるので...。
GetHashCodeをオーバーライドできません。オーバーライドでは、
foreach(char c in ToString().ToCharArray()){
int hashCode |= c;
}
この結果、方程式のシンボルをパックした表現である4バイトのコードが生成されます。
各シンボルにHashTableで検索できる特定のOpCodeがある場合、これはさらに進む可能性があります。
各SymbolがプロパティOpCodeを宣言する必要がないように、各OpCodeのエイリアスを使用してHashTableを構築します。
次に、上記のHashTableでルックアップを実行したSymbolクラスで拡張ToOpCodeを作成します。
次に、GetHashCodeのExtensionメソッドを利用します。
方式....
public override int GetHashCode(){
foreach(Symbol c in Symbols){
int hashCode |= c.ToOpCode();
}
}
シンボル....
public override int GetHashCode(){
retuurn Extensions.ToOpCode(this);
}
この実装では、a+bとb+aに対して同じハッシュが生成されます。これは、質問ごとに非常に重要です...
さらに、OpCodeを正しく連続して指定した場合、技術的には次の形式で方程式を比較できます。
(a) + (b)
==(a+b)
これは、括弧OpCodesに数値とは異なる場所のHashCodeの値が指定されていることを確認することで実現されます...
たとえば、4バイト(整数)の場合、スコープの深さは最初のバイトに保持でき、スタック内の前または次の方程式/シンボルへのインデックスは次になり、次の2バイトは符号データと方程式の値/継続または変数の数(排他的)。
これにより、ネストレベルの数などの特定の情報を伝えることができるため、基本的にEqualsをオーバーライドして、必要に応じa + b
てとb + a
を区別できるようになります((a) + (b))
。
たとえば、方程式が特定の方法でまったく同じであるかどうかを知りたい場合がありますが、別の方法では、方程式が同じことを行っているが、まったく同じ方法で記述されていないかどうかを知りたい場合があります。
これにより、ハッシュコードに基づいて単純に仮定するのではなく、スコープの深さが一致するかどうか、方程式にまったく同じステップ数があるかどうかを確認するなど、さまざまな方法で同等性を判断することもできます。
たとえば、次のようにシフトして、次のようなものを決定できます。
hash<<8はparensの部門になりますhash<<16はスタックハッシュの前または次の方程式のポインターになります<<24は、方程式の符号またはコード値の連続または変数の数になります(排他的)
hash == anotherHashを実行することもできますが、この方法では、文字通りオーバーヘッドがなく、柔軟性が大幅に向上します。
ハッシュにさらにスペースが必要な場合は、longを返す新しいメソッドGetExtendedHashCodeを作成してから、シフト/ダウンキャストするか、GetHashCodeのExtendedHashCodeを再フォーマットして、CLRで必要なint形式に一致させます。
また、シンボルをスタックに残し、CLRと同じように使用することで、この方法で変数と値を表すことができるという利点もあります。