为我的测验问题创建随机顺序

时间:2012-02-13 10:02:20

标签: c# list random

我对C#编程很陌生,所以对我很陌生。我已经阅读了网站上已经发布的众多问题,但我似乎无法看到一个提出相同问题的问题,我相信可能会有更简单的方法。

我创建了一个测验应用程序,并使用switch语句来解决问题。即从1到2到3到4,依此类推。 但是,一旦用户完成测验并希望重新开始,他们就必须重新审阅所有相同的问题。 (设计是如果他们错了,应用程序退出)。 因此,我想看看是否有办法随机化 QuestionCount 的数字(但只生成一次这个数字)或我可以做的另一种方式。 我可以看到有使用列表的建议,但这些似乎集中在列表中包含的大数字,而我的目前只有20个问题。

我已经复制了我目前正在使用的代码。

private void Verify(int Question)
{
    switch (Question)
    {
        case 1:
            if (checkBox1.Checked && !checkBox2.Checked && !checkBox3.Checked && !checkBox4.Checked)
            {
                MessageBox.Show("Correct - Well Done");
                //This was a test to see if I could assign a random number which works but the number could then appear again meaning the user gets the same question
                Random random = new Random();
                QuestionCount = random.Next(0, 21);
                QuestionSelection(QuestionCount);
                //SelectLabel(QuestionCount);
                ClearcheckBox();
            }
            else
            {
                MessageBox.Show("No - It was Sunguard");
                Application.Exit();
            }
            break;
        case 2:
            if (checkBox3.Checked && !checkBox2.Checked && !checkBox1.Checked && !checkBox4.Checked)
            {
                //this method was the original where it just adds 1 to QuestionCount and works it way through the switch statement for the questions.
                MessageBox.Show("Correct - Well Done");
                QuestionCount++;
                QuestionSelection(QuestionCount);
                //SelectLabel(QuestionCount);
                ClearcheckBox();
            }
            else
            {
                MessageBox.Show("No - It's to look at a students details");
                Application.Exit();
            }
    }
}

3 个答案:

答案 0 :(得分:1)

为什么不把所有问题都放在一个列表中,并将其改组:

public List<T> RandomPermutation<T>(List<T> array)
{
    Random random = new Random();
    List<T> retArray = new List<T>(array);

    int maxIndex = array.Count - 1;

    for (int i = 0; i <= maxIndex; i++)
    {
        int swapIndex = random.Next(i, maxIndex);
        if (swapIndex != i)
        {
            T temp = retArray[i];
            retArray[i] = retArray[swapIndex];
            retArray[swapIndex] = temp;
        }
    }
    return retArray;
}

答案 1 :(得分:1)

要确保每次问题只会在我使用两个列表时询问:AnsweredQuestionsUnansweredQuestions

在开头AnsweredQuestions为空时,UnansweredQuestions包含要问的所有问题。 现在你可以在上面的代码中使用像你这样的随机数发生器了。作为random.Next()的最大值,您可以获取Count列表的当前项UnansweredQuestions

正确回答问题后,您可以将其从UnansweredQuestions列表中删除并将其放入AnsweredQuestions列表。

这样,您的随机数发生器只会使用那些真正无法回答的问题。

答案 2 :(得分:0)

如果您只有少量可能的值,则可以将选项编码为Uint64中的位标志。我在下面添加了一个例子。

为方便起见,我使用BitArray。使用bit-wise&amp;更好。和|运营商。 结果打包成一个UInt64,但它可以很容易地用于标志和值的两个单独的Uint32。

private static UInt64 Next(UInt64 current, int questions)
{
    // Convert the current value to an array of bytes.
    // Remove the least significant 4 bytes.
    // and then create a flag array.
    var bytes = BitConverter.GetBytes(current);
    bytes[0] = bytes[1] = bytes[2] = bytes[3] = 0;
    var flags = new BitArray(bytes);

    // If all questions has been answered then exit with 0.
    var all = Enumerable.Range(32, questions).All(flags.Get);
    if (all)
        return 0UL;

    // Make a random next value, if the value has been used then repeat.
    var random = new Random(DateTime.Now.Millisecond);
    var next = random.Next(questions);
    while (flags.Get(next + 32))
        next = random.Next(questions);

    // set the flag value for the guess.
    flags.Set(next + 32, true);

    // convert the flags back to Uint64 and add the next value.
    flags.CopyTo(bytes, 0);
    return BitConverter.ToUInt64(bytes, 0) + Convert.ToUInt64(next);
}

测试:

var first = Next(0UL, 20);
while (first != 0UL)
{
    var v = first & 0xFFFFFFFF;
    Console.Out.WriteLine(v);
    first = Next(first, 20);
}