1

現在、乱数(1〜20)を生成し、各数値がランダムに生成された回数を数えています。で、textBox1生成する数値の量を選択します。最終結果を複数行で表示しますtextBox2。私が経験している問題は、ボタンをもう一度クリックするたびに、数値がランダムに生成された回数がリセットされることです。

ボタンをx回クリックして、カウントをリセットせずにランダムに生成された回数をカウントできますか? 私は配列の助けを借りてこれを具体的にしようとしています。

コード

 public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        Random r = new Random();

        private void button1_Click(object sender, EventArgs e)
        {


            var n = int.Parse(this.textBox1.Text);



            var y =
                Enumerable
                    .Range(0, n)
                    .Select(x => r.Next(20) + 1)
                    .ToArray();

            var sum = y.Sum();
            var avg = (double)sum / (double)n;
            var frequency = y.ToLookup(x => x);

            textBox2.Text = String.Join(Environment.NewLine, new[]
        {
            "Number of times an integer was randomly generated",
            String.Format("{0} {1}", sum, avg),
        }.Concat(Enumerable
                .Range(1, 20)
                .Select(x => String.Format("{0} ({1})", x, frequency[x].Count()))));

        }

    }
4

2 に答える 2

3

変数のスコープは、button1_Clickメソッド内にのみ存在します。クリックしても保持するには、プライベート クラス変数として移動する必要があります。そこに到達するには、コードを少しリファクタリングする必要があります。

public partial class Form1 : Form
{
    private Random r = new Random();

    private int[] counts = new int[20];

    private static string newLine = Environment.NewLine;

    public Form1()
    {
        InitializeComponent();
    }

    private void button1_Click(object sender, EventArgs e)
    {
        int n = 0;
        if (int.TryParse(this.textBox1.Text, out n))
        {
            // Clear the box
            this.textBox2.Text = string.Empty;

            var generatedList = new int[n];
            for (int i = 0; i < n; i++)
            {
                // Upper bound is EXCLUSIVE
                var gen = r.Next(1, 21);
                counts[gen - 1]++;
                generatedList[i] = gen;
            }

            this.textBox2.Text += PrintNumbers(generatedList);
            this.textBox2.Text += PrintCounts(this.counts);
        }
        else
        {
            this.textBox2.Text = "Invalid input! Cannot generate numbers.";
        }
    }

    private static string PrintNumbers(int[] numbers)
    {
        if (numbers == null)
        {
            return "No numbers generated" + newLine;
        }

        string result = "Generated sequence: {";
        for (int i = 0; i < numbers.Length; i++)
        {
            result += numbers[i];

            if (i < numbers.Length - 1)
            {
                result += ", ";
            }
        }

        return result + "}" + newLine;
    }

    private static string PrintCounts(int[] counts)
    {
        if (counts == null)
        {
            return string.Empty;
        }

        string result = string.Empty;
        for (int i = 0; i < counts.Length; i++)
        {
            result += "Number " + (i + 1) + " generated " + counts[i] + " times." + newLine;
        }

        return result;
    }
}

メソッドの上限rand.next(min,max)は排他的であることに注意してください。つまり、1 から 20 までの数値を生成するには、1 から 21 までを渡す必要があります。なぜ矛盾しているのかわかりません。少し混乱します。

n = 10 の出力

Generated sequence: {12, 5, 12, 15, 8, 20, 6, 5, 16, 6}
Number 1 generated 0 times.
Number 2 generated 0 times.
Number 3 generated 0 times.
Number 4 generated 0 times.
Number 5 generated 2 times.
Number 6 generated 2 times.
Number 7 generated 0 times.
Number 8 generated 1 times.    
Number 9 generated 0 times.
Number 10 generated 0 times.
Number 11 generated 0 times.
Number 12 generated 2 times.
Number 13 generated 0 times.
Number 14 generated 0 times.
Number 15 generated 1 times.
Number 16 generated 1 times.
Number 17 generated 0 times.
Number 18 generated 0 times.
Number 19 generated 0 times.
Number 20 generated 1 times.
于 2012-09-14T13:22:31.980 に答える
1

インスタンス フィールドにいくつかのデータを覚えておく必要があります。リストで以前に生成されたすべての数値 (コードの変更はほとんどありません) またはヒストグラム自体をDictionary<int, int>.

インスタンス フィールドは、イベント ハンドラーへの呼び出し間で保持されますが、ローカル変数は失われます。

于 2012-09-14T13:21:12.443 に答える