0

各行に 1 つの名前を含むテキスト ファイルを作成します。名前が出現する回数を計算します。ファイル内の名前ごとに 1 行を出力し、各行に出現回数と名前を出力します。

このコードを使用してファイルを開くことができます

private void button1_Click(object sender, EventArgs e)
{
    using (OpenFileDialog dlgOpen = new OpenFileDialog())
    {
        try
        {
            // Available file extensions
            openFileDialog1.Filter = "All files(*.*)|*.*";
            // Initial directory
            openFileDialog1.InitialDirectory = "D:";
            // OpenFileDialog title
            openFileDialog1.Title = "Open";
            // Show OpenFileDialog box
            if (openFileDialog1.ShowDialog() == DialogResult.OK)
            {
                // Create new StreamReader
                StreamReader sr = new StreamReader(openFileDialog1.FileName, Encoding.Default);
                // Get all text from the file
                string str = sr.ReadToEnd();
                // Close the StreamReader
                sr.Close();
                // Show the text in the rich textbox rtbMain

            }
        }
        catch (Exception errorMsg)
        {
            MessageBox.Show(errorMsg.Message);
        }
    }
}

しかし、私が望むのは、同じボタンを使用して、グループボックスで読み取って表示することです。

4

5 に答える 5

3

これは宿題であるため、コードを提供するつもりはありませんが、正しい方向に向けるのに十分な情報が得られることを願っています.

File.ReadAllLines を使用してファイルを文字列の配列に読み込むことをお勧めします。配列内の各項目はファイル内の 1 行です。つまり、ファイルの内容を自分で分割する必要はありません。次に、文字列配列をループして、各行を Dictionary に追加します。キーはファイルから読み取った行であり、値は出現回数です。キーがすでにディクショナリにあるかどうかを確認する必要があります。そうでない場合はカウント 1 で追加し、そうでない場合は既存のカウントを更新します (+1)。そのループの後、辞書の内容をループする 2 番目のループを作成し、名前とその数でテキスト ボックスを更新します。

于 2012-07-26T09:48:11.617 に答える
1

(これは宿題だと仮定して)私は以下を使用File.ReadAllLineしましたDictionary<TKey, TValue>

var nameCount = new Dictionary<string, int>();

foreach (String s in File.ReadAllLines("filename"))
{
    if (nameCount.ContainsKey(s))
    {
        nameCount[s] = nameCount[s] + 1;
    }
    else
    {
        nameCount.Add(s, 1);
    }
}

// and printing
foreach (var pair in nameCount)
{
    Console.WriteLine("{0} count:{1}", pair.Key, pair.Value);
}
于 2012-07-26T09:43:18.983 に答える
0

int変数をインクリメントすることなく、Linqを使用してこれを行うことができます。最後に、名前とカウントを含む辞書を作成します

string names = sr.ReadAllLines();
Dictionary<string, int> namesAndCount = new Dictionary<string, int>();

foreach(var name in names)
{
    if(namesAndCount.ContainsKey(name))
        continue;

    var count = (from n in names
                where n == name
                select n).Count();

    namesAndCount.Add(name, count);
}
于 2012-07-26T10:04:49.917 に答える
0

同様の質問が以前に尋ねられました: リスト内の出現をカウントする方法

私の意見では、LINQ クエリを使用するのが適切なオプションです。

string[] file = File.ReadAllLines(openFileDialog1.FileName, Encoding.Default);

IEnumerable<string> groupQuery =
    from name in file
    group name by name into g
    orderby g.Key
    select g;

foreach (var g in groupQuery)
{
    MessageBox.Show(g.Count() + " " + g.Key);
}
于 2012-07-26T09:41:21.840 に答える
0

さて、このような関数は、カウントを使用して個別の名前を作成します。

private static IDictionary<string, int> ParseNameFile(string filename)
{
    var names = new Dictionary<string, int>();
    using (var reader = new StreamReader(filename))
    {
        var line = reader.ReadLine();
        while (line != null)
        {
            if (names.ContainsKey(line))
            {
                names[line]++;
            }
            else
            {
                names.Add(line, 1);
            }
            line = reader.ReadLine(); 
        }
    }
}

または、linq と readAllLines を使用して何らかのフラッシュを実行することもできます。

private static IDictionary<string, int> ParseNameFile(string filename)
{
    return File.ReadAllLines(filename)
        .OrderBy(n => n)
        .GroupBy(n => n)
        .ToDictionary(g => g.Key, g => g.Count);
}

最初のオプションには、ファイル全体をメモリにロードしないという利点があります。

情報の出力に関しては、

var output = new StringBuilder();
foreach (valuePair in ParseNameFile(openFileDialog1.FileName))
{
    output.AppendFormat("{0} {1}\n", valuePair.Key, valuePair.Value); 
}

次にToString()、出力時に、必要な場所にデータを配置します。非常に多くの行がある場合は、StreamWriterアプローチが優先されます。

于 2012-07-26T09:48:48.007 に答える