C#-读取文本文件,比较字典数据并查找每种数据的频率

C#-读取文本文件,比较字典数据并查找每种数据的频率,c#,dictionary,C#,Dictionary,我有一个名为data.txt的文本文件,其中包含替换文本的数据 data.txt的内容: 第1行:System1->MachineA 第2行:System2->MachineB 第3行:System3->MachineC 第4行:系统4->机械加工 第4行:System6->MachineF 第5行:System5->MachineE 第6行:System6->MachineF 第7行:System7->MachineG 第8行:System2->MachineB 第8行:System8->Ma

我有一个名为data.txt的文本文件,其中包含替换文本的数据

data.txt的内容

第1行:System1->MachineA

第2行:System2->MachineB

第3行:System3->MachineC

第4行:系统4->机械加工

第4行:System6->MachineF

第5行:System5->MachineE

第6行:System6->MachineF

第7行:System7->MachineG

第8行:System2->MachineB

第8行:System8->MachineH

它计算行数,我想计算频率或原始文本被替换的次数

所需输出:

System1 has been replaced with MachineA 1 time(s)

System2 has been replaced with MachineB 2 time(s)

System3 has been replaced with MachineC 3 time(s)

System4 has been replaced with MachineD 4 time(s)

System6 has been replaced with MachineF 5 time(s)

System5 has been replaced with MachineE 6 time(s)

System6 has been replaced with MachineF 7 time(s)

System7 has been replaced with MachineG 8 time(s)

System2 has been replaced with MachineB 9 time(s)

System8 has been replaced with MachineH 10 time(s)
System1 has been replaced with MachineA 1 time(s)

System2 has been replaced with MachineB 2 time(s)

System3 has been replaced with MachineC 1 time(s)

System4 has been replaced with MachineD 1 time(s)

System6 has been replaced with MachineF 2 time(s)

System5 has been replaced with MachineE 1 time(s)

System7 has been replaced with MachineG 1 time(s)

System8 has been replaced with MachineH 1 time(s)

如何获得所需的输出?

只有交换循环才能工作

 foreach(var replacement in Replaced.Keys)
     { 
        for (int i = 0; i < arrayofLine.Length;i++ )
                    {

                            if (arrayofLine[i].Contains(replacement))
                            {
                                countr++;
                                 //if (Frequency.ContainsKey(countr))
                                //{
                                //    Frequency[countr] = Frequency[countr] + "|" + replacement;
                                //}
                                //else
                                //{
                                //    Frequency.Add(countr, replacement);
                                //}
                                Frequency.Add(countr, Convert.ToString(replacement));
                            }
                        }

                    }
foreach(替换.Keys中的变量替换)
{ 
for(int i=0;i
为什么不数一数它发生了多少次

首先获取唯一记录:

for (int i = 0; i < arrayofLine.Length; i++)
        {
           //Your original logic here
        }

//This is an additional code:
Frequency = Frequency.GroupBy(s => s.Value)
        .Select(g => g.First())
        .ToDictionary(kvp => kvp.Key, kvp => kvp.Value);  //Get only the distinct records.

StringBuilder sbFreq = new StringBuilder();
foreach (var freq in Frequency)
     {
sbFreq.AppendLine(string.Format("{0} has been replaced with {1} {2} time(s) ",
freq.Value, Replaced[freq.Value], 
arrayofLine.Where(x => x.Contains(freq.Value)).Count())); //Here is the modification part
    }
for(int i=0;is.Value)
.Select(g=>g.First())
.ToDictionary(kvp=>kvp.Key,kvp=>kvp.Value)//只获取不同的记录。
StringBuilder sbFreq=新的StringBuilder();
foreach(频率中的var频率)
{
sbFreq.AppendLine(string.Format(“{0}已替换为{1}{2}时间)”,
频率值,已替换[频率值],
其中(x=>x.Contains(freq.Value)).Count());//这是修改部分
}
您将收到所需的输出:


最短的答案是将
countr
声明放入循环并交换循环(Mukesh的答案忘记了更改
countr
的位置)

请注意,我使用的是
字典频率
,而不是
字典
(您的版本没有意义,因为多个替换可能具有相同的出现次数)

但是如果您希望在同一迭代中也执行实际的字符串替换,则需要更加详细。您仍然可以使用LINQ,但需要手动迭代,以便在每个步骤中添加所需的替换逻辑

大概是这样的:

foreach(var replacement in Replaced)
{   
    //Count how often it occurs
    Frequency.Add(
                  replacement.Key, 
                  arrayofLine.Count(line => line.Contains(replacement.Key))
              );

    //And also replac the occurrences!
    for (int i = 0; i < arrayofLine.Length;i++ )
    {
         if (arrayofLine[i].Contains(replacement)) 
             arrayofLine[i] = arrayofLine[i].Replace(replacement.Key, replacement.Value);
    }

}
foreach(替换中的var替换)
{   
//数一数它发生的频率
频率。添加(
更换,钥匙,
arrayofLine.Count(line=>line.Contains(replacement.Key))
);
//并重新播放发生的事件!
for(int i=0;i
仍有一个潜在的bug
如果一行可以多次包含相同的替换值,那么您可能应该计算出现次数,而不是至少包含一次出现次数的行数。
但如果重置价值永远不会出现两次,这就不是问题


如果这是一个问题,我建议您调查一下,如果遇到任何问题,可以发布一个新的问题。

原样的代码实际上并不使用字典作为字典,但可能初始值是不相关的,只有所有的
行x:system->machine
组合应该被解析? (换句话说:文件是否可以包含不在替换列表中的系统?)

一种替代方法是使用正则表达式的形式来获取所有组合:

//arrayofLine = File.ReadAllLines("data.txt");
var rx = new Regex(@"(?:.*:\s*)(\w+)(?:\s*->\s*)(\w+)");
string sFreq = string.Join(Environment.NewLine, from l in arrayofLine
    let m = rx.Match(l)
    where m.Success
    group l by new {From = m.Groups[1].Value, To = m.Groups[2].Value} into g
    select $"{g.Key.From} has been replaced with {g.Key.To} {g.Count()} time(s)"
);
sFreq
将包含基于示例输入的所需结果。
请注意,所有唯一的from->to组合上都有此组,但在示例代码中,每个“from”(系统)似乎都设置为相同的“to”(机器)。如果只需要检查系统,代码(分组)可以简化

当I Console.WriteLine(sbFreq)时,它会给出相同的输出;它显示空白的控制台窗口。我没有修改所有内容。我刚刚在字典变量(Frequency=Frequency.GroupBy)中添加了GroupBy。并编辑了foreach循环。我更新了我的帖子,所以你可以关注。剩下的都是你的代码。非常感谢你的详细解释。
Frequency = Replaced.ToDictionary(
                            x => x.Key,
                            x => arrayofLine.Count(line => line.Contains(x.Key))
                        );
foreach(var replacement in Replaced)
{   
    //Count how often it occurs
    Frequency.Add(
                  replacement.Key, 
                  arrayofLine.Count(line => line.Contains(replacement.Key))
              );

    //And also replac the occurrences!
    for (int i = 0; i < arrayofLine.Length;i++ )
    {
         if (arrayofLine[i].Contains(replacement)) 
             arrayofLine[i] = arrayofLine[i].Replace(replacement.Key, replacement.Value);
    }

}
//arrayofLine = File.ReadAllLines("data.txt");
var rx = new Regex(@"(?:.*:\s*)(\w+)(?:\s*->\s*)(\w+)");
string sFreq = string.Join(Environment.NewLine, from l in arrayofLine
    let m = rx.Match(l)
    where m.Success
    group l by new {From = m.Groups[1].Value, To = m.Groups[2].Value} into g
    select $"{g.Key.From} has been replaced with {g.Key.To} {g.Count()} time(s)"
);