[英]Randomisation of multidimensional array in C#
對於一個小型項目,我正在制作測驗程序。我當前的(相對)代碼如下:
static Random _r = new Random();
static int Quiz()
{
string[,] QAndA = {
{"What is the capital of France", "Paris"},
{"What is the capital of Spain", "Madrid"},
...
{"What is the captial of Russia", "Moscow"},
{"What is the capital of Ukraine", "Kiev"},
};
for (int i = 0; i < NUM_QUESTIONS; i++)
{
int num = _r.Next(QAndA.GetLength(0) / 2);
Question(QAndA[num, 0], QAndA[num, 1]);
}
}
現在,明顯的問題是可以重復隨機數,這意味着可以重復問題。
現在,我的老師(是的,這是學校的事情)告訴我尋找改組算法,但是我找不到適合我所使用的多維數組的算法。
我是一個相當新的C#程序員,但是我有使用c ++的經驗,並且該程序是命令行程序(目前是:)),如果那很重要/有幫助的話
因此,問題是,將多維數組重新排序/改組為隨機順序的最佳方法是什么?
您正在尋找錯誤的問題。 而不是多維數組(因為很少支持,所以很少使用)使用鋸齒數組。
string[][] questions = new[] {
new [] {"What is the capital of France", "Paris"},
new [] {"What is the capital of Spain", "Madrid"},
new [] {"What is the captial of Russia", "Moscow"},
new [] {"What is the capital of Ukraine", "Kiev"},
};
// use: questions[0][0] (question), questions[0][1] (answer), questions[1][0] (question)...
或(更好)創建一個具有兩個成員的類Question
and Answer
。
class QuestionAndAnswer
{
public string Question { get; protected set; }
public string Answer { get; protected set; }
public QuestionAndAnswer(string question, string answer)
{
this.Question = question;
this.Answer = answer;
}
}
QuestionAndAnswer[] questions = new QuestionAndAnswer[] {
new QuestionAndAnswer("What is the capital of France", "Paris"),
new QuestionAndAnswer("What is the capital of Spain", "Madrid"),
// ...
};
// use: questions[0].Question, questions[0].Answer...
然后,您可以使用Knuth算法:-)
從那里報價:
To shuffle an array a of n elements (indexes 0..n-1):
for i from n − 1 downto 1 do
j ← random integer with 0 ≤ j ≤ i
exchange a[j] and a[i]
在C#中,算法類似於
Random rnd = new Random();
for (int i = questions.Length - 1; i >= 1; i--)
{
// Random.Next generates numbers between min and max - 1 value, so we have to balance this
int j = rnd.Next(0, i + 1);
if (i != j)
{
var temp = questions[i];
questions[i] = questions[j];
questions[j] = temp;
}
}
我建議不要使用“多維”數組,如果它不是多維數組。
我的建議:(請在此處實時查看http://ideone.com/NsjfM )
using System;
using System.Linq;
using System.Collections.Generic;
public class Program
{
struct QA { public string Q, A; }
static Random _r = new Random();
static int Quiz()
{
var QAndA = new QA[] {
new QA { Q = "What is the capital of France" , A = "Paris"},
new QA { Q = "What is the capital of Spain" , A = "Madrid"},
// ...
new QA { Q = "What is the captial of Russia" , A = "Moscow"},
new QA { Q = "What is the capital of Ukraine" , A = "Kiev"},
};
foreach (var qa in QAndA.OrderBy(i => _r.Next()))
{
Question(qa.Q, qa.A);
}
return 0;
}
public static void Main(string[] args)
{
int n = Quiz();
}
private static void Question(string q, string a)
{
Console.WriteLine("Q. {0}", q);
Console.WriteLine("A. {0}", a);
}
}
maybe better (without shouffling, without repeatable questions):
class QuizQuestion
{
public string Question {get; set;}
public string Answer {get; set;}
}
static Random _r = new Random();
static int Quiz()
{
QuizQuestion[] QAndA = new QuizQuestion[] {
new QuizQuestion() {Question = "What is the capital of France", Answer = "Paris"},
new QuizQuestion() {Question = "What is the capital of Spain", Answer ="Madrid"},
...
new QuizQuestion() {Question = "What is the captial of Russia", Answer ="Moscow"},
new QuizQuestion() {Question = "What is the capital of Ukraine", Answer ="Kiev"},
};
var questions = QAndQ.ToList();
for (int i = 0; i < NUM_QUESTIONS; i++)
{
int num = _r.Next(questions.Length / 2);
Question(questions[num].Question, questions[num].Answer);
questions.Remove(questions[num]);
}
}
實際上,您正在重新排序一個二元數組,因為您不應該整理答案;)最簡單的算法可能是:
foreach array index
switch with random index in array
不需要重新排列數組的方法,並且如果您只需要選擇幾個問題,則該方法會更快,該方法是將選擇的問題存儲在一組中。
繼續生成隨機數,並在集合大小正確后將其添加到集合的索引處。
您的循環將類似於:
var questions = new HashSet<Question>();
while (questions.Count < numberOfQuestionsRequired)
{
questions.Add(questionArray[_r.Next()])
}
HashSet<>.Count
和HashSet<>.Add()
均為O(1),因此限制因素將是碰撞了多少個隨機數。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.