java怎么實(shí)現(xiàn)隨機(jī)不重復(fù)數(shù)字?針對(duì)這個(gè)問題,這篇文章給出了相對(duì)應(yīng)的分析和解答,希望能幫助更多想解決這個(gè)問題的朋友找到更加簡(jiǎn)單易行的辦法。
創(chuàng)新互聯(lián)公司是專業(yè)的東麗網(wǎng)站建設(shè)公司,東麗接單;提供網(wǎng)站設(shè)計(jì)制作、成都網(wǎng)站設(shè)計(jì),網(wǎng)頁(yè)設(shè)計(jì),網(wǎng)站設(shè)計(jì),建網(wǎng)站,PHP網(wǎng)站建設(shè)等專業(yè)做網(wǎng)站服務(wù);采用PHP框架,可快速的進(jìn)行東麗網(wǎng)站開發(fā)網(wǎng)頁(yè)制作和功能擴(kuò)展;專業(yè)做搜索引擎喜愛的網(wǎng)站,專業(yè)的做網(wǎng)站團(tuán)隊(duì),希望更多企業(yè)前來合作!
為了更好地理解這個(gè)題意,我們先來看下具體內(nèi)容:生成一個(gè)1-100的隨機(jī)數(shù)組,但數(shù)組中的數(shù)字不能重復(fù),即位置是隨機(jī)的,但數(shù)組元素不能重復(fù)。
在這里呢,沒有給我們規(guī)定數(shù)組的長(zhǎng)度,我們可以讓它是1-100之間的任意長(zhǎng)度。
接下來讓我們看一下幾種實(shí)現(xiàn)方法并對(duì)這幾種方法作個(gè)對(duì)比。
通常我們會(huì)使用ArrayList或數(shù)組來實(shí)現(xiàn),先來看下ArrayList實(shí)現(xiàn)過程,如下面代碼所示:
import java.util.ArrayList; import java.util.Random; /** * 使用ArrayList實(shí)現(xiàn) * @Description: * @File: Demo.java * @Date 2012-10-18 下午06:16:55 * @Version V1.0 */ public class Demo { public static void main(String[] args) { Object[] values = new Object[20]; Random random = new Random(); ArrayListlist = new ArrayList (); for(int i = 0; i < values.length;i++){ int number = random.nextInt(100) + 1; if(!list.contains(number)){ list.add(number); } } values = list.toArray(); // 遍歷數(shù)組并打印數(shù)據(jù) for(int i = 0;i < values.length;i++){ System.out.print(values[i] + "\t"); if(( i + 1 ) % 10 == 0){ System.out.println("\n"); } } } }
使用數(shù)組實(shí)現(xiàn)的過程如下所示代碼:
import java.util.Random; /** * 使用數(shù)組實(shí)現(xiàn) * @Description: * @File: Demo4.java * @Package None * @Author Hanyonglu * @Date 2012-10-18 下午06:27:38 * @Version V1.0 */ public class Demo4 { public static void main(String[] args) { int[] values = new int[20]; Random random = new Random(); for(int i = 0;i < values.length;i++){ int number = random.nextInt(100) + 1; for(int j = 0;j <= i;j++){ if(number != values[j]){ values[i]=number; } } } // 遍歷數(shù)組并打印數(shù)據(jù) for(int i = 0;i < values.length;i++){ System.out.print(values[i] + "\t"); if(( i + 1 ) % 10 == 0){ System.out.println("\n"); } } } }
上面這兩個(gè)實(shí)現(xiàn)過程效率比較低的。因?yàn)樵诿看翁砑訒r(shí)都要去遍歷一下當(dāng)前列表中是否存在這個(gè)數(shù)字,時(shí)間復(fù)雜度是O(N^2)。我們可以這樣思考一下:既然涉及到無重復(fù),我們可以想一下HashSet和HashMap的功能。
HashSet實(shí)現(xiàn)Set接口,Set在數(shù)學(xué)上的定義就是無重復(fù),無次序的集合。而HashMap實(shí)現(xiàn)Map,也是不允許重復(fù)的Key。這樣我們可以使用HashMap或HashSet來實(shí)現(xiàn)。
在使用HashMap實(shí)現(xiàn)時(shí),只需要將它的key轉(zhuǎn)化成數(shù)組就Ok了,如下代碼:
import java.util.HashMap; import java.util.Iterator; import java.util.Random; import java.util.Map.Entry; /** * 使用HashMap實(shí)現(xiàn) * @Description: * @File: Demo.java * @Package None * @Author Hanyonglu * @Date 2012-10-18 下午06:12:50 * @Version V1.0 */ public class Demo { public static void main(String[] args) { int n = 0; Object[] values = new Object[20]; Random random = new Random(); HashMap
由于HashSet和HashMap的關(guān)系太近了,HashSet在底層就是用HashMap來實(shí)現(xiàn)的,只不過沒有Value的集合,只有一個(gè)Key的集合,所以也可使用HashSet來實(shí)現(xiàn),如下代碼:
import java.util.HashSet; import java.util.Random; /** * 使用HashSet實(shí)現(xiàn) * @Description: * @File: Test.java * @Package None * @Author Hanyonglu * @Date 2012-10-18 下午06:11:41 * @Version V1.0 */ public class Test { public static void main(String[] args) { Random random = new Random(); Object[] values = new Object[20]; HashSethashSet = new HashSet (); // 生成隨機(jī)數(shù)字并存入HashSet for(int i = 0;i < values.length;i++){ int number = random.nextInt(100) + 1; hashSet.add(number); } values = hashSet.toArray(); // 遍歷數(shù)組并打印數(shù)據(jù) for(int i = 0;i < values.length;i++){ System.out.print(values[i] + "\t"); if(( i + 1 ) % 10 == 0){ System.out.println("\n"); } } } }
這樣實(shí)現(xiàn)效率稍微好些。如果給我們限定了數(shù)組的長(zhǎng)度,只需要變換下for循環(huán),設(shè)置成whlie循環(huán)就可以了。如下所示:
import java.util.HashSet; import java.util.Random; /** * 使用HashSet實(shí)現(xiàn) * @Description: * @File: Test.java * @Package None * @Author Hanyonglu * @Date 2012-10-18 下午05:11:41 * @Version V1.0 */ public class Test { public static void main(String[] args) { Random random = new Random(); Object[] values = new Object[20]; HashSethashSet = new HashSet (); // 生成隨機(jī)數(shù)字并存入HashSet while(hashSet.size() < values.length){ hashSet.add(random.nextInt(100) + 1); } values = hashSet.toArray(); // 遍歷數(shù)組并打印數(shù)據(jù) for(int i = 0;i < values.length;i++){ System.out.print(values[i] + "\t"); if(( i + 1 ) % 10 == 0){ System.out.println("\n"); } } } }
以上幾種相比較而言,使用HashMap的效率是比較高的,其實(shí)是HashSet,再次是數(shù)組,最后是ArrayList。如果我們生成10000個(gè)數(shù)據(jù)將會(huì)發(fā)現(xiàn),使用HashMap花費(fèi)時(shí)間是:0.05s,HashSet是0.07s,數(shù)組是:0.20s,而ArrayList是0.25s。有興趣的可以設(shè)置下時(shí)間查看一下。
當(dāng)然了,除了使用HashMap實(shí)現(xiàn)外,還有其它高效的方法。比如,我們可以把1-100這些數(shù)字存儲(chǔ)在一個(gè)數(shù)組中,然后在for循環(huán)中隨機(jī)產(chǎn)生兩個(gè)下標(biāo),如果這兩個(gè)下標(biāo)不相等的話,可以交換數(shù)組中的元素,實(shí)現(xiàn)過程如下所示:
import java.util.Random; /** * 隨機(jī)調(diào)換位置實(shí)現(xiàn) * @Description: * @File: Demo4.java * @Package None * @Author Hanyonglu * @Date 2012-10-18 下午06:54:06 * @Version V1.0 */ public class Demo4 { public static void main(String[] args) { int values[] = new int[100]; int temp1,temp2,temp3; Random r = new Random(); for(int i = 0;i < values.length;i++){ values[i] = i + 1; } //隨機(jī)交換values.length次 for(int i = 0;i < values.length;i++){ temp1 = Math.abs(r.nextInt()) % (values.length-1); //隨機(jī)產(chǎn)生一個(gè)位置 temp2 = Math.abs(r.nextInt()) % (values.length-1); //隨機(jī)產(chǎn)生另一個(gè)位置 if(temp1 != temp2){ temp3 = values[temp1]; values[temp1] = values[temp2]; values[temp2] = temp3; } } // 遍歷數(shù)組并打印數(shù)據(jù) for(int i = 0;i < 20;i++){ System.out.print(values[i] + "\t"); if(( i + 1 ) % 10 == 0){ System.out.println("\n"); } } } }
關(guān)于java實(shí)現(xiàn)隨機(jī)不重復(fù)數(shù)字的方法就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,可以學(xué)到更多知識(shí)。如果覺得文章不錯(cuò),可以把它分享出去讓更多的人看到。