如何从文本中读取一周未分类的字符串数组,并将其转换为可在排序算法中使用的内容?
我猜我每天必须用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]);
}
}
}
}
}
我希望输出如下: 星期一 星期一 星期一 星期二 星期二 星期二等等
非常感谢任何帮助! 谢谢。
答案 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>
接口完成的,类似double
,string
,数字类型等类型都可以实现。
要使用此功能,您需要使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>
谓词类型。您可以允许调用者传入其中任何一种类型的实例,而不是用作方法的约束。要么允许传入的对象负责比较一对值。