确保相同的列表输出不会出现两次

问题描述:

我正在制作一种自我测验,在其中添加问题然后自测。确保相同的列表输出不会出现两次

我希望能够得到所有的问题给你(随机如果可能的话)。 我已经有所作为,但偶尔会遗漏一些问题或重复它们。

public void LoadUp() { 
    if(TimeLimit) { 
     timer2.Start(); 
    } 

    KeyWords.Clear(); 
    Hint_Used=false; 
    int QuestionCount=correct+incorrect; 
    int AnswerCount=Study_Helper.Form1.QuizList.Count; 
    Random random=new Random(); 
    int randomNumber=random.Next(0, Study_Helper.Form1.QuizList.Count); 

    if(!Study_Helper.Form1.PreviousQuestions.Contains(randomNumber)) { 
     Study_Helper.Form1.PreviousQuestions.Add(randomNumber); 
     String raw=Study_Helper.Form1.QuizList[randomNumber].ToString(); 
     String[] Split=raw.Split(new char[] { '|' }); 
     Question=Split[0]; 
     richTextBox1.Text=Question; 
     Answer=Split[1]; 
     Hint=Split[2]; 
     String[] NewSplit=Split[3].Split(new char[] { ',' }); 
     int TotalKeywords=0; 

     foreach(string s in NewSplit) { 
      TotalKeywords++; 
     } 

     for(int size=0; size<TotalKeywords-1; size++) { 
      String KeyWord=NewSplit[size].ToString(); 
      KeyWords.Add(KeyWord); 
     } 
    } 
    else if(QuestionCount>=AnswerCount) { 
     int Total=correct-incorrect; 

     if(Total<0) { 
      Total=0; 
     } 

     timer2.Stop(); 
     Counter=Study_Helper.Form4.Counter; 
     Form6 form6=new Form6(); 
     form6.Show(); 
     TimeLimit=false; 
     MessageBox.Show("Study Questions over! you got "+Total+" in total, that's "+correct+" correct answers!", "Results", MessageBoxButtons.OK, MessageBoxIcon.Information); 
     correct=0; 
     incorrect=0; 
     this.Close(); 
    } 
} 

它的作用是将随机数添加到保存它的列表中,并检查是否已经包含它。我觉得我失去了一些明显的东西来流利地做这项工作。

+0

请编辑代码片段,只留下*有意义的*部分。 – abatishchev 2013-02-10 05:06:39

最简单的方法是随机化列表,然后按顺序开始处理。

var randomizedList = Study_Helper.Form1.QuizList.OrderBy(a => Guid.NewGuid()); 

foreach(var question in randomizedList) 
{ 
    //Handle displaying the question. 
} 

这是什么东西做的是“排序”名单,但因为我们是给分拣机一个新的随机 Guid每次所以它会随机列表。然后,我们可以使用这个混乱的测验来完成剩下的代码。

1.这不是一种随机的“安全”方式,因为某人可以对输出进行密码分析以预测问题的顺序,但是您并不试图加密保护,而只是试图争夺测验问题和这个解决方案已经够好了。有关更多信息,请参阅this SO question关于洗牌的更多信息。

我认为使用PreviousQuestions跟踪所有的指标是复杂的自己。我建议在开始时对指数进行洗牌,因此一旦用这种方法初始化堆栈,您只需拨打randomNumbers.Pop()即可获得一个新的随机数。

Stack<int> ShuffleNumbers(int count) 
{ 
    IEnumerable<int> range = Enumerable.Range(0, count); 
    Random rnd = new Random(); 
    return new Stack<int>(range.OrderBy(x => rnd.Next())); 
}