2

我在richTextBox1 中有一些文本。

  1. 我必须按单词的频率对单词进行排序并将它们显示在richTextBox2. 它似乎工作。

  2. 必须找到所有错误的单词并将它们显示在richTextBox4. 我正在使用 Hunspell。显然我错过了一些东西。几乎所有单词都显示在richTextBox4不仅错误的单词中。

代码:

foreach (Match match in wordPattern.Matches(str))
{
    if (!words.ContainsKey(match.Value))
        words.Add(match.Value, 1);
    else
        words[match.Value]++;
}

string[] words2 = new string[words.Keys.Count];
words.Keys.CopyTo(words2, 0);

int[] freqs = new int[words.Values.Count];
words.Values.CopyTo(freqs, 0);

Array.Sort(freqs, words2);
Array.Reverse(freqs);
Array.Reverse(words2);

Dictionary<string, int> dictByFreq = new Dictionary<string, int>();

for (int i = 0; i < freqs.Length; i++)
{
    dictByFreq.Add(words2[i], freqs[i]);
}

Hunspell hunspell = new Hunspell("en_US.aff", "en_US.dic");

StringBuilder resultSb = new StringBuilder(dictByFreq.Count); 

foreach (KeyValuePair<string, int> entry in dictByFreq)
{
    resultSb.AppendLine(string.Format("{0} [{1}]", entry.Key, entry.Value));
    richTextBox2.Text = resultSb.ToString();

    bool correct = hunspell.Spell(entry.Key);

    if (correct == false)                
    {
        richTextBox4.Text = resultSb.ToString();
    }    
}
4

2 回答 2

0

您在richtextbox4 上的显示与在richtextbox2 中的显示相同:)

我认为这应该有效:

foreach (KeyValuePair<string, int> entry in dictByFreq)
{
    resultSb.AppendLine(string.Format("{0} [{1}]", entry.Key, entry.Value));
    richTextBox2.Text = resultSb.ToString();

    bool correct = hunspell.Spell(entry.Key);

    if (correct == false)                
    {

        richTextBox4.Text += entry.Key;
    }    
}
于 2014-05-09T07:18:33.547 回答
0

除了上面的答案(如果你的 Hunspell.Spell 方法正常工作,它应该工作),我有一些建议来缩短你的代码。您正在将匹配项添加到您的字典中,并计算每个匹配项的出现次数。然后您似乎正在按频率的降序对它们进行排序(因此最高出现匹配将在结果中具有索引 0)。这里有一些代码片段可以让你的函数更短:

IOrderedEnumerable<KeyValuePair<string, int>> dictByFreq = words.OrderBy<KeyValuePair<string, int>, int>((KeyValuePair<string, int> kvp) =>  -kvp.Value);

这使用 .NET 框架为您完成所有工作。words.OrderBy 接受一个 Func 参数,该参数提供要排序的值。使用此函数的默认值的问题是它希望对进行排序,而您希望对进行排序。这个函数调用将完全做到这一点。它还将根据值(即特定匹配发生的频率)按降序对它们进行排序。它返回一个必须存储的 IOrderedEnumerable 对象。而且由于这是可枚举的,您甚至不必将其放回字典中!如果以后确实需要对其进行其他操作,可以调用dictByFreq.ToList()函数,该函数返回一个类型为:List>的对象。

所以你的整个功能就变成了这样:

foreach (Match match in wordPattern.Matches(str))
{
    if (!words.ContainsKey(match.Value))
        words.Add(match.Value, 1);
    else
        words[match.Value]++;
}

IOrderedEnumerable<KeyValuePair<string, int>> dictByFreq = words.OrderBy<KeyValuePair<string, int>, int>((KeyValuePair<string, int> kvp) => -kvp.Value);

Hunspell hunspell = new Hunspell("en_US.aff", "en_US.dic");

StringBuilder resultSb = new StringBuilder(dictByFreq.Count);

foreach (KeyValuePair<string, int> entry in dictByFreq)
{

    resultSb.AppendLine(string.Format("{0} [{1}]", entry.Key, entry.Value));
    richTextBox2.Text = resultSb.ToString();

    bool correct = hunspell.Spell(entry.Key);

    if (correct == false)
    {
        richTextBox4.Text = entry.Key;
    }
}
于 2014-05-09T07:46:38.713 回答