2つのノードが同じであるかどうか、つまり、同じ数の子があり、それらの子がまったく同じ状態になるかどうかを確認しようとしています。したがって、私は2つのノードのサブツリーを効果的に比較しようとしています。ハッシュを使用してこの同等性チェックを実行できるかどうか疑問に思っています。
いいえ、同等性をチェックするためにハッシュを使用しないでください。それはその目的ではありません。最終的には、オブジェクトが等しくないかどうかを確認するのに役立ちますが、オブジェクトが等しいかどうかはわかりません。
同じオブジェクトは同じハッシュ値を生成しますが、等しくない2つの異なるオブジェクトも同じハッシュを生成できます。つまり、ハッシュ値が異なる場合は、オブジェクトが異なることを確実に知っています。それでおしまい。
同等性をテストする場合は、同等性を実装する必要があります。あなたの場合、あなたのメソッドが再帰的になり、スタックオーバーフローを引き起こす危険があります。オブジェクトにそれ自体への参照が含まれている場合はどうなりますか?
ハッシュを生成する場合は、配列のサイズ(およびそれがnullであるかどうか)を考慮に入れることができますが、可能性があるため、配列内のオブジェクトのハッシュ値を使用しようとはしません。無限ループ。完璧ではありませんが、十分です。
良い結果をもたらすかもしれない別の根本的な方法もあります。ハッシュ値を動的に計算する代わりに、ノードオブジェクトインスタンスごとにランダムなint値を設定します(つまり、作成時に一度だけ、常にその値を返します)。あなたの場合、配列内のオブジェクトインスタンスのハッシュ値を取得することで無限ループのリスクを冒すことはありません。
ハッシュが等しい場合は、配列オブジェクトインスタンスの比較を開始する必要があります。
REM:ノードに他の属性が含まれている場合は、これらの他の属性のハッシュを計算し、配列を忘れてください。ハッシュが2つのオブジェクト間で同一である場合に限り、配列のコンテンツ/サイズについて調査を開始します。
REM2:コメントにはDAGグラフが記載されています。これは、再帰性の問題が発生しないことを意味します。ただし、その条件は、deepHashCode()が成功することを保証するのに十分ではありません。さらに、それもやり過ぎでしょう。この問題を解決するためのより効率的な方法があります。
Nodeが使用するハッシュメソッドが配列のみを使用してハッシュ値を計算する場合、deepHashCode()が機能する可能性があります。しかし、それは効率的ではありません。ハッシュメソッドが他のノード属性を使用する場合、これらの属性も等しくなければなりません。
ノードの同等性を比較するより高速な方法があります。各ノードインスタンスに一意の番号を付けます。次に、2つのノードを比較するには、最初にそれらの配列サイズを比較します。等しい場合は、一意の番号を使用して各アレイのノードを比較します。一方の配列にもう一方のノードがない場合は、等しいノードを処理していません。このソリューションは、再帰的に実行するよりもはるかに高速です。