我是C#和面向对象编程的新手。我有一个解析非常大的文本文件的应用程序。
我有两本字典:
Dictionary<string, string> parsingDict //key: original value, value: replacement
Dictionary<int, string> Frequency // key: count, value: counted string
我正在查找每个键的频率。我能够获得所需的输出,即:
系统1已被机器A替换5次
系统2已被机器B更换7次
系统3已被替换为机器C10次
系统4已被替换为机器D19次
以下是我的代码:
String[] arrayofLine = File.ReadAllLines(File);
foreach (var replacement in parsingDict.Keys)
{
for (int i = 0; i < arrayofLine.Length; i++)
{
if (arrayofLine[i].Contains(replacement))
{
countr++;
Frequency.Add(countr, Convert.ToString(replacement));
}
}
}
Frequency = Frequency.GroupBy(s => s.Value)
.Select(g => g.First())
.ToDictionary(kvp => kvp.Key, kvp => kvp.Value); //Get only the distinct records.
foreach (var freq in Frequency)
{
sbFreq.AppendLine(string.Format("The text {0} was replaced {2} time(s) with {1} n",
freq.Value, parsingDict[freq.Value],
arrayofLine.Where(x => x.Contains(freq.Value)).Count()));
}
使用String[] arrayofLine = File.ReadAllLines(File);
可提高内存利用率。
数组如何能够 Line.Where(x => x.Contains(freq.值((。Count(((使用 File.ReadLine 实现,因为它对内存友好。
string line = string.Empty;
Dictionary<string, int> found = new Dictionary<int, string>();
using(System.IO.StreamReader file = new System.IO.StreamReader(@"c:PathToBigFile.txt"))
{
while(!file.EndOfStream)
{
line = file.ReadLine();
// Matches found logic
if (!found.ContainsKey(line)) found.Add(line, 1);
else found[line] = found[line] + 1;
}
}
您可以一次轻松地阅读一行(ref(。
相关代码如下所示:
Dictionary<string,int> lineCount = new Dictionary<string,int>();
string line;
// Read the file and display it line by line.
using(System.IO.StreamReader file =
new System.IO.StreamReader("c:\test.txt"))
{
while((line = file.ReadLine()) != null)
{
string value = DiscoverFreq(line);
lineCount[value] += 1;
}
}
注意:重要的是要考虑要存储的其他信息。 将大文件中的行附加到字符串中本质上与一次读取整个文件相同,但垃圾回收更多。
注2:我简化了您更新计数的部分。 您必须检查计数条目是否存在并添加它,或者如果存在,则递增它。 或者,您可以在扫描文件之前初始化 lineCounts,将所有freq.Values
设置为 0。
如果唯一单词的数量足够多,那么您可能需要使用像 SQLite 这样的小型数据库来为您存储计数。 这使您可以快速查询信息,而无需考虑如何存储和读取您自己编写的自定义文件。