【问题标题】:Creating a random order for my quiz questions为我的测验问题创建随机顺序
【发布时间】:2012-02-13 10:02:20
【问题描述】:

我创建了一个测验应用程序,并使用 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();
            }
    }
}

【问题讨论】:

  • 您要查找的关键字是“shuffle”。也就是说,随机重新排序列表而不进行替换。您想重新排列问题列表(在您的代码中,问题似乎只是由ints 标识,因此是ints 的列表)。

标签: c# list random


【解决方案1】:

为了确保每个问题只被问一次,我会使用两个列表:AnsweredQuestionsUnansweredQuestions

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

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

这样你的随机化器只使用那些真正没有答案的问题。

【讨论】:

  • 感谢您的建议。这仍然适用于我在 switch 语句中提出的问题。 private void QuestionSelection(int intQuestionNo) { switch (intQuestionNo) { case 1: labelQuestion.Text = "谁制作了横幅"; checkBox1.Text = "Sungard"; checkBox2.Text = "麦当劳"; checkBox3.Text = "阿斯达"; checkBox4.Text = "苹果";休息;尝试将这些问题放入带有 checkbox.text 答案的列表中可以证明是一项正确的任务?
  • 抱歉,将代码放入评论框不太好,因为我是新用户,我无法再创建新帖子 8 小时
  • @user1206484:我根本不会采用这种方法,因为那非常不灵活。如果您需要将问题的数量更改为 50 或 1000,您会怎么做?这个怎么样:随机数是您在“未回答问题”列表中的问题的索引。该问题提供了每个答案和正确的解决方案作为属性。然后,您可以将问题提供给将这些属性分配给适当 CheckBox 的方法。通过这样做,您可以获得一种灵活的方法,从不关心您有多少问题。
【解决方案2】:

你为什么不把所有的问题都放在一个列表中,然后随机播放:

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;
}

【讨论】:

    【解决方案3】:

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

    为了方便起见,我使用了 BitArray。最好使用按位 & 和 |运营商。 结果被打包到一个 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);
    }
    

    【讨论】:

      猜你喜欢
      • 2015-11-22
      • 1970-01-01
      • 1970-01-01
      • 2017-04-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-17
      • 1970-01-01
      相关资源
      最近更新 更多