【发布时间】:2011-11-10 20:45:48
【问题描述】:
我现在正在使用流式阅读器来读取人名文件,它是一个文本文件,人名,所以显然有重复,我希望能够显示现在有多少人有相同的名字所以例如:
josh
alex
josh
john
alex
我想说,
josh 2
alex 2
john 1
但我似乎找不到一种简单的方法,这样做最简单的方法是什么,
【问题讨论】:
标签: c# streamreader
我现在正在使用流式阅读器来读取人名文件,它是一个文本文件,人名,所以显然有重复,我希望能够显示现在有多少人有相同的名字所以例如:
josh
alex
josh
john
alex
我想说,
josh 2
alex 2
john 1
但我似乎找不到一种简单的方法,这样做最简单的方法是什么,
【问题讨论】:
标签: c# streamreader
我会说使用Dictionary<string, int>。
Dictionary<string, int> firstNames = new Dictionary<string, int>();
foreach (string name in YourListWithNames)
{
if (!firstNames.ContainsKey(name))
firstNames.Add(name, 1);
else
firstNames[name] += 1;
}
当然,解决方案有很多不同的途径,但这就是我要解决的方法。我还没有运行这段代码,但我认为这会对你有所帮助。
【讨论】:
用 LINQ 试试这个。
首先使用此代码将您的文本文件读入List<string>:
const string f = "TextFile1.txt";
// 1
// Declare new List.
List<string> lines = new List<string>();
// 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<string>
List<PersonCount> personCounts = lines.GroupBy(p => p).Select(g => new PersonCount() {Name = g.Key, Count = g.Count()}).ToList();
现在遍历列表以获取名称和重复次数。
【讨论】:
使用 HashMap 可以解决您的问题。 当你读取一个名字时,检查这个键是否已经存在,如果存在,更新它(+1),如果没有,将它添加到你的 Hash Map 中。
最后,您需要做的就是打印键值对。
【讨论】:
将所有名称存储在 Dictionary<string, int> names 中。
对每一行使用类似的内容:
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<string>(
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<string, int> count = new Dictionary<string, int>();
for (int i = 0; i < p.Length; i++)
{
try
{
count[p[i].Trim()] = count[p[i]] + 1;
}
catch
{
count.Add(p[i], 1);
}
}
【讨论】: