C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[2]: C#でDF.exeのような比較ツール作成での改行判断


(過去ログ 83 を表示中)

[トピック内 14 記事 (1 - 14 表示)]  << 0 >>

■49367 / inTopicNo.1)  C#でDF.exeのような比較ツール作成での改行判断
  
□投稿者/ 初心者 (121回)-(2010/05/02(Sun) 09:10:00)

分類:[.NET 全般] 

使用言語 C#.NET 

■ファイル比較方法について

同一ファイル名.javaの内容比較を行う際、文字列比較は、下記『パターン1』の処理で可能です。
『パターン1』:Aファイルを一行読み、FOR文でBファイル同一文字列行があるかの判断をすることの繰り返しで行えます。
『パターン2』:Aファイルを一行読み、次にBファイルも一行読む方法では、正確な差分結果がでません。
  
*しかし、改行のみの行となるといくつもファイル中に存在し、パターン1の判断ではどの行に改行が増えたかのかの判断がつきません。
この場合、どのようなアルゴリズムを加えたらよいのかわかりません。
現在、DF.exeのオプション→比較方法→同値行が少ない用(最初から)(高速)でアルゴリズムを調査していますが、検討がつきません。
最終的な比較結果は、DF.exeのオプション→比較方法→同値行が少ない用(最初から)(高速)の出力方法を求めています。
いまは、ただただDF.exeを開発した方のすごさを痛感しております。

ファイル比較方法のご教授をお願いします。
引用返信 編集キー/
■49370 / inTopicNo.2)  Re[1]: C#でDF.exeのような比較ツール作成での改行判断
□投稿者/ なっと (20回)-(2010/05/02(Sun) 10:40:15)
こんにちわ。

テキストファイルの比較による差分表示は、非常に難しいアルゴリズムだと聞いたことがありますが…。
掲示板で聞いてポンと答えが返ってくるのでしょうか。(^-^;

WinMarge のソースなら公開されているそうです。Diffのアルゴリズムと同じだという話ですが。

引用返信 編集キー/
■49385 / inTopicNo.3)  Re[1]: C#でDF.exeのような比較ツール作成での改行判断
□投稿者/ .SHO (1322回)-(2010/05/02(Sun) 20:57:49)
No49367 (初心者 さん) に返信
> 使用言語 C#.NET 
>
> ■ファイル比較方法について
>
> 同一ファイル名.javaの内容比較を行う際、文字列比較は、下記『パターン1』の処理で可能です。
> 『パターン1』:Aファイルを一行読み、FOR文でBファイル同一文字列行があるかの判断をすることの繰り返しで行えます。

これでは、Aファイルの一行がBファイルで削除されている場合、うまくいかないですよね?
ファイルの差分は、そんなに単純じゃないです。

引用返信 編集キー/
■49388 / inTopicNo.4)  Re[2]: C#でDF.exeのような比較ツール作成での改行判断
□投稿者/ れい (899回)-(2010/05/03(Mon) 00:30:40)
No49370 (なっと さん) に返信
> テキストファイルの比較による差分表示は、非常に難しいアルゴリズムだと聞いたことがありますが…。
> 掲示板で聞いてポンと答えが返ってくるのでしょうか。(^-^;

数学的には少し難しいかもしれませんが、
プログラム的にはそんな難しいものではないですよ。

ただ、「差分」というのが曖昧なので、
言葉の定義から入らないといけませんから、
「ポン」と返すのは難しい。

A,Bがあって、9割一致するときに。

「Aの内容を全部削除」して「Bの内容を全部追加」したとすればそれで
AからBを再現できますが、「差分」とは言えません。

「Aの内容を半分削除」して「Bの内容を半分追加」したとしたら
一応「差分」っぽいですが、まだまだ最適ではありませんよね。

「最も少ない編集」になるとうれしい。

で、「編集」ですが、

1 Aのn行目に「xxx\n」を挿入
2 Aのn行目に「yyy\n」を挿入

というのと

1 Aのn行目に「yyy\n」を挿入
2 Aのn+1行目に「xxx\n」を挿入

というのは「同じ結果」になります。
「同じ目的地に行くための、別の行き方」とみなせるわけです。

当然

1 Aのn行目に「xxx\n」を挿入
2 Aのn行目に「aaa\n」を挿入
3 Aのn行目を削除
4 Aのn行目に「yyy\n」を挿入

も、同じ結果になります。
(最後のパターンは明らかに「無駄な編集」が入っているので「差分」としてはよくないのですが。
これは「回り道」なわけです。

つまり、一連の編集は「経路」として捉えることが可能で、
経路は無限にあることがわかります。

文章の比較アルゴリズムは結局この無限にある編集経路のうち、
「最も短い経路」を探すアルゴリズムとなります。

ここまでわかればあとはただの経路探索アルゴリズムです。
「サラリーマン巡回」と違って「前に戻る」経路や「関係のない編集」は明らかに「無駄な編集」ですから、
初めから経路に選ぶ必要がありません。

つまりAをBに編集する経路において、
各編集における選択肢は「行追加」「行削除」の2通りしかないことがわかりますし、
頭から1行ずつ判定していけば十分であることがわかります。

ここまで考えた時点で探すべき経路数は2^N通りになります。(NはAの行数です
この経路をすべて虱みつぶしに探せば最短経路を探すことができます。

頭を使うとこれをもっと小さくできます。
いろいろ有名なアルゴリズムがありますが、それは検索でもすればすぐに見つかります。
理論上最短が保証されたアルゴリズムはまだ無かったと思いますが、本当のところは知りません。

昔、.Netにジェネリックが追加されたとき、
ジェネリックの勉強を兼ねて作った差分リストのコードを持っています。

提供しますので適当に使ってください。
引用返信 編集キー/
■49389 / inTopicNo.5)  Re[3]: C#でDF.exeのような比較ツール作成での改行判断
□投稿者/ れい (900回)-(2010/05/03(Mon) 00:52:08)
No49388 (れい さん) に返信
> 昔、.Netにジェネリックが追加されたとき、
> ジェネリックの勉強を兼ねて作った差分リストのコードを持っています。
>
> 提供しますので適当に使ってください。

提供しようとおもったんですが
10000文字しか書き込めない、ということなので無理でした。

8000文字x2に分割しても投稿できませんでした。

ソースは別に貼りつけられるといいんだけど。

欲しかったら言ってください。

引用返信 編集キー/
■49394 / inTopicNo.6)  Re[4]: C#でDF.exeのような比較ツール作成での改行判断
□投稿者/ 初心者 (122回)-(2010/05/03(Mon) 09:42:57)
No49389 (れい さん) に返信
> ■No49388 (れい さん) に返信
>
> ソースは別に貼りつけられるといいんだけど。
>
> 欲しかったら言ってください。
>

ご返信ありがとうございます。
是非、サンプルソースが欲しいです。
お手数ですが、下記のアドレスにお願いします。
t_kouji_1981@yahoo.co.jp

その後、ソースの解析をしたいと思います。

引用返信 編集キー/
■49395 / inTopicNo.7)  Re[5]: C#でDF.exeのような比較ツール作成での改行判断
□投稿者/ れい (902回)-(2010/05/03(Mon) 09:55:58)
No49394 (初心者 さん) に返信
>
> ご返信ありがとうございます。
> 是非、サンプルソースが欲しいです。
> お手数ですが、下記のアドレスにお願いします。
> t_kouji_1981@yahoo.co.jp
>
> その後、ソースの解析をしたいと思います。
>

んー
せっかく公開されてる掲示板なので
個人的にあげる、というのはもったいないですよね。

今から頑張って分割して貼ります。

以下のソースは
上で言ったように、ジェネリックの勉強用につくったので
「行」でかんがえるわけではなく、「任意のオブジェクトの配列」の差分情報を計算します。

アルゴリズムはMyersによるO(ND)タイプです。
今発見されているなかで最短というわけではありません。
デバッグは殆ど行っていません。

このくらいの長さになると著作権などを述べておいた方がいいかもしれませんね。

どこかからソースをコピペしたわけではありません。論文を読んでそこからソースを起こしました。
もちろんGNU系のソースを見てもいません。

ですので、著作権はもしかすると私に属するかもしれませんが、
アルゴリズムの「まんま」実装なので、私は著作権を主張しません。

他の厄介なライセンスの縛りもありませんので
いつでも誰でもどんな用途にでもご自由にお使いください。

参考文献:

E.W.Myers, "An O(ND) difference algorithm and its variations", Algorithmixa, 1 (1986), 251


引用返信 編集キー/
■49396 / inTopicNo.8)  Re[5]: C#でDF.exeのような比較ツール作成での改行判断
□投稿者/ れい (903回)-(2010/05/03(Mon) 09:57:01)
2010/05/03(Mon) 09:57:47 編集(投稿者)
using System;
using System.Collections;
using System.Collections.ObjectModel;
using System.Collections.Generic;
using System.Text;

namespace Rei {

    /// <summary>
    /// 二つのリストの変更情報を作成・保持するクラス。
    /// 非変更点も保持する場合は変更後のリストと変更前のリストの全ての情報を保持します。
    /// 非変更点を保持しない場合は、変更後のリストがあれば変更前のリストを、
    /// 変更前のリストがあれば変更後のリストを復元できます。
    /// オブジェクトの比較にはObject.Equals(A,B)を用います。
    /// </summary>
    public class DifferenceList<T> : IList<DifferenceList<T>.DifferenceListEntry> {

        #region private

        private List<DifferenceListEntry> _list;

        private bool _containsunchanged;

        /// <summary>
        /// +-のインデックスを取れるFPの配列
        /// </summary>
        private class FPList {
            List<FP> _list;
            int _delta;
            public FPList(int delta) {
                _delta = delta;
                _list = new List<FP>(_delta + 2);
                for (int i = 0; i <= _delta; i++) _list.Add(new FP());
            }
            public FP this[int index] {
                get {
                    if (index > _delta) index = _delta + (index - _delta) * 2;
                    else if (index < 0) index = _delta - index * 2 - 1;
                    while (index >= _list.Count) _list.Add(new FP());
                    return _list[index];
                }
            }
        }

        /// <summary>
        /// エディットパスと現在のyを保存するノード
        /// </summary>
        private class FP {
            public int value;
            public PathLink path;
            public FP() {
                value = -1;
                path = null;
            }
        }

        /// <summary>
        /// エディットパスを保存するための一方行リンクリスト
        /// </summary>
        private class PathLink {
            public PathLink previous;
            public ChangeType type;
            public PathLink(PathLink previous, ChangeType type) {
                this.previous = previous;
                this.type = type;
            }
        }

        private static bool snake(FPList fp, IList<T> A, IList<T> B, int k) {
            int x, y, y2;
            y = fp[k - 1].value + 1;
            y2 = fp[k + 1].value;
            if (y > y2) {
                fp[k].path = new PathLink(fp[k - 1].path, ChangeType.Deleted);
            } else {
                fp[k].path = new PathLink(fp[k + 1].path, ChangeType.Added);
                y = y2;
            }
            for (x = y - k; x < A.Count - 1 && y < B.Count - 1 && object.Equals(A[x + 1], B[y + 1]); ) {
                x++; y++;
                fp[k].path = new PathLink(fp[k].path, ChangeType.Unchanged);
            }
            if (x == A.Count - 1 && y == B.Count - 1) return true;
            fp[k].value = y;
            return false;
        }

        private DifferenceList() {
            _list = new List<DifferenceListEntry>();
            _containsunchanged = ContainsUnchanged;
        }

        #endregion

        /// <summary>
        /// 2つのリストの変更方法のリストを取得します。
        /// 変更内容は含まれません。
        /// </summary>
        /// <param name="originallist">変更前のリスト</param>
        /// <param name="new">変更後のリスト</param>
        /// <returns></returns>
        public static ChangeType[] GetChanges(IList<T> originallist, IList<T> newlist) {
            ChangeType[] r;
            if (originallist.Count == 0) {
                //変更前の長さが0の時
                //全部Addに。
                r = new ChangeType[newlist.Count];
                for (int i = 0; i < newlist.Count; i++) r[i] = ChangeType.Added;
                return r;
            } else if (newlist.Count == 0) {
                //変更後の長さが0の時
                //全部Deleteに。
                r = new ChangeType[originallist.Count];
                for (int i = 0; i < originallist.Count; i++) r[i] = ChangeType.Deleted;
                return r;
            }

            IList<T> A;
            IList<T> B;
            //長いほうをBに。
            if (originallist.Count > newlist.Count) {
                A = newlist; B = originallist;
            } else {
                A = originallist; B = newlist;
            }

            int delta = B.Count - A.Count;
            FPList fp = new FPList(delta);
            int k;
            int p;
            p = 0;
            //最初だけ例外
            fp[-1].value = -2;
            //メインループ
            while (true) {
                for (k = -p; k < delta; k++) if (snake(fp, A, B, k)) goto find;
                for (k = delta + p; k >= delta; k--) if (snake(fp, A, B, k)) goto find;
                p++;
            }
        find:
            LinkedList<ChangeType> l = new LinkedList<ChangeType>();
            PathLink pl = fp[delta].path;

            if (originallist.Count > newlist.Count) {
                while (pl != null) {
                    l.AddFirst(pl.type);
                    pl = pl.previous;
                }
            } else {
                while (pl != null) {
                    l.AddFirst((ChangeType)(-(int)pl.type));
                    pl = pl.previous;
                }
            }
            //先頭は意味無いので削除
            l.RemoveFirst();
            r = new ChangeType[l.Count];
            l.CopyTo(r, 0);

            return r;
        }

        /// <summary>
        /// 二つのリストの変更情報を保持するDifferenceListを作成します。
        /// </summary>
        /// <param name="originallist">差分を取得する変更前のリスト</param>
        /// <param name="newlist">差分を取得する変更後のリスト</param>
        /// <param name="ContainsUnchanged">originallistを保持する場合はtrue。しない場合はfalse。</param>
        public DifferenceList(IList<T> originallist, IList<T> newlist, bool ContainsUnchanged) {
            _list = new List<DifferenceListEntry>();
            _containsunchanged = ContainsUnchanged;
            ChangeType[] list1 = GetChanges(originallist, newlist);

            int newindex = 0;
            int originalindex = 0;
            for (int i = 0; i < list1.Length; i++) {
                if (list1[i] != ChangeType.Unchanged || this.ContainsUnchanged) {
                    if (list1[i] == ChangeType.Added) {
                        _list.Add(new DifferenceListEntry(ChangeType.Added, newlist[newindex], originalindex, newindex));
                    } else {
                        _list.Add(new DifferenceListEntry(list1[i], originallist[originalindex], originalindex, newindex));
                    }
                }
                switch (list1[i]) {
                    case ChangeType.Deleted:
                        originalindex++;
                        break;
                    case ChangeType.Added:
                        newindex++;
                        break;
                    default:
                        newindex++;
                        originalindex++;
                        break;
                }
            }
        }

        /// <summary>
        /// 非変更点を保持しているかを表します。
        /// </summary>
        public bool ContainsUnchanged {
            get {
                return _containsunchanged;
            }
        }

        /// <summary>
        /// ContainsUnchangedがtrueの時に変更前のリストを取得します。
        /// ContainsUnchangedがfalseの時は例外を投げます。
        /// </summary>
        /// <returns></returns>
        public List<T> GetOriginal() {
            if (!ContainsUnchanged) throw new InvalidOperationException();
            List<T> l = new List<T>();
            for (int i = 0; i < _list.Count; i++) {
                if (_list[i].Type != ChangeType.Added) {
                    l.Add(_list[i].Difference);
                }
            }
            return l;
        }

        /// <summary>
        /// ContainsUnchangedがtrueの時に変更後のリストを取得します。
        /// ContainsUnchangedがfalseの時は例外を投げます。
        /// </summary>
        /// <returns></returns>
        public List<T> GetNew() {
            if (!ContainsUnchanged) throw new InvalidOperationException();
            List<T> l = new List<T>();
            for (int i = 0; i < _list.Count; i++) {
                if (_list[i].Type != ChangeType.Deleted) {
                    l.Add(_list[i].Difference);
                }
            }
            return l;
        }

引用返信 編集キー/
■49397 / inTopicNo.9)  Re[5]: C#でDF.exeのような比較ツール作成での改行判断
□投稿者/ れい (904回)-(2010/05/03(Mon) 09:58:42)
        /// <summary>
        /// 変更後のリストから変更前のリストを作成します。
        /// このインスタンスを作成したリストでない場合の結果は不定です。
        /// </summary>
        /// <param name="new"></param>
        /// <returns></returns>
        public List<T> GetOriginal(IList<T> newlist) {
            List<T> l = new List<T>();
            int originalindex = 0;
            int newindex = 0;
            for (int i = 0; i < _list.Count; i++) {
                while (originalindex + 1 < _list[i].OriginalIndex && newindex + 1 < _list[i].NewIndex) {
                    l.Add(newlist[newindex]);
                    originalindex++;
                    newindex++;
                }
                if (_list[i].Type == ChangeType.Added) {
                    newindex++;
                } else if (_list[i].Type == ChangeType.Deleted) {
                    l.Add(_list[i].Difference);
                    originalindex++;
                } else {
                    l.Add(newlist[newindex]);
                    originalindex++;
                    newindex++;
                }
            }
            return l;
        }

        /// <summary>
        /// 変更前のリストから変更後のリストを作成します。
        /// このインスタンスを作成したリストでない場合の結果は不定です。
        /// </summary>
        /// <param name="originallist"></param>
        /// <returns></returns>
        public List<T> GetNew(IList<T> originallist) {
            List<T> l = new List<T>();
            int originalindex = 0;
            int newindex = 0;
            for (int i = 0; i < _list.Count; i++) {
                while (originalindex + 1 < _list[i].OriginalIndex && newindex + 1 < _list[i].NewIndex) {
                    l.Add(originallist[originalindex]);
                    originalindex++;
                    newindex++;
                }
                if (_list[i].Type == ChangeType.Added) {
                    l.Add(_list[i].Difference);
                    newindex++;
                } else if (_list[i].Type == ChangeType.Deleted) {
                    originalindex++;
                } else {
                    l.Add(originallist[originalindex]);
                    originalindex++;
                    newindex++;
                }
            }
            return l;
        }

        /// <summary>
        /// より新しい変更情報を持つDifferenceListと合成し、
        /// 二つの変更情報の合成の変更情報を作ります。
        /// </summary>
        /// <param name="newdifference"></param>
        /// <returns></returns>
        public DifferenceList<T> Merge(DifferenceList<T> @new) {
            List<DifferenceListEntry> l = new List<DifferenceListEntry>();
            int orgindex = 0;
            int medindex = 0;
            int newindex = 0;
            int i1 = 0;
            int i2 = 0;
            bool f = this.ContainsUnchanged && @new.ContainsUnchanged;

            while (i1 < this._list.Count && i2 < @new._list.Count) {
                ChangeType t1;
                ChangeType t2;
                bool f1;
                bool f2;
                if (i1 >= this._list.Count || (orgindex + 1 < this._list[i1].OriginalIndex && medindex + 1 < this._list[i1].NewIndex)) {
                    t1 = ChangeType.Unchanged;
                    f1 = false;
                } else {
                    t1 = this._list[i1].Type;
                    f1 = true;
                }
                if (i2 >= @new._list.Count || (medindex + 1 < @new._list[i1].OriginalIndex && newindex + 1 < @new._list[i1].NewIndex)) {
                    t2 = ChangeType.Unchanged;
                    f2 = false;
                } else {
                    t2 = @new._list[i1].Type;
                    f2 = true;
                }

                if (t1 == ChangeType.Added) {
                    if (t2 == ChangeType.Added) {
                        //「追加+追加」は後の追加を処理
                        l.Add(new DifferenceListEntry(ChangeType.Added, @new._list[i2].Difference, orgindex, newindex));
                        i2++;
                        newindex++;
                    } else if (t2 == ChangeType.Deleted) {
                        //「追加+削除」はパス。
                        i1++;
                        i2++;
                        medindex++;
                    } else {
                        //「追加+変化なし」はまとめて処理。
                        l.Add(new DifferenceListEntry(ChangeType.Added, this._list[i1].Difference, orgindex, newindex));
                        i1++;
                        if (f2) i2++;
                        medindex++;
                        newindex++;
                    }
                } else if (t1 == ChangeType.Deleted) {
                    if (t2 == ChangeType.Added) {
                        //「削除+追加」は
                        if (object.Equals(this._list[i1].Difference, @new._list[i2])) {
                            //同じ要素ならパス。
                            i1++;
                            i2++;
                            orgindex++;
                            newindex++;
                        } else {
                            //違う要素なら先の削除を処理
                            l.Add(new DifferenceListEntry(ChangeType.Deleted, this._list[i1].Difference, orgindex, newindex));
                            i1++;
                            orgindex++;
                        }
                    } else {
                        //「削除+削除」「削除+変化なし」は先の削除を処理
                        l.Add(new DifferenceListEntry(ChangeType.Deleted, this._list[i1].Difference, orgindex, newindex));
                        i1++;
                        orgindex++;
                    }
                } else {
                    if (t2 == ChangeType.Added) {
                        //「変化なし+追加」は後の追加を処理
                        l.Add(new DifferenceListEntry(ChangeType.Added, @new._list[i2].Difference, orgindex, newindex));
                        i2++;
                        newindex++;
                    } else if (t2 == ChangeType.Deleted) {
                        //「変化なし+削除」はまとめて処理
                        l.Add(new DifferenceListEntry(ChangeType.Deleted, @new._list[i2].Difference, orgindex, newindex));
                        if (f1) i1++;
                        i2++;
                        orgindex++;
                        medindex++;
                    } else {
                        //「変化なし+変化なし」はまとめて処理
                        if (f) {
                            l.Add(new DifferenceListEntry(ChangeType.Unchanged, this._list[i1].Difference, orgindex, newindex));
                        }
                        if (f1) i1++;
                        if (f2) i2++;
                        orgindex++;
                        medindex++;
                        newindex++;
                    }
                }
            }

            DifferenceList<T> r = new DifferenceList<T>();
            r._list = l;
            r._containsunchanged = f;
            return r;
        }

        /// <summary>
        /// 非変更点の情報を削除し、保持データを減らします。
        /// </summary>
        public void DeleteUnchanged() {
            if (!ContainsUnchanged) return;
            List<DifferenceListEntry> l = new List<DifferenceListEntry>();
            for (int i = 0; i < _list.Count; i++) {
                if (_list[i].Type != ChangeType.Unchanged) l.Add(_list[i]);
            }
            _list = l;
            _containsunchanged = false;
        }

        /// <summary>
        /// 変更点1個の変更情報を保持します。
        /// </summary>
        public class DifferenceListEntry {
            private ChangeType _type;
            private T _difference;
            private int _originalindex;
            private int _newindex;

            internal DifferenceListEntry(ChangeType type, T difference, int originalindex, int newindex) {
                _type = type;
                _difference = difference;
                _originalindex = originalindex;
                _newindex = newindex;
            }

            public ChangeType Type { get { return _type; } }

            public int OriginalIndex { get { return _originalindex; } }

            public int NewIndex { get { return _newindex; } }

            public T Difference { get { return _difference; } }

        }

引用返信 編集キー/
■49398 / inTopicNo.10)  Re[5]: C#でDF.exeのような比較ツール作成での改行判断
□投稿者/ れい (905回)-(2010/05/03(Mon) 09:59:09)
        public int IndexOf(DifferenceListEntry item) { return _list.IndexOf(item); }

        void IList<DifferenceListEntry>.Insert(int index, DifferenceListEntry item) { throw new InvalidOperationException(); }

        void IList<DifferenceListEntry>.RemoveAt(int index) { throw new InvalidOperationException(); }

        public DifferenceListEntry this[int index] {
            get { return _list[index]; }
            set { throw new InvalidOperationException(); }
        }

        #endregion

        #region ICollection<DifferenceListEntry> メンバ

        void ICollection<DifferenceListEntry>.Add(DifferenceListEntry item) { throw new InvalidOperationException(); }

        void ICollection<DifferenceListEntry>.Clear() { throw new InvalidOperationException(); }

        public bool Contains(DifferenceListEntry item) { return _list.Contains(item); }

        public void CopyTo(DifferenceListEntry[] array, int arrayIndex) { _list.CopyTo(array, arrayIndex); }

        public int Count { get { return _list.Count; } }

        bool ICollection<DifferenceListEntry>.IsReadOnly { get { return true; } }

        bool ICollection<DifferenceListEntry>.Remove(DifferenceListEntry item) { throw new InvalidOperationException(); }

        #endregion

        #region IEnumerable<DifferenceListEntry> メンバ

        public IEnumerator<DifferenceListEntry> GetEnumerator() { return _list.GetEnumerator(); }

        #endregion

        #region IEnumerable メンバ

        IEnumerator IEnumerable.GetEnumerator() { return _list.GetEnumerator(); }

        #endregion

    }

    /// <summary>
    /// 変更方法を現します。
    /// </summary>
    public enum ChangeType {
        Unchanged = 0,
        Added = -1,
        Deleted = 1
    }

}

引用返信 編集キー/
■49399 / inTopicNo.11)  Re[6]: C#でDF.exeのような比較ツール作成での改行判断
□投稿者/ 初心者 (123回)-(2010/05/03(Mon) 10:07:02)
No49398 (れい さん) に返信
コードご提供ありがとうございます。
今から、時間がかかると思いますが頑張って解析してみます!

引用返信 編集キー/
■49401 / inTopicNo.12)  Re[6]: C#でDF.exeのような比較ツール作成での改行判断
□投稿者/ aetos (290回)-(2010/05/03(Mon) 11:54:32)
No49398 (れい さん) に返信

これはありがたい。いただきます。
引用返信 編集キー/
■49402 / inTopicNo.13)  Re[6]: C#でDF.exeのような比較ツール作成での改行判断
□投稿者/ aetos (291回)-(2010/05/03(Mon) 12:01:02)
No49395 (れい さん) に返信

> 参考文献:
>
> E.W.Myers, "An O(ND) difference algorithm and its variations", Algorithmixa, 1 (1986), 251

の解説らしきものが以下にあります。英語に抵抗ある場合は参考までに。

http://hp.vector.co.jp/authors/VA007799/viviProg/doc5.htm
引用返信 編集キー/
■49407 / inTopicNo.14)  Re[2]: C#でDF.exeのような比較ツール作成での改行判断
□投稿者/ れい (907回)-(2010/05/03(Mon) 16:17:56)
よく見たらC#ですね。
VBしか投稿しないことに決めていたのに。
失敗しました。

No49399 (初心者 さん) に返信
> ■No49398 (れい さん) に返信
> コードご提供ありがとうございます。
> 今から、時間がかかると思いますが頑張って解析してみます!

はい。
きちんと解析して、一度は理解をしてから使ってください。
ブラックボックスでは勉強になりませんし、
なにより私は自分の書くコードを信じていませんので。

で、バグを見つけたら教えてくださいね。

No49401 (aetos さん) に返信
> これはありがたい。いただきます。

お役にたてればコードも生まれた甲斐があります。
使ってやってください。

で、バグを見つけたら(略

引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -