我正在创建一个高分 top5 列表,但我不知道如何对文本文件中的数据进行排序并写出具有最高 int 的 top5。现在我有一个程序将结果写入文本文件 highscore.txt。
我希望它看起来像这样。
Highscore
1. 500pts
2. 450pts
3. 400pts
4. 350pts
5. 300pts
我正在创建一个高分 top5 列表,但我不知道如何对文本文件中的数据进行排序并写出具有最高 int 的 top5。现在我有一个程序将结果写入文本文件 highscore.txt。
我希望它看起来像这样。
Highscore
1. 500pts
2. 450pts
3. 400pts
4. 350pts
5. 300pts
如果数据是逐行的,或者您知道文件中的字节偏移量,那么以非常节省内存的方式有效地读取整个文件并跟踪前 5 个分数是相当容易的。
假设您有一个从文件返回下一个分数的函数(通过StreamReader),那么代码将如下所示(我假设分数是整数):
System.IO.StreamReader reader = new System.IO.StreamReader(fileName); // create StreamReader for the file
int maxTopScores = 5; // maximum number of scores to retrieve
List<int> topScores = new List<int>(); // create a list to store the top scores in
while (!reader.EndOfStream) // check there is still data to read (or some other check, depending on file format)
{
int tempScore = getScore(reader); // hypothetical function that retrieves the next score (returns an int)
for (int i = 0; i < topScores.Count; i++)
{
if (tempScore > topScores[i])
{
topScores.Insert(i, tempScore); // insert this score before the one that it is bigger than
if (topScores.Count > maxTopScores)
topScores.RemoveAt(topScores.Count - 1); // too many scores, remove the last (lowest)
goto scoreAdded; // sorry about the goto, but I hate breaking through loops with state booleans
}
}
// score not added yet
if (topScores.Count < maxTopScores)
topScores.Add(tempScore); // not enough scores, add it to the end (it's the lowest yet)
scoreAdded:
continue; // annoyingly this is needed
}
这应该为您提供一个int 分数列表,最高分数在索引 0 处topScores
,并且随着您在列表中向下移动,分数会降低。它不需要太多内存,而且你很难让它崩溃。
如果需要,它只是在将分数插入列表时循环遍历他的文件fileName
,并确保列表不包含超过maxTopScores
分数。
File.ReadLines("highscore.txt")
.Select(line => int.Parse(line))
.OrderByDescending(score => score)
.Take(5)
最佳解决方案取决于您的平台限制和文本文件的大小。
最简单的解决方案可能是将每一行表示为一个类。从文本文件中读取行,填充分数列表,然后
public class Score
{
public int Points { get; set; }
public string Player { get; set; }
}
List<Score> top5 = (from s in allScores select s)
.OrderByDescending(s => s.Points)
.Take(5);
如果您在相对于文本文件大小的内存受限的平台上,您可以使用整数计数器来跟踪当前在前 5 名中的最低高分,并使用该计数器来决定您读入的下一个高分是否从文件应添加到您手动维护的 5 个最高分的列表中。
无论哪种方式,您都可以像这样输出前 5 个:
for (int i = 0; i < top5.Count; i++)
{
Score score top5[i];
// e.g. Console.WriteLine((i + 1) + ". " + top5.Points);
// Optionally output player name / initials if that was in the text file
}
我建议改用真正的数据库,例如免费的Sql-Server Express。
如果你真的想使用文本文件,你可以使用这种方法:
IEnumerable<string> top5HighScore = File.ReadLines("highscore.txt")
.Select(line => int.Parse(line))
.OrderByDescending(score => score)
.Take(5)
.Select((score, index) => string.Format("{0}. {1}pts", index + 1, score));
现在,您可以例如使用 aforeach
来输出字符串。
请注意,您需要添加using System.Linq;
.