我有一个问题清单可以由系统按随机顺序排列,但同时检查某些问题需要在另一个问题之前提出。
q1 before q4, q3 before q2
我还必须确保在那里没有类似的东西:
q1 before q4, q3 before q2, q2 before q1, q4 before q2
我不完全确定如何做到这一点。
存储这个的方法我作为一个例子给出了一个数组数组let n: number[number, number][]
答案 0 :(得分:0)
如果你很懒,我就是这样,因为只有几个问题,我会随机排序问题并检查规则,如果它违反了规则,只需再次运行。
如果这是一个家庭作业并且你被标记为懒惰,你可以创建一个函数,将问题随机地分配给一个数组中的插槽,从必须跟随其他问题开始,然后减少随机数生成器的范围,必须小于最大的随机生成位置,必须大于出现的位置。
例如:
假设你有一系列长度为5的问题,q1必须出现在q3之前,而q4必须出现在q2之前。首先将q3置于长度为5的数组中的随机位置,假设poition为2.然后将q1随机分配给小于2的位置。对每组规则执行此操作,每次分配一个数字时将其从完成所有规则后,RNG会运行其他问题。
您可以将约束表示为元组,第一个字符串表示必须先出现的问题,第二个字符串表示必须排在第二位的问题。 rules: number[][] = [['q1', 'q3], ['q4', 'q2']]
将是您的规则,每次从元组中分配问题时,您将在问题数组questions: string[] = ['q1', 'q2', ...]
中获得所有问题。使用splice获取字符串的索引将其从问题数组中删除。下面是一些应该使用这两种数据类型的代码,请注意我使用了一系列可用的索引来排除以前选择的索引:
questions: string[]; // put all questions here.
rules: string[][]; // put all less than rules as tuples here,
// i.e. q1 must come before q2 written as [['q1', 'q2'],...]
randomizer(): string[] {
const arr = new Array<string>(this.questions.length);
const availableIndices = [];
let rand: number;
for (let i = 0; i < arr.length; i++) {
availableIndices.push(i)
}
for (const tuple of rules) {
rand = Math.floor(Math.random() * availableIndices.length)
arr[availableIndices[rand]] = tuple[1];
questions.splice(indexOf(tuple[1]), 1);
availableIndices.splice(indexOf(rand), 1);
rand = Math.floor(Math.random() * availableIndices.indexOf(tuple[1]))
arr[availableIndices[rand]] = tuple[0];
questions.splice(indexOf(tuple[2]), 1);
availableIndices.splice(indexOf(rand), 1);
}
for (const q of questions) {
rand = Math.floor(Math.random() * availableIndices.length);
arr[availableIndices[rand]] = q;
availableIndices.splice(indexOf(rand), 1);
}
return arr;
}
此算法为O(n),因此您的老师不能抱怨。