如何从随机池中 select 一个数字,然后使数字无法重新 select
How to select a number from random pool, then make so number can't be reselected
我基本上是想写一个测验作为我的计算机编程课堂作业的一部分,但我 运行 遇到了麻烦。
我希望从 运行dom 池中选择问题以防止作弊,我可以做到 运行domly 在 1,8 之间选择,但这可能会导致提问中重复,这是我不想要的。
Random random = new Random(); // We use this random object to choose random icons for the squares.
List<int> Assignments = new List<int>()
{
1,2,3,4,5,6,7,8
};
Random RandomlyChooseNumbers = new Random();
int AssignmentForQ1;
int AssignmentForQ2;
int AssignmentForQ3;
int AssignmentForQ4;
string CorrectAnswerA1;
string CorrectAnswerA2;
string CorrectAnswerA3;
string CorrectAnswerA4;
public double timePassed;
public int calculatedScore;
public int timeLeft;
public frmQuizOneHardMode()
{
InitializeComponent();
AssignQuestionToTextQ1();
}
private void AssignQuestionToTextQ1()
{
int randomNumber = RandomlyChooseNumbers.Next(Assignments.Count);
AssignmentForQ1 = Assignments[randomNumber];
Assignments.RemoveAt(randomNumber);
AssignmentForQ2 = Assignments[randomNumber];
Assignments.RemoveAt(randomNumber);
AssignmentForQ3 = Assignments[randomNumber];
Assignments.RemoveAt(randomNumber);
AssignmentForQ4 = Assignments[randomNumber];
Assignments.RemoveAt(randomNumber);
}
但由于某种原因,数字总是相同的,这意味着 AssignmentForQ1、Q2、Q3 和 Q4 都显示完全相同的问题,我完全不知道这里出了什么问题,有人可以帮忙吗?
编辑:我个人要感谢 Jamiec,伙计,你真是个救星,没有你我做不到,谢谢!
您已经完成了一半。一般的想法是选择一个随机数,然后删除该元素,这样它就不能被重新选择。但是,为了使所有元素都是随机的,您需要在每次尝试后从缩减集中选择一个 new 随机数。
int randomNumber1 = RandomlyChooseNumbers.Next(Assignments.Count);
AssignmentForQ1 = Assignments[randomNumber1];
Assignments.RemoveAt(randomNumber1);
// set is reduced
int randomNumber2 = RandomlyChooseNumbers.Next(Assignments.Count);
AssignmentForQ2 = Assignments[randomNumber2];
Assignments.RemoveAt(randomNumber2);
这可以通过使用数组进行赋值和循环来简化
int[] Questions = new int[4];
for(var i=0;i<Questions.Length;i++)
{
int randomNumber = RandomlyChooseNumbers.Next(Assignments.Count);
Questions[i] = Assignments[randomNumber];
Assignments.removeAt(randomNumber);
}
TL;DR
不必每次都尝试生成一个随机数,您可以随机化列表并获取第一个 n
项可以满足您的要求。
详情
如果你总共有 20 个问题,但测验只有 10 个,那么随机化 20 个列表和 select 前 10 个。我还建议你创建一个数据结构来存储这些信息,而不仅仅是 AssignmentForQ1
、AssignmentForQ2
等。使用如下内容:
public class Question
{
public int Assignment { get; set; }
public string ActualAnswer { get; set; }
public string SelectedAnswer { get; set; }
public bool IsCorrect
{
get { return String.Equals(ActualAnswer, SelectedAnswer,
StringComparison.InvariantCultureIgnoreCase); }
}
}
public class Quiz
{
public List<Question> Questions { get; set; }
public int CalculatedScore
{
get { return Questions.Count(q => q.IsCorrect); }
}
public DateTime TimeStarted { get; set; }
public TimeSpan TimeAllowed { get; set; }
public TimeSpan TimeRemaining
{
get { return DateTime.Now - (TimeStarted + TimeAllowed); }
}
public TimeSpan TimeElapsed
{
get { return DateTime.Now - TimeStarted; }
}
}
然后将它们存储在 List<Question>
中并像这样随机化它:
Random rand = new Random();
List<Question> questions = new List<Question>();
var myQuiz = new Quiz
{
TimeAllowed = TimeSpan.FromMinutes(15),
Questions = questions.OrderBy((q) => rand.Next()).Take(10).ToList()
};
这会给你 10 个随机问题,没有重复!虽然这不是最优化的洗牌,但它只是完成了工作。查看 this answer 以获取有关如何安全有效地随机排列列表的更详细说明。
最后,尝试使用类封装你的数据,它会让事情变得更容易理解和扩展。
我基本上是想写一个测验作为我的计算机编程课堂作业的一部分,但我 运行 遇到了麻烦。
我希望从 运行dom 池中选择问题以防止作弊,我可以做到 运行domly 在 1,8 之间选择,但这可能会导致提问中重复,这是我不想要的。
Random random = new Random(); // We use this random object to choose random icons for the squares.
List<int> Assignments = new List<int>()
{
1,2,3,4,5,6,7,8
};
Random RandomlyChooseNumbers = new Random();
int AssignmentForQ1;
int AssignmentForQ2;
int AssignmentForQ3;
int AssignmentForQ4;
string CorrectAnswerA1;
string CorrectAnswerA2;
string CorrectAnswerA3;
string CorrectAnswerA4;
public double timePassed;
public int calculatedScore;
public int timeLeft;
public frmQuizOneHardMode()
{
InitializeComponent();
AssignQuestionToTextQ1();
}
private void AssignQuestionToTextQ1()
{
int randomNumber = RandomlyChooseNumbers.Next(Assignments.Count);
AssignmentForQ1 = Assignments[randomNumber];
Assignments.RemoveAt(randomNumber);
AssignmentForQ2 = Assignments[randomNumber];
Assignments.RemoveAt(randomNumber);
AssignmentForQ3 = Assignments[randomNumber];
Assignments.RemoveAt(randomNumber);
AssignmentForQ4 = Assignments[randomNumber];
Assignments.RemoveAt(randomNumber);
}
但由于某种原因,数字总是相同的,这意味着 AssignmentForQ1、Q2、Q3 和 Q4 都显示完全相同的问题,我完全不知道这里出了什么问题,有人可以帮忙吗?
编辑:我个人要感谢 Jamiec,伙计,你真是个救星,没有你我做不到,谢谢!
您已经完成了一半。一般的想法是选择一个随机数,然后删除该元素,这样它就不能被重新选择。但是,为了使所有元素都是随机的,您需要在每次尝试后从缩减集中选择一个 new 随机数。
int randomNumber1 = RandomlyChooseNumbers.Next(Assignments.Count);
AssignmentForQ1 = Assignments[randomNumber1];
Assignments.RemoveAt(randomNumber1);
// set is reduced
int randomNumber2 = RandomlyChooseNumbers.Next(Assignments.Count);
AssignmentForQ2 = Assignments[randomNumber2];
Assignments.RemoveAt(randomNumber2);
这可以通过使用数组进行赋值和循环来简化
int[] Questions = new int[4];
for(var i=0;i<Questions.Length;i++)
{
int randomNumber = RandomlyChooseNumbers.Next(Assignments.Count);
Questions[i] = Assignments[randomNumber];
Assignments.removeAt(randomNumber);
}
TL;DR
不必每次都尝试生成一个随机数,您可以随机化列表并获取第一个 n
项可以满足您的要求。
详情
如果你总共有 20 个问题,但测验只有 10 个,那么随机化 20 个列表和 select 前 10 个。我还建议你创建一个数据结构来存储这些信息,而不仅仅是 AssignmentForQ1
、AssignmentForQ2
等。使用如下内容:
public class Question
{
public int Assignment { get; set; }
public string ActualAnswer { get; set; }
public string SelectedAnswer { get; set; }
public bool IsCorrect
{
get { return String.Equals(ActualAnswer, SelectedAnswer,
StringComparison.InvariantCultureIgnoreCase); }
}
}
public class Quiz
{
public List<Question> Questions { get; set; }
public int CalculatedScore
{
get { return Questions.Count(q => q.IsCorrect); }
}
public DateTime TimeStarted { get; set; }
public TimeSpan TimeAllowed { get; set; }
public TimeSpan TimeRemaining
{
get { return DateTime.Now - (TimeStarted + TimeAllowed); }
}
public TimeSpan TimeElapsed
{
get { return DateTime.Now - TimeStarted; }
}
}
然后将它们存储在 List<Question>
中并像这样随机化它:
Random rand = new Random();
List<Question> questions = new List<Question>();
var myQuiz = new Quiz
{
TimeAllowed = TimeSpan.FromMinutes(15),
Questions = questions.OrderBy((q) => rand.Next()).Take(10).ToList()
};
这会给你 10 个随机问题,没有重复!虽然这不是最优化的洗牌,但它只是完成了工作。查看 this answer 以获取有关如何安全有效地随机排列列表的更详细说明。
最后,尝试使用类封装你的数据,它会让事情变得更容易理解和扩展。