Exemple #1
0
        /// <summary>
        /// 移動先の点のベクトルを計算
        /// </summary>
        /// <param name="vMinus">下の斜線上の点</param>
        /// <param name="vPlus">右の斜線上の点</param>
        /// <returns>移動先の点</returns>
        protected static Vector Move(Vector vMinus, Vector vPlus)
        {
            V_PARAMETER param = GetVStatus(vMinus, vPlus);
            Vector result = new Vector();

            switch (param) {
                //vに何も定義されていない場合は左上になります。
                case V_PARAMETER.V_INIT:
                    result.Set(
                        0,
                        0,
                        new Vector(0, 0, null));
                    break;

                //右の斜線上の点を採用する場合。下に移動します。
                case V_PARAMETER.V_X:
                    result.Set(
                        vPlus.fX,
                        vPlus.fY + 1,
                        vPlus);
                    break;

                //下の斜線上の点を採用する場合。右に移動します。
                case V_PARAMETER.V_Y:
                    result.Set(
                        vMinus.fX + 1,
                        vMinus.fY,
                        vMinus);
                    break;
            }

            return result;
        }
        /// <summary>
        /// O(ND)アルゴリズムの処理
        /// </summary>
        /// <param name="dest">変更後のセル範囲</param>
        /// <param name="src">変更前のセル範囲</param>
        /// <returns>解析結果の最終位置ベクトル</returns>
        protected static Vector GetEndPoint(Excel.Range dest, Excel.Range src)
        {
            //配列vはそれぞれの斜線上の点の位置を表します。
            Vector[] v = new Vector[dest.Count + src.Count + 3];
            for (int i = 0; i < v.Length; ++i) {
                v[i] = null;
            }

            int offset = src.Count + 1;

            List<int[]> cellList1 = new List<int[]>();
            foreach (Excel.Range cell in dest) {
                int[] tmp = { cell.Row, cell.Column };
                cellList1.Add(tmp);
            }

            List<int[]> cellList2 = new List<int[]>();
            foreach (Excel.Range cell in src) {
                int[] tmp = { cell.Row, cell.Column };
                cellList2.Add(tmp);
            }

            //Dを1ずつ増やしてループします。
            for (var d = 0; d <= dest.Count + src.Count; d++) {
                //斜線kをどこからどこまで調べる必要があるかを決めます。
                int k_max = (d <= dest.Count) ? d : (dest.Count - (d - dest.Count));
                int k_min = (d <= src.Count) ? d : (src.Count - (d - src.Count));

                for (var k = -k_min; k <= k_max; k += 2) {
                    int index = offset + k;

                    //移動先の点を計算
                    Vector result = Move(v[index - 1], v[index + 1]);

                    //縦と横の文字が同じ場合は斜めに移動できます。移動できるだけ移動します。
                    while (((result.fX < dest.Count) && (result.fY < src.Count))
                            && (Convert.ToString(dest[cellList1[result.fX][0], cellList1[result.fX][1]].Value)
                            == Convert.ToString(src[cellList2[result.fY][0], cellList2[result.fY][1]].Value))) {
                        result.fX++;
                        result.fY++;
                    }

                    //配列vにxとyと移動元の点(parent)を格納します。
                    if (v[index] == null) {
                        v[index] = new Vector();
                    }

                    v[index].Set(result.fX, result.fY, result.fParent);

                    //右下にたどりついたらその点を返します。
                    if ((dest.Count <= result.fX) && (src.Count <= result.fY)) {
                        return v[index];
                    }
                }
            }

            return null;
        }
        /// <summary>
        /// O(ND)アルゴリズムの処理
        /// </summary>
        /// <param name="dest">変更後の文字列</param>
        /// <param name="src">変更前の文字列</param>
        /// <returns>解析結果の最終位置ベクトル</returns>
        protected static Vector GetEndPoint(string dest, string src)
        {
            //配列vはそれぞれの斜線上の点の位置を表します。
            Vector[] v = new Vector[dest.Length + src.Length + 3];
            for (int i = 0; i < v.Length; ++i) {
                v[i] = null;
            }

            int offset = src.Length + 1;
            int k_min, k_max, d, k, index;

            //Dを1ずつ増やしてループします。
            for (d = 0; d <= dest.Length + src.Length; d++) {
                //斜線kをどこからどこまで調べる必要があるかを決めます。
                k_max = (d <= dest.Length) ? d : (dest.Length - (d - dest.Length));
                k_min = (d <= src.Length) ? d : (src.Length - (d - src.Length));

                for (k = -k_min; k <= k_max; k += 2) {
                    index = offset + k;

                    //移動先の点を計算
                    Vector result = Move(v[index - 1], v[index + 1]);

                    //縦と横の文字が同じ場合は斜めに移動できます。移動できるだけ移動します。
                    while (((result.fX < dest.Length)
                            && (result.fY < src.Length))
                            && (dest[result.fX] == src[result.fY])) {
                        result.fX++;
                        result.fY++;
                    }

                    //配列vにxとyと移動元の点(parent)を格納します。
                    if (v[index] == null) {
                        v[index] = new Vector();
                    }

                    v[index].Set(result.fX, result.fY, result.fParent);
                    //System.Diagnostics.Debug.WriteLine(index + "," + result.fX + "," + result.fY + "," + result.fParent.fX + "," + result.fParent.fY);

                    //右下にたどりついたらその点を返します。
                    if ((dest.Length <= result.fX) && (src.Length <= result.fY)) {
                        return v[index];
                    }
                }
            }

            return null;
        }
        /// <summary>
        /// O(ND)アルゴリズムによる変更解析結果から変更解析結果文字列を生成
        /// </summary>
        /// <param name="dest">変更後の文字列</param>
        /// <param name="src">変更前の文字列</param>
        /// <returns>変更解析結果文字列</returns>
        public static RevString GetDiffStringOND(string dest, string src)
        {
            Vector parent = new Vector();
            RevString revStr = new RevString();
            int x, y, minLen;

            //O(ND)アルゴリズムの実行
            Vector point = GetEndPoint(dest, src);

            while (point.fParent != null) {
                parent = point.fParent;
                x = point.fX - parent.fX;
                y = point.fY - parent.fY;
                minLen = Math.Min(x, y);

                //変化なし
                for (var i = 0; i < minLen; i++) {
                    revStr.Push(
                        dest[point.fX - i - 1],
                        REVISION_KIND.SAME);
                }

                //追加
                if (y < x) {
                    revStr.Push(
                        dest[parent.fX],
                        REVISION_KIND.INSERT);
                }
                //削除
                else if (x < y) {
                    revStr.Push(
                        src[parent.fY],
                        REVISION_KIND.DELETE);
                }

                point = parent;
            }

            return revStr;
        }
Exemple #5
0
        /// <summary>
        /// 斜線kで、下の斜線上の点か、右の斜線上の点か、どちらから移動するかを決める関数です。
        /// より右にあるほうを採用します。
        /// </summary>
        /// <param name="vMinus">下の斜線上の点</param>
        /// <param name="vPlus">右の斜線上の点</param>
        /// <returns>移動方向を規定する列挙型変数</returns>
        private static V_PARAMETER GetVStatus(Vector vMinus, Vector vPlus)
        {
            //vに何も定義されていない場合
            if ((vMinus == null) && (vPlus == null)) {
                return V_PARAMETER.V_INIT;
            }

            //下の斜線上の点がない場合
            if (vMinus == null) {
                return V_PARAMETER.V_X;
            }

            //右の斜線上の点がない場合
            if (vPlus == null) {
                return V_PARAMETER.V_Y;
            }

            //2つの点の内、より右にあるほうを採用
            if (vMinus.fX < vPlus.fX) {
                return V_PARAMETER.V_X;
            } else {
                return V_PARAMETER.V_Y;
            }
        }
Exemple #6
0
 /// <summary>
 /// フィールド設定関数
 /// </summary>
 /// <param name="x">fXの設定値</param>
 /// <param name="y">fYの設定値</param>
 /// <param name="parent">fParentの設定値</param>
 public void Set(int x, int y, Vector parent)
 {
     fX = x;
     fY = y;
     fParent = parent;
 }
Exemple #7
0
 /// <summary>
 /// コンストラクタ
 /// </summary>
 /// <param name="x">fXの初期値</param>
 /// <param name="y">fYの初期値</param>
 /// <param name="parent">fParentの初期値</param>
 public Vector(int x, int y, Vector parent)
 {
     Set(x, y, parent);
 }
Exemple #8
0
 /// <summary>
 /// コンストラクタ(x,yを0に、parentをnullに初期化)
 /// </summary>
 public Vector()
 {
     fX = 0;
     fY = 0;
     fParent = null;
 }