使用StreamReader计算重复项?
我现在正在使用streamreader来读取人名的文件,它是一个文本文件,人名,所以显然有重复,我希望能够显示现在有多少人有相同的例如:
josh alex josh john alex
我想要它说,
josh 2 alex 2 john 1
但我似乎无法找到一种简单的方法来做到这一点,这是最简单的方法,
我会说使用Dictionary
。
Dictionary firstNames = new Dictionary(); foreach (string name in YourListWithNames) { if (!firstNames.ContainsKey(name)) firstNames.Add(name, 1); else firstNames[name] += 1; }
当然,解决方案有很多不同的途径,但这就是我要解决它的方法。 我还没有运行此代码,但这对我有所帮助。
尝试使用LINQ。
首先使用以下代码将文本文件读取到List
:
const string f = "TextFile1.txt"; // 1 // Declare new List. List lines = new List (); // 2 // Use using StreamReader for disposing. using (StreamReader r = new StreamReader(f)) { // 3 // Use while != null pattern for loop string line; while ((line = r.ReadLine()) != null) { // 4 // Insert logic here. // ... // "line" is a line in the file. Add it to our List. lines.Add(line); } }
您需要定义一个您将拥有名称的类,以及相应的计数:
class PersonCount { public string Name { get; set; } public int Count { get; set; } }
最后使用此Lambda
表达式来获取所需的List
List personCounts = lines.GroupBy(p => p).Select(g => new PersonCount() {Name = g.Key, Count = g.Count()}).ToList();
现在遍历列表以获取名称和重复计数。
使用HashMap是您的问题的解决方案。 当您读取名称时,请检查该密钥是否已存在,如果是,请更新它(+1),如果没有将其添加到您的哈希映射中。
最后,您需要做的就是打印键值对。
将所有名称存储在Dictionary
。
对每行使用这样的东西:
var theName = reader.ReadLine(); names[theName] += 1;
(如果项目不存在,则应将计数设置为1)
foreach (var keyvalue in File.ReadAllLines(@"C:\....").GroupBy(x => x).Select(x => new { name = x.Key, count = x.Count() })) { Console.WriteLine(keyvalue.name + ": " + keyvalue.count); }
您当然也可以使用Linq执行类似的操作(省略错误检查):
var names = new List( File.ReadAllText(pathToFile).Split( Environment.NewLine.ToCharArray(), StringSplitOptions.RemoveEmptyEntries )); var namesAndOccurrences = from name in names.Distinct() select name + " " + names.Count(n => n == name); foreach (var name in namesAndOccurrences) Console.WriteLine(name);
根据文件的大小,可能需要删除流; 但是,这并不是说如果文件对于内存来说相当大,那么你应该使用ReadLine
。
尝试此离线解决方案
StreamReader dr = new StreamReader(@"C:\txt.txt"); string str = dr.ReadToEnd(); string[] p = str.Split(new string[] { Environment.NewLine, " " }, StringSplitOptions.RemoveEmptyEntries); Dictionary count = new Dictionary(); for (int i = 0; i < p.Length; i++) { try { count[p[i].Trim()] = count[p[i]] + 1; } catch { count.Add(p[i], 1); } }