这是this post的新版本,以便将编程问题与概率问题隔离开来。
我想存储一些例如在阵列中随机生成25个1到365之间的数字。但我需要跟踪重复。以下是我在考虑这样做的方式:
创建4个数组:一个主数组,一个包含2个重复数组的数组,一个包含3个重复数组的数组和一个包含3个以上重复项的数组
将每个生成的数字逐个添加到主数组中。但在此之前,循环遍历数组以查看它是否已存在。如果是这样,请将其添加到第二个数组,但在此之前重复上述过程,依此类推
在过程结束时,我可以计算每个数组中的非空值,以了解我有多少个唯一数字,有多少出现两次等等
它似乎不是一个非常有效的算法。有任何改进建议吗?
我建议的方法可以被认为是大O(n),即线性吗?
答案 0 :(得分:2)
为什么使用数组? HashMap或其他地图结构似乎更有意义。我就是这样做的。
现在,您可以获取由散列映射中的键数生成的唯一日期数,以及有关值中重复数的任何信息。
答案 1 :(得分:1)
以下是我认为问题可以解决的方法。
希望这有帮助。
答案 2 :(得分:0)
in ruby:
birthdays = {}.tap{|h| h.default = 0}
25.times { birthdays[rand(364)+1] += 1 }
puts birthdays.keys # all the uniq birthdays
puts birthdays.inspect # all birthdays with counts
想法是使用散列或固定大小的数组,其中键对应于生日,值是选择生日的次数
问题是你会失去生日的顺序,因为它们只是哈希/数组中的键,但如果原始顺序不重要,你可以随时通过
获得随机生日序列birthdays.keys.shuffle
答案 3 :(得分:0)
根据您需要生成随机列表的次数,您可以考虑创建所有数字的列表,然后使用shuffle sort置换它们,然后您可以从阵列中拉出连续的块,这将是两者都是随机顺序和独特的。因此,在最坏的情况下,性能将是O(大小所有数字)+ O(所需数字的大小),最佳情况是O(所需数字的大小)。一个例子:
private int[] numbers;
private int numberIndex=Integer.MAX_VALUE;
private void initNumbers(){
int[] numbers = new int[365];
for(int i=0;i<365;i++){
numbers[i] = i+1;
}
shuffleSort(numbers);
numberIndex = 0;
}
public int[] getRandom(int howMany){
if(numberIndex > numbers.length-howMany){
initNumbers();
}
int[] ret = new int[howMany];
for(int i=0;i<howMany;i++){
ret[i] = numbers[numberIndex++];
}
return ret;
}
private void shuffleSort(int[] numbers){
Random r = new Random();
int tmp=0, swap=0;
for(int i=numbers.length-1;i>0;i--){
swap = r.nextInt(i);//random number between 0 and i
tmp = numbers[i];
numbers[i] = numbers[swap];
numbers[swap] = tmp;
}
}
}