从文本文件中读取和在C#中排序的最佳方法

时间:2015-04-21 03:53:09

标签: c# sorting

如何从文本中读取一周未分类的字符串数组,并将其转换为可在排序算法中使用的内容?

我猜我每天必须用if语句分配一个数字,但是我无法在我的生命中解决这个问题。

这是我已经做过的事情。 SH1文件正在按照我的要求进行。 文本文件只是一个很长的数字列表,所以我可以很容易地将它们转换为双数。

至于日子,(和日期,但我还没有,所以只是忽略已经存在的东西,因为它不起作用)我不知道该怎么做。

class Algorithm
{

    // Sorting Algorithms
    public static void Quick_Sort(double[] data, int left, int right)
    {
        double temp;
        int i, j;
        double pivot;
        i = left;
        j = right;
        pivot = data[(left + right) / 2];
        do
        {
            while ((data[i] < pivot) && (i < right)) i++;
            while ((pivot < data[j]) && (j > left)) j--;
            if (i <= j)
            {
                temp = data[i];
                data[i] = data[j];
                data[j] = temp;
                i++;
                j--;
            }
        } while (i <= j);

        if (left < j) Quick_Sort(data, left, j);
        if (i < right) Quick_Sort(data, i, right);
    }


    static void Main()
    {

        //Read text files 

        string[] Day = System.IO.File.ReadAllLines("Day.txt");
        string[] Date = System.IO.File.ReadAllLines("Date.txt");
        string[] _Open = System.IO.File.ReadAllLines("SH1_Open.txt");
        string[] _Close = System.IO.File.ReadAllLines("SH1_Close.txt");
        string[] _Diff = System.IO.File.ReadAllLines("SH1_Diff.txt");
        string[] _Volume = System.IO.File.ReadAllLines("SH1_Volume.txt");

        //Convert to double Array

        //double[] Dates = Array.ConvertAll(Date, s => double.Parse(s));
        double[] SH1_Open = Array.ConvertAll(_Open, s => double.Parse(s));
        double[] SH1_Close = Array.ConvertAll(_Close, s => double.Parse(s));
        double[] SH1_Diff = Array.ConvertAll(_Diff, s => double.Parse(s));
        double[] SH1_Volume = Array.ConvertAll(_Volume, s => double.Parse(s));


        Console.WriteLine("\nWelcome to Shane Porter's Algorithms and Complexity Assingment!\n\nWhat would you like to do?");
        Console.WriteLine("\n1. Select an individual array to analyse\n\n2. View all of the files in decending order by Date\n\n3. Search for a Date\n\n4. Search for a Day\n        \n5. Sort an Array");

        int Choice = Convert.ToInt32(Console.ReadLine());



        //Option 1. Individual Array
        if (Choice == 1)

        Console.WriteLine("\nYou have chosen to select an individual array to analyse");
        Console.WriteLine("\nPlease select the array that you wish to analyse");
        Console.WriteLine("\n1. Day\n2. Date\n3. SH1_Open\n4. SH1_Close\n5. SH1_Diff\n6. SH1_Volume ");

        int ArrayChoice = Convert.ToInt32(Console.ReadLine());

        //Day
        if (ArrayChoice == 1)


        //Date
        if (ArrayChoice == 2)
        {

            DateTime[] dates = new DateTime[143];
            dates[0] = Convert.ToDateTime("12/01/2009");
            dates[1] = DateTime.Now;

            Console.WriteLine(Date);


        }

        //SH1_Open
        if (ArrayChoice == 3)
        {
            Quick_Sort(SH1_Open, 0, 143);
            for (int i = 0; i < SH1_Open.Length; i++)
            {
                Console.WriteLine(SH1_Open[i]);
            }

        }
        //SH1_Close
        if (ArrayChoice == 4)
        {
            Quick_Sort(SH1_Close, 0, 143);
            for (int i = 0; i < SH1_Close.Length; i++)
            {
                Console.WriteLine(SH1_Close[i]);
            }

            //SH1_Diff
            if (ArrayChoice == 5)
            {
                Quick_Sort(SH1_Diff, 0, 143);
                for (int i = 0; i < SH1_Diff.Length; i++)
                {
                    Console.WriteLine(SH1_Diff[i]);
                }
            }
        }

        //SH1_Volume
        if (ArrayChoice == 6)
        {
            Quick_Sort(SH1_Volume, 0, 143);
            for (int i = 0; i < SH1_Volume.Length; i++)
            {
                Console.WriteLine(SH1_Volume[i]);
            }
        }






    }
}

}

我希望输出如下: 星期一 星期一 星期一 星期二 星期二 星期二等等

非常感谢任何帮助! 谢谢。

2 个答案:

答案 0 :(得分:1)

这看起来像是一个家庭作业:)在C#中有内置的QuickSort算法实现 - Array.Sort() - 您可能会注意到本机QuickSort算法是通用的 - 即只要您的元素实现接口{ {1}} - 所以你可以从中获取灵感并将你的双重QuickSort重写为通用的(剧透 - 下面的完整代码)。

至于排序星期几;现在,当您拥有快速排序的通用版本时,您可以使用系统枚举IComparable

DayOfWeek

注意:var days = Array.ConvertAll(Day, s => (DayOfWeek)Enum.Parse(typeof(DayOfWeek), s)); Quick_Sort(days, 0, days.Length - 1); 使用英文日历顺序(星期日是星期的第一天);如果你想要不同的顺序,你必须制作自己的枚举 - 并在那里分配正确的值。像:

DayOfWeek

通用快速排序:

public enum MyDayOfWeek : int {
  Monday = 0,
  Tuesday = 1, // etc
}

答案 1 :(得分:1)

根据您的示例,在我看来,最简单的方法是将数据映射到double类型,对其进行排序,然后重新映射。像这样:

Dictionary<string, double> dayToDouble = new Dictionary<string, double>()
{
    { "Monday", 0.0 },
    { "Tuesday", 1.0 },
    { "Wednesday", 2.0 },
    { "Thursday", 3.0 },
    { "Friday", 4.0 },
    { "Saturday", 5.0 },
    { "Sunday", 6.0 }
};
Dictionary<double, string> doubleToDay =
    dayToDouble.ToDictionary(kvp => kvp.Value, kvp => kvp.Key);

double[] Days = Day.Select(day => dayToDouble[day]).ToArray();

然后您可以照常排序Days并在显示结果时将其映射回来:

Quick_Sort(Days, 0, Days.Length);
foreach (double dayValue in Days)
{
    Console.WriteLine(doubleToDay[dayValue]);
}


我认为以上内容应该针对您的具体要求,即使用Quick_Sort()方法对一周中的几天进行排序。但是,请注意,要使用此方法,您必须有一种方法将所有数据映射到double并返回。这可能是也可能并非总是可行,或者至少不方便。

虽然一周的日子没有一个容易比较的表示(即你总是必须以某种方式将它们映射到可比较的数据类型),除了{{1}之外的许多其他类型}做。遗憾的是,必须始终绕过映射数据值才能对它们进行排序。

幸运的是,.NET(和许多其他框架)通过使数据类型的概念彼此“可比”来优雅地处理这个问题。在.NET中,这是使用IComparable<T>接口完成的,类似doublestring,数字类型等类型都可以实现。

要使用此功能,您需要使DateTime方法具有通用性,在Quick_Sort()的类型参数上指定约束,以便您可以在排序中使用IComparable<T>方法方法。将该方法应用于您的方法,它看起来像这样:

CompareTo()

然后你应该能够调用输入数组是实现public static void Quick_Sort<T>(T[] data, int left, int right) where T : IComparable<T> { T temp; int i, j; T pivot; i = left; j = right; pivot = data[(left + right) / 2]; do { while ((data[i].CompareTo(pivot) < 0) && (i < right)) i++; while ((pivot.CompareTo(data[j]) < 0) && (j > left)) j--; if (i <= j) { temp = data[i]; data[i] = data[j]; data[j] = temp; i++; j--; } } while (i <= j); if (left < j) Quick_Sort(data, left, j); if (i < right) Quick_Sort(data, i, right); } 的任何类型的方法,而不仅仅是IComparable<T>。例如,double

DateTime

然后你可以像调用其他数组一样调用它:

double[] Dates = Array.ConvertAll(Date, s => DateTime.Parse(s));

.NET中还有其他与比较相关的类型。上述两种常见的替代方法(除了 Quick_Sort(Dates, 0, Dates.Length); 之外,通常在许多类中受支持)是IComparer<T>接口和Comparison<T>谓词类型。您可以允许调用者传入其中任何一种类型的实例,而不是用作方法的约束。要么允许传入的对象负责比较一对值。