2

richTextBox1 にテキストがあります。

  1. 単語を頻度順に並べ替えて、 に表示する必要がありrichTextBox2ます。うまくいくようです。

  2. 間違った単語をすべて見つけて、 に表示する必要がありrichTextBox4ます。ハンスペルを使用しています。どうやら私は何かが欠けているようです。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

あなたはrichtextbox2と同じようにrichtextbox4に表示されています:)

私はこれがうまくいくと思います:

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 メソッドが正しく機能する場合に機能するはずです) に加えて、コードを短くするための提案がいくつかあります。Matches を辞書に追加し、各一致の出現回数を数えます。次に、頻度の降順でそれらを並べ替えているように見えます(したがって、最も高い出現一致の結果はインデックス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 に答える