1

プログラム (C#.NET) に複数の問題があり、何が原因なのかわかりません。

このプログラムは、名前と生年月日のリスト (フォーマット済みfirst name,last name,DD/MM/YYYY) を、名、姓、および生年月日の昇順および降順でソートすることを目的としています。また、まだ実装されていない他の機能も備えています。

最初の問題はquikSortStr方法にあります。プログラムは最初のifブロックでクラッシュし、それjが配列の範囲外であることを示します。これは、かどうかに関係なく発生しmode == "asc"ます。

2 つ目の、より紛らわしい問題は、値がテキスト ファイルから読み込まれると、firstとの奇数インデックス値はlastすべて null になり、 の奇数インデックス値はbDayになります1/1/0001

参照用に以下に完全なプログラムを含めました。クイックソート メソッドと並列配列の使用が必要です。コメント不足で申し訳ありません。

助けてくれてありがとう。私は完全に困惑しています。

namespace Names_Arrays
{
public partial class frmNamArrays : Form
{
    System.Globalization.CultureInfo culture = new System.Globalization.CultureInfo("en-CA");
    string[] first;
    string[] last;
    DateTime[] bDay;
    string order = "asc";
    string format = "d/M/yyyy";

    public frmNamArrays()
    {
        InitializeComponent();
    }
    private void write()
    {
        string[] lines = new string[first.Length];

        for (int i = 0; i < lines.Length; i++)
            lines[i] = first[i] + ',' + last[i] + ',' + bDay[i].ToString(format);

        txtbxNames.Clear();
        txtbxNames.Lines = lines;
    }

    private void load()
    {
        string[] lines = txtbxNames.Lines;

        first = new string[lines.Length];
        last = new string[lines.Length];
        bDay = new DateTime[lines.Length];

        int i = 0;
        foreach (string line in lines)
        {
            string[] data = line.Split(',');

            //There aren't any lines that split to a string[] of length less than three,
            //but for some reason the program kept believing there are.
            //patched that leak.

            if (data.Length == 3)
            {
                first[i] = data[0];
                last[i] = data[1];
                bDay[i] = Convert.ToDateTime(data[2], culture);
            }
            i++;
        }
    }
    public DateTime[] quikSortTim(DateTime[] primary, string mode, int left, int right)
    {
        if (primary.Length > 1)
        {
            int i = left, j = right;
            DateTime pivot = primary[left + (right - left) / 2];

            while (i <= j)
            {
                if (mode == "asc")
                {
                    while (DateTime.Compare(primary[i], pivot) < 0)
                        i++;
                    while (DateTime.Compare(primary[j], pivot) > 0)
                        j--;
                }
                else
                {
                    while (DateTime.Compare(primary[i], pivot) > 0)
                        i++;
                    while (DateTime.Compare(primary[j], pivot) < 0)
                        j--;
                }
                if (i <= j)
                {
                    DateTime holdoverB = primary[i];
                    primary[i++] = primary[j];
                    primary[j--] = holdoverB;

                    string holdover = last[i - 1];
                    last[i] = last[j + 1];
                    last[j] = holdover;

                    holdover = first[i - 1];
                    first[i] = first[j + 1];
                    first[j] = holdover;

                }
            }
            if (j > left)
                primary = quikSortTim(primary, mode, left, j);
            if (i < right)
                primary = quikSortTim(primary, mode, i, right);
        }
        return primary;
    }

    public string[] quikSortStr(string[] primary, string type, string mode, int left, int right)
    {
        if (primary.Length > 1)
        {
            int i = left, j = right;
            string pivot = primary[left + (right - left) / 2];

            while (i <= j)
            {
                if (mode == "asc")
                {
                    while (String.Compare(primary[i], pivot) < 0)
                        i++;
                    while (String.Compare(primary[j], pivot) > 0)
                        j--;
                }
                else
                {
                    while (String.Compare(primary[i], pivot) > 0)
                        i++;
                    while (String.Compare(primary[j], pivot) < 0)
                        j--;
                }
                if (i <= j)
                {
                    string holdover = primary[i];
                    primary[i] = primary[j];
                    primary[j] = holdover;
                    if (type == "first")
                    {
                        holdover = last[i];
                        last[i] = last[j];
                        last[j] = holdover;
                    }
                    else
                    {
                        holdover = first[i];
                        first[i] = first[j];
                        first[j] = holdover;
                    }
                    DateTime holdoverBeta = bDay[i];
                    bDay[i] = bDay[j];
                    bDay[j] = holdoverBeta;
                    i++;
                    j++;
                }
            }
            if (j > left)
                primary = quikSortStr(primary, type, mode, left, j);
            if (i < right)
                primary = quikSortStr(primary, type, mode, i, right);
        }
        return primary;
    }

    private void frmNamArrays_SizeChanged(object sender, EventArgs e)
    {
        txtbxNames.Width = this.Width - 40;
        txtbxNames.Height = this.Height - 157;
    }

    private void btnSort_Click(object sender, EventArgs e)
    {
        load();

        switch (cbobxCategory.Text)
        {
            case ("First Name"):
                first = quikSortStr(first, "first", order, 0, first.Length - 1);
                break;
            case ("Last Name"):
                last = quikSortStr(last, "last", order, 0, last.Length - 1);
                break;
            case ("Birthday"):
                bDay = quikSortTim(bDay, order, 0, bDay.Length - 1);
                break;
            default:
                break;
        }

        write();
    }

    private void cbobxOrder_SelectedIndexChanged(object sender, EventArgs e)
    {
        if (cbobxOrder.Text == "Ascending")
            order = "asc";
        else
            order = "desc";
    }

    private void displayfile(string name)
    {
        StreamReader fileData = new StreamReader(name);

        txtbxNames.Lines = fileData.ReadToEnd().Split('\n');

    }

    private void mnuOpen_Click(object sender, EventArgs e)
    {
        OpenFileDialog open = new OpenFileDialog();
        open.Filter = "Text Files|*.txt";
        open.Title = "Select a text file...";

        if (open.ShowDialog() == DialogResult.OK && open.FileName != "")
            displayfile(open.FileName);
    }

    private void mnuExit_Click(object sender, EventArgs e)
    {
        this.Close();
    }
}
}
4

2 に答える 2

1

You have to change the code as below in the quikSortStr method inside the if (i <= j) loop

    DateTime holdoverBeta = bDay[i];
    bDay[i] = bDay[j];
    bDay[j] = holdoverBeta;
    i++;
    j--;//was: j++;

and this will fix the issue.

于 2013-05-05T11:06:02.380 に答える
0

私の最初の間違いを指摘してくれた saravanan に感謝します。範囲外のエラーはj、誤った方向への偶発的なインクリメントが原因でした。固定方法は、

    public DateTime[] quikSortTim(DateTime[] primary, string mode, int left, int right)
    {
        if (primary.Length > 1)
        {
            int i = left, j = right;
            DateTime pivot = primary[left + (right - left) / 2];

            while (i <= j)
            {
                if (mode == "asc")
                {
                    while (DateTime.Compare(primary[i], pivot) < 0)
                        i++;
                    while (DateTime.Compare(primary[j], pivot) > 0)
                        j--;
                }
                else
                {
                    while (DateTime.Compare(primary[i], pivot) > 0)
                        i++;
                    while (DateTime.Compare(primary[j], pivot) < 0)
                        j--;
                }
                if (i <= j)
                {
                    DateTime holdoverB = primary[i];
                    primary[i] = primary[j];
                    primary[j] = holdoverB;

                    string holdover = last[i];
                    last[i] = last[j];
                    last[j] = holdover;

                    holdover = first[i];
                    first[i] = first[j];
                    first[j] = holdover;

                    i++;
                    j--;
                }
            }
            if (j > left)
                primary = quikSortTim(primary, mode, left, j);
            if (i < right)
                primary = quikSortTim(primary, mode, i, right);
        }
        return primary;
    }

    public string[] quikSortStr(string[] primary, string type, string mode, int left, int right)
    {
        if (primary.Length > 1)
        {
            int i = left, j = right;
            string pivot = primary[left + (right - left) / 2];

            while (i <= j)
            {
                if (mode == "asc")
                {
                    while (String.Compare(primary[i], pivot) < 0)
                        i++;
                    while (String.Compare(primary[j], pivot) > 0)
                        j--;
                }
                else
                {
                    while (String.Compare(primary[i], pivot) > 0)
                        i++;
                    while (String.Compare(primary[j], pivot) < 0)
                        j--;
                }
                if (i <= j)
                {
                    string holdover = primary[i];
                    primary[i] = primary[j];
                    primary[j] = holdover;
                    if (type == "first")
                    {
                        holdover = last[i];
                        last[i] = last[j];
                        last[j] = holdover;
                    }
                    else
                    {
                        holdover = first[i];
                        first[i] = first[j];
                        first[j] = holdover;
                    }
                    DateTime holdoverBeta = bDay[i];
                    bDay[i] = bDay[j];
                    bDay[j] = holdoverBeta;
                    i++;
                    j--;
                }
            }
            if (j > left)
                primary = quikSortStr(primary, type, mode, left, j);
            if (i < right)
                primary = quikSortStr(primary, type, mode, i, right);
        }
        return primary;
    }

2番目の問題自体の解決策は見つかりませんでした。ただし、読み取ったすべての要素",,1/1/0001"が追加され、名前を置き換えていないことがわかりました。linesこれを使用して、 を含まないインデックス値のみを配列に追加しました"1/1/0001"。次に、null 型の値をすべて削除lines = lines.Where(s => s != null).ToArray();して短縮しました。lines変更された関数は次のとおりです。

private void write()
    {
        string[] lines = new string[first.Length];

        for (int i = 0; i < lines.Length; i++)
            if (bDay[i].ToString(format) != "1/1/0001")
                lines[i] = first[i] + ',' + last[i] + ',' + bDay[i].ToString(format);

        lines = lines.Where(s => s != null).ToArray();

        txtbxNames.Clear();
        txtbxNames.Lines = lines;
    }

助けてくれてありがとう。ここで私のソリューションのリソースを見つけました。

編集:問題はに固有のもののようですStreamReader.ReadToEnd()。理由はわかりませんが、 を使用することで完全に回避できますSystem.IO.File.ReadAllLines(filepath)。元のコードでは、置き換えます

StreamReader file = new StreamReader(name);
lines = file.ReadToEnd().Split('\n');

lines = File.ReadAllLines(name);

を追加しusing System.IO;ます。

于 2013-05-05T19:39:09.390 に答える