【问题标题】:Sort text file data into an array将文本文件数据排序到数组中
【发布时间】:2015-03-31 01:48:15
【问题描述】:

我正在为我的计算机科学课做作业。城市人口普查数据位于保存其公民记录的文本文件中。每行将有四个不同数据类型的字段(年龄、性别、婚姻状况和地区),用逗号分隔。比如22、F、M、1。

我应该如何处理这个问题?我的想法是我应该使用两个一维数组,一个用于年龄,一个用于地区。我需要以后能够计算每个区有多少人,以及整个城市有多少不同年龄组的人。

如何读取每一行并将我想要的信息放入每个数组中?

编辑** 这就是我到目前为止所做的。我正在尝试将我的数据从字段中分离到四个不同的数组中。这就是我卡住的地方。

        FileStream fStream = new FileStream("test.txt", FileMode.Open, FileAccess.Read);
        StreamReader inFile = new StreamReader(fStream);

        string inputRecord = "";
        string[] fields;
        int[] ageData = new int[1000];
        string[] genderData = new string[1000];
        string[] maritalData = new string[1000];
        int[] districtData = new int[1000];



        inputRecord = inFile.ReadLine();
        while (inputRecord != null)
        {
            fields = inputRecord.Split(',');

            int i = 0;

            ageData[i] = int.Parse(fields[0]);
            genderData[i] = fields[1];
            maritalData[i] = fields[2];
            districtData[i] = int.Parse(fields[3]);
            i++;

            inputRecord = inFile.ReadLine();
         }

编辑 2**

第一个问题,我决定使用下面的代码来找出人口普查数据的每个地区有多少公民。

for (int x = 1; x <= 22; x++)
            for (int y = 0; y < districtData.Length; y++)
                if (districtData[y] == x)
                    countDist[x]++;

        for (int x = 1; x <= 22; x++)
            Console.WriteLine("District   " + x + "   has   " + countDist[x] + "   citizens");

在我的.Writeline 中,当x 达到两位数时,它会脱离我的列。我怎样才能更好地排列我的列?

第二个问题,我不太清楚如何使用 if 语句将 ageData 中的值分成年龄组。

【问题讨论】:

  • 感谢您将我的原始帖子从一段文本编辑成更易于阅读的内容。

标签: c# arrays sorting


【解决方案1】:

听起来这四个字段中的每一个都有一些共同点......它们代表人口普查中的一个人。现在是使用类似于

的类的好时机
public class Person
{
    public int Age { get; set; }
    public string Gender { get; set; }
    public string MaritalStatus { get; set; }
    public int District { get; set; }
}

然后,只需读入文本文件中的所有行(如果文件很小,可以使用File.ReadAllLines()),然后为文件中的每一行创建一个 Person 实例。

你可以创建一个

List<Person> people;

保存您从文本文件中解析的 Person 实例。

由于这些行似乎用逗号分隔,请查看String.Split()

更新

您的编辑尝试非常接近。您不断创建一个新的 i 并将其初始化为 0。而是在循环之外对其进行初始化:

int i = 0;
while (inputRecord != null)
{
    fields = inputRecord.Split(',');

您可能还想修剪输入中多余的空格。如果字段用“,”而不是“,”分隔,您的字段中将有多余的空格。

        genderData[i] = fields[1].Trim();
        maritalData[i] = fields[2].Trim();

【讨论】:

  • 你也可以通过这个类结构来使用 linq,虽然下面的 linq 有点过头了 ;): List o = File.ReadAllLines(@"C:\TestCases\test. txt").Select(x => x.Split(',')).Select(y => new Person() { Age = int.Parse(y[0]), Gender = y[1], MaritalStatus = y[2], District = int.Parse(y[3]) }).OrderBy(y => y.Age).ToList();
  • 感谢您的 cmets 对我的问题。我们还没有在课堂上讲课,很遗憾你的回答超出了我的理解
  • 我真的不明白为什么你的教授会在没有涵盖课程的情况下分配这个问题。我想你可以用每个属性一个列表或数组来解决它,但这将是一个非常糟糕的结构,并且会教一个坏的编程习惯。您目前正在学习哪些主题?
  • 刚刚看到您的编辑......这就是每个属性一个数组所谈论的内容。你具体看到了什么问题? (一个问题:这将在文件中超过 1000 行时失败,因为您的数组已固定为该大小)。
  • 我知道这个程序将失败超过 1000 行。我还没有决定是否应该将数字设置得非常大,或者是否有更好的方法。我现在关心的是如何将数据与fields[] 分开。我知道如何测试它的唯一方法是 Console.WriteLine(ageData[0]); 然后再做一个 Console.WriteLine(ageData[1]); 第一个显示文件最后一行的年龄,第二个给我一个 0。所以只有一个值被保存到我现在的数组。
【解决方案2】:

这个怎么样?

List<string[]> o = File.ReadAllLines(@"C:\TestCases\test.txt").Select(x => x.Split(',')).OrderBy(y => y[0]).ToList();

每个人都是列表中的一个字符串数组。 每个属性都是数组中的一个索引,例如:年龄是第一个。 上面的代码读取所有行,用逗号分隔它们按年龄排序并将它们添加到列表中。

【讨论】:

  • 感谢您的 cmets 对我的问题。我们还没有涵盖课堂上的课程,很遗憾你的回答超出了我的理解范围。
【解决方案3】:
public static class PersonsManager
{
    public static PersonStatistics LoadFromFile(string filePath)
    {
        var statistics = new PersonStatistics();
        using (var reader = new StreamReader(filePath))
        {
            var separators = new[] { ',' };
            while (!reader.EndOfStream)
            {
                var line = reader.ReadLine();

                if (string.IsNullOrWhiteSpace(line))
                    continue; //--malformed line

                var lParts = line.Split(separators, StringSplitOptions.RemoveEmptyEntries);
                if (lParts.Length != 4)
                    continue; //--malformed line

                var person = new Person
                {
                    Age = int.Parse(lParts[0].Trim()),
                    Gender = lParts[1].Trim(),
                    MaritalStatus = lParts[2].Trim(),
                    District = int.Parse(lParts[3].Trim())
                };

                statistics.Persons.Add(person);
            }
        }

        return statistics;
    }
}

public class PersonStatistics
{
    public List<Person> Persons { get; private set; }

    public PersonStatistics()
    {
        Persons = new List<Person>();
    }

    public IEnumerable<Person> GetAllByGender(string gender)
    {
        return GetByPredicate(p => string.Equals(p.Gender, gender, StringComparison.InvariantCultureIgnoreCase));
    }

    //--NOTE: add defined queries as many as you need
    public IEnumerable<Person> GetByPredicate(Predicate<Person> predicate)
    {
        return Persons.Where(p => predicate(p)).ToArray();
    }
}

public class Person
{
    public int Age { get; set; }
    public string Gender { get; set; }
    public string MaritalStatus { get; set; }
    public int District { get; set; }
}

用法:

var statistics = PersonsManager.LoadFromFile(@"d:\persons.txt");
var females = statistics.GetAllByGender("F");
foreach (var p in females)
{
    Console.WriteLine("{0} {1} {2} {3}", p.Age, p.Gender, p.MaritalStatus, p.District);
}

希望对你有帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-03-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-12
    相关资源
    最近更新 更多