在指定的范圍內,生成不重復的隨機數序列(排除法,篩選法)
import java.util.ArrayList; import java.util.List; import java.util.Random;/**
在指定的范圍內,生成不重復的隨機數序列 */ public class UnrepeatRandomNumber { private int min; private int max;
public UnrepeatRandomNumber() {
this.min = 0; this.max = 10;
}
public UnrepeatRandomNumber(int min, int max) {
this(); if (max >= min) { this.min = min; this.max = max; } else { System.out.println("max比min小,按缺省值生成UnrepeatRandomNumber對象!"); }
}
/**
- 第一種方法:排除法。隨機生成數字,如果是新生成的數字,則放到結果列表種 否則是已經生成過的,則不加入結果列表,繼續隨機生成。
- @param length
- 結果列表的長度
@return */ public Integer[] getRandomMethodA(int length) { if (length <= 0) {
return new Integer[0];
} else if (length > (this.max - this.min)) {
System.out.println("結果列表長度不能達到:" + length + ", 結果長度只能是:" + (this.max - this.min)); length = this.max - this.min;
} Random rd = new Random();// 用于生成隨機結果 List resultList = new ArrayList(); while (resultList.size() < length) {
// 將[min, max]區間等價于min + [0, max - min + 1) Integer randnum = new Integer(this.min + rd.nextInt(this.max - this.min + 1)); if (!resultList.contains(randnum)) { resultList.add(randnum); }
} // 使用toArray方法將List轉換成對象數組返回 return (Integer[]) resultList.toArray(new Integer[0]); }
/**
- 第二種方法:篩選法。將所有可能被生成的數字放到一個候選列表中。 然后生成隨機數,作為下標,將候選列表中相應下標的數字放到放到結果列表中,
- 同時,把它在候選列表中刪除。
- @param length
- 結果列表的長度
@return */ public Integer[] getRandomMethodB(int length) { if (length <= 0) {
return new Integer[0];
} else if (length > (this.max - this.min)) {
System.out.println("結果列表長度不能達到:" + length + ", 結果長度只能是:" + (this.max - this.min)); length = this.max - this.min;
} // 初始化候選列表,列表長度為 max -min + 1 int candidateLength = this.max - this.min + 1; List candidateList = new ArrayList(); for (int i = this.min; i <= this.max; i++) {
candidateList.add(new Integer(i));
}
Random rd = new Random();// 用于生成隨機下標 List resultList = new ArrayList(); while (resultList.size() < length) {
// 生成下標,在[0,candidateLength)范圍內 int index = rd.nextInt(candidateLength); // 將候選隊列中下標為index的數字對象放入結果隊列中 resultList.add(candidateList.get(index)); // 將下標為index的數字對象從候選隊列中刪除 candidateList.remove(index); // 候選隊列長度減去1 candidateLength--;
} // 使用toArray方法將List轉換成對象數組返回 return (Integer[]) resultList.toArray(new Integer[0]); }
public static void outputArray(Integer[] array) { if (array != null) {
for (int i = 0; i < array.length; i++) { System.out.print(array[i] + " "); }
} System.out.println(); }
public static void main(String[] args) {
UnrepeatRandomNumber test = new UnrepeatRandomNumber(5, 15); outputArray(test.getRandomMethodA(8)); outputArray(test.getRandomMethodB(8)); // 相比之下,第一種方法利用Random對象生成的隨機數的次數比較多,可能生成了20次數字,才能找到10個不一樣的數字。 // 第二種方法利用Random對象生成的隨機數的次數比較少,需要多少個,就生成多少個,保證了每次生成的數字都不重復。 // 也就是說第一種方法在時間花費上更多。但是第二種方法需要初始化一個候選隊列,需要更多的空間花費。 } } </pre>