0

2 つのバイナリ データ セットの違いを比較するソフトウェアを作成しています。バイナリ データには座標が含まれており、DBF ファイルから読み取って各オブジェクトの属性情報を取得します。私のソフトウェアは、オブジェクトが移動したかどうか、属性が変更されたかどうか、オブジェクトが削除/追加されたかどうかを示します。

カスタム オブジェクトのハッシュコードは、各インスタンス内の座標のリストに基づいて生成されます。各オブジェクトにはデータ行もあります。最初に「不完全なレコード」(基本的には、座標とデータ行に基づいて一致しないオブジェクト) を見つけようとすると、データ行が考慮され、データ行が十分に一意になるため、HashSet を使用できます。

public override int GetHashCode()
    {

        if (considerAttrs)
        {
            return (value.GetHashCode() + dbString.GetHashCode());
        }
        else
        {
            return value.GetHashCode();
        }

    }

わたしはどこにいますか:

現時点では、ソフトウェアは完全に一致しない (座標と属性が完全に一致しない) オブジェクトを返します。このデータは正しいです (少なくとも私は願っています)

origUnfoundCount: 114 modUnfoundCount: 223

113 の属性が変更され、1 が移動されたため、元の 114 は見つかりません。113 の変更された属性があり、1 が移動され、109 が追加されたため、変更された属性で 223 を見つけることができません。

私が立ち往生している場所:

このソフトウェアは、小さなデータ (各リストで数百) を美しく処理します。

各オブジェクトの thinkAttrs を false に変更し、HashSet の代わりに List を使用しました。私のアプリケーションの点では、データ間の小さな違いを比較するのにしか適していません。

ただし、ハッシュセットに重複を含めることはできないため、リストを使用する必要がありますが、リストは遅くなるだけです。キーは一意でなければならないため、辞書は使用できません

私は新しいアプローチが必要です。以下の私のロジックは、私がそれを行うために必要なことの一般的な要点を提供するはずです.

私の現在の比較コード

    //ignored modified records
    HashSet<int> ignoredRecNo = new HashSet<int>();
    //ignoring moved records
    HashSet<String> ignoredDBstrings = new HashSet<string>();

    HashSet<String> columnNames = new HashSet<string>();
    HashSet<int> modModdedRNs = new HashSet<int>();
    columnNames = (HashSet<String>)HttpContext.Current.Session["columnNames"];

    List<PolyLineZ> originalNFs = new List<PolyLineZ>();
    List<PolyLineZ> modifiedNFs = new List<PolyLineZ>();

    List<PolyLineZ> removedList = new List<PolyLineZ>();
    List<PolyLineZ> movedList = new List<PolyLineZ>();
    List<PolyLineZ> modifiedList = new List<PolyLineZ>();
    List<PolyLineZ> modifiedMatchList = new List<PolyLineZ>();

    List<PolyLineZ> movedOrDeleted = new List<PolyLineZ>();

    if (HttpContext.Current.Session["origNFList"] != null)
    {
        origPolyLineZNFList = (HashSet<PolyLineZ>)HttpContext.Current.Session["origNFList"];
    }

    if (HttpContext.Current.Session["modNFList"] != null)
    {
        modPolyLineZNFList = (HashSet<PolyLineZ>)HttpContext.Current.Session["modNFList"];
    }


    //----------Generate Lists of string for each row---------------//
    foreach (PolyLineZ polyLineZ in origPolyLineZNFList)
    {
        origDBStrings.Add(polyLineZ.dbString);
        PolyLineZ temp = new PolyLineZ();
        temp = polyLineZ;
        temp.considerAttrs = false;
        originalNFs.Add(temp);
    }

    foreach (PolyLineZ polyLineZ in modPolyLineZNFList)
    {
        modDBStrings.Add(polyLineZ.dbString);
        PolyLineZ temp = new PolyLineZ();
        temp = polyLineZ;
        temp.considerAttrs = false;
        modifiedNFs.Add(temp);
    }


    foreach (PolyLineZ modpolyLineZ in modifiedNFs)
    {
        bool foundAmatch = false;
        foreach (PolyLineZ origPolyLineZ in originalNFs)
        {
            if (origPolyLineZ.Equals(modpolyLineZ))
            {
                if (!modDBStrings.Contains(origPolyLineZ.dbString))
                {
                    //database modifications are in here                        
                    modModdedRNs.Add(origPolyLineZ.RecordNumber);
                    foundAmatch = true;
                    break;
                }
            }
        }

    }

    foreach (PolyLineZ polyLineZ in originalNFs)
    {
        bool foundAmatch = false;
        foreach (PolyLineZ modpolyLineZ in modifiedNFs)
        {
            if (foundAmatch)
            {
                break;
            }
            if (modpolyLineZ.Equals(polyLineZ))
            {
                if (!origDBStrings.Contains(modpolyLineZ.dbString))
                {

                    foundAmatch = true;
                    //database modifications are in here                            
                    ignoredRecNo.Add(modpolyLineZ.RecordNumber);
                    ignoredDBstrings.Add(modpolyLineZ.dbString);
                    modifiedList.Add(polyLineZ);
                    modifiedMatchList.Add(modpolyLineZ);
                    break;

                } // end db string comparison

            } //end shape equals if

        } //end modNF loop

        if (!foundAmatch)
        {
            movedOrDeleted.Add(polyLineZ);
            ignoredDBstrings.Add(polyLineZ.dbString);
            ignoredRecNo.Add(polyLineZ.RecordNumber);
        }

    } //end origNF loop


    result += "movedDeletedCount: " + movedOrDeleted.Count + "<br/>";
    foreach (PolyLineZ polylineZ in movedOrDeleted)
    {

        if (!modDBStrings.Contains(polylineZ.dbString))
        {
                removedList.Add(polylineZ);
        }
        else
        {

                movedList.Add(polylineZ);   
        }
    }

    /*************************** ITERATE DATABASE CHANGES***********************************/
    for(int i=0; i < modifiedList.Count;i++)
    {
        if (modModdedRNs.Contains(modifiedList[i].RecordNumber))
        {
            if (modifiedAttrs < 1001)
            {
                //database modifications are in here                            
                ignoredRecNo.Add(modifiedMatchList[i].RecordNumber);
                ignoredDBstrings.Add(modifiedMatchList[i].dbString);
                modifiedAttrs++;
                modifiedResults += "<div class='turnBlue'>";
                //show where the change was made at
                modifiedResults += "Change Detected at original FID# " + (modifiedList[i].RecordNumber - 1) + " and modified FID#";
                HashSet<String> mismatchedColumns = new HashSet<String>();
                modifiedResults += (modifiedMatchList[i].RecordNumber - 1);
                modifiedResults += "</div>"; //end turnblue div
                DataRow origRow = modifiedList[i].datarow;
                DataRow modRow = modifiedMatchList[i].datarow;
                foreach (String columnName in columnNames)
                {
                    String origRowValue = "" + origRow.Field<Object>(columnName);
                    String modRowValue = "" + modRow.Field<Object>(columnName);
                    if (!modRowValue.Equals(origRowValue))
                    {
                        mismatchedColumns.Add(columnName);

                    }
                }
                foreach (String mismatchedColumn in mismatchedColumns)
                {

                    //grab original attr value
                    String origMismatchedRowValue = "" + origRow.Field<Object>(mismatchedColumn);
                    //grab the modified value
                    String modMismatchedRowValue = "" + modRow.Field<Object>(mismatchedColumn);
                    //generate a heading, letting the user know about the situation
                    modifiedResults += "<div class='turnBlue'>Value at Column: &nbsp;<b>" + mismatchedColumn + "</b> has been modified<br/>";
                    modifiedResults += "<div class='pushLeft'>Original value: &nbsp;<b>" + origMismatchedRowValue + "</b><br/></div>";
                    modifiedResults += "<div class='pushLeft'>Modified value: &nbsp;<b>" + modMismatchedRowValue + "</b><br/></div>";
                    modifiedResults += "</div>"; //end modified div 
                }
            }
            else
            {
                modifiedAttrs++;
            }


        }
        else
        {
            if (removed < 1001)
            {
                //iterate removed data here
                removed++;
            }
            else
            {
                removed++;
            }

        }
    }
    //****************************this determines which ones have been added ***************************/

    foreach (PolyLineZ modpolyLineZ in modifiedNFs)
    {
        if (!ignoredRecNo.Contains(modpolyLineZ.RecordNumber) && (!ignoredDBstrings.Contains(modpolyLineZ.dbString)))
        {
            //iterate added data here
        }

    }

    foreach (PolyLineZ polylineZ in removedList)
    {
        //iterate removed data here
    }
    foreach (PolyLineZ polylineZ in movedList)
    {
        //iterate  moved data here

    }

    result += "<div id='addedJump'></div>" + addedResult;
    result += "<div id='moddedJump'></div>" + modifiedResults;
    result += "<div id='removedJump'></div>" + removedResults;
    result += "<div id='movedJump'></div>" + movedResults;

}

4

1 に答える 1

0

すべてのデータを単一の文字列に追加することから、stringbuilder の使用に切り替えました...

削除された 3,200 件のレコードを検出するのに 30 分かかっていた私のプログラムは、7 秒フラットまで短縮されました。

詳細については、この質問を参照してください。

文字列と StringBuilder

于 2013-07-19T17:47:41.267 に答える