2011-05-13 20 views
2

あるメモリブロックを別のメモリブロックと比較し、目的の値を提供するアルゴリズムを書いて、一致の品質を判断したいと考えています。私はmemcmpを調査しました.2つのメモリブロックが同じかどうかを判断するのは本当に便利です。私はこれを達成するために再帰的な関数を書いていますが、それは正しく動作していません。客観的なメモリ比較

DWORD CMemory::Compare(LPBYTE pDst, LPBYTE pSrc, DWORD len) 
{ 
    DWORD dwDiff; 

    if (len == 0) 
    { 
     dwDiff = 0; 
    } 
    else 
    { 
     dwDiff = (*pSrc - *pDst) * len; // * len is attempt to weight difference by MSB 
     dwDiff += this->Compare(pSrc + 1, pDst + 1, len - 1); 
    } 

    return dwDiff; 
} 

2つのメモリ空間が一致するほど、戻り値は低くなります。たとえば、Hello World 0 !,Hello World 1 !、およびHello World 2 !を含む3つのメモリブロックがあり、いずれのメモリブロックが候補hello world 1 !と「最善の一致」であるかを調べたいとします。考え方は、Compare関数を各メモリブロックと候補を順番に比較して3回実行し、CompareHello World 1 !を含むメモリブロックの最小値を返します。しかし、現実には、Hellow World 2 !を含む最後のメモリブロックの最小値が返されます。

私はこの機能をどのように改善することができますか?ありがとう。

+0

このメソッドはどのように呼び出しますか? –

+1

なぜハミング距離はありませんか? http://en.wikipedia.org/wiki/Hamming_distance –

+0

@ c-smile:提案(+1)ありがとう!私はハミング距離を使用するアルゴリズムを書き直しましたが、今はうまくいっています! –

答えて

3

(*pSrc - *pDst)の絶対値をとる必要があると思います。 「Hello World 1!」では、「Hello World 2!」では数字の位置が0になります。あなたは-1を返し、-1は0未満です。

また、これをメモリの長いセクションで使用すると、スタックの問題に遭遇する可能性があるため、反復的にすることができます。

あなたのアルゴリズムは、位置比較によって位置を決定するため、挿入または削除された文字を考慮しません。あなたがそれについて心配しているなら、問題はもっと困難になります。

+1

+1、加えて挿入と削除について言及する余分な道徳的ポイントは、このアルゴリズムが領域の残りの部分がまったく異なっていると考えるようにします。そこには、この種のものを補償しようとするdiffアルゴリズムがありますが、それはやりにくく、簡単ではありません。'diff'ディスプレイが同期しなくなり、ばかげた" diff "の表示を開始したことがあるなら、あなたは私が何を話しているのか知っています。 –

+0

「Hello World 1!」と "こんにちは世界1!"同等ではない。つまり、 '' H ' - ' h '!= 0'です。しかし、あなたは絶対値で何かにいるかもしれません。私の全体的なアルゴリズムが現在構造化されている方法は絶対値は 'Compare'の最終的な戻り値から決定されます。私があなたを正しく理解していれば、それが合計に加算される前に、それぞれの差異の絶対値をとるべきです。 –

+1

@ Jim Fell:しかし、Hの違いは "Hello World 1!"と同じです。と "Hello World 2!"と比較して違いはありません。はい、あなたはそれぞれの差異の絶対値を取るべきです。 –

0

文字列を比較する場合は、soundexを調べるとよいでしょう。

+0

必ずしも文字列ではありません。私は、コンソールから入力して表示するのが最も簡単なので、文字列( 'char []')を使ってテストしています。一度、これは動作している、それはバイナリデータを比較することになります。 –

2

書き込むと考えられるabs(* pSrc- * pDst)?そうでなければ、完全一致(0)よりも常に低い負の値が得られます。

1

これを改善するには...

送信元と送信先の両方の長さを指定します。 ソースと宛先のnバイトを比較するために値 'n'を指定します。 送信元と送信先が同じサイズでない場合、または終了時に問題が発生する場合は、ケースを処理する必要があります。

本当に小さなメモリブロックを扱っている場合を除き、再帰は使用しないでください。 ループを使用するだけで同じ作業を行うことができます。 このメソッドは実際に呼び出すには本当に高価です。

+0

提案していただきありがとうございます! –