ホームページ  >  記事  >  Java  >  Javaで非反復乱数を生成する方法のまとめ

Javaで非反復乱数を生成する方法のまとめ

尚
オリジナル
2019-11-25 10:24:128025ブラウズ

Javaで非反復乱数を生成する方法のまとめ

この記事では、JAVA でランダムな非反復数値の関数を実装する方法を紹介します。 (関連ビデオ コースの推奨事項: Java ビデオ チュートリアル)

この質問の意味をよりよく理解するために、まず具体的な内容を見てみましょう: 1 ~ 100 のランダムな配列を生成します。ただし、配列内の数値を繰り返すことはできません。つまり、位置はランダムですが、配列要素を繰り返すことはできません。

ここでは、配列の長さは指定されていません。1 ~ 100 の間の任意の長さにすることができます。

次に、いくつかの実装方法を見て、これらの方法を比較してみましょう。

通常は、ArrayList または配列を使用して実装します。まず、次のコードに示すように、ArrayList の実装プロセスを見てみましょう:

import java.util.ArrayList;
import java.util.Random;

/**
 * 使用ArrayList实现
 * @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();
        ArrayList<Integer> list = new ArrayList<Integer>();

        for(int i = 0; i < values.length;i++){
            int number = random.nextInt(100) + 1;
            
            if(!list.contains(number)){
                list.add(number);
            }
        }
        
        values = list.toArray();
        
        // 遍历数组并打印数据
        for(int i = 0;i < values.length;i++){
            System.out.print(values[i] + "\t");
            
            if(( i + 1 ) % 10 == 0){
                System.out.println("\n");
            }
        }
    }
}

配列実装を使用するプロセスは次のとおりです。

import java.util.Random;

/**
 * 使用数组实现
 * @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;
                }                              
            }
        }
        
        // 遍历数组并打印数据
        for(int i = 0;i < values.length;i++){
            System.out.print(values[i] + "\t");
            
            if(( i + 1 ) % 10 == 0){
                System.out.println("\n");
            }
        }
    }
}

上記の 2 つの実装プロセスは比較的非効率です。追加するたびに、その数値が現在のリストに存在するかどうかを調べる必要があり、時間計算量は O(N^2) になるためです。次のように考えることができます。重複がないので、HashSet と HashMap の機能を考えることができます。

HashSet は Set インターフェイスを実装します。Set の数学的定義は、重複や順序のないコレクションです。 HashMap は Map を実装しており、重複したキーを許可しません。このようにして、HashMap または HashSet を使用してそれを実現できます。

HashMap を使用して実装する場合、次のコードに示すように、そのキーを配列に変換するだけで済みます。

import java.util.HashMap;
import java.util.Iterator;
import java.util.Random;
import java.util.Map.Entry;

/**
 * 使用HashMap实现
 * @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<Object, Object> hashMap = new HashMap<Object, Object>();
        
        // 生成随机数字并存入HashMap
        for(int i = 0;i < values.length;i++){
            int number = random.nextInt(100) + 1;
            hashMap.put(number, i);
        }
        
        // 从HashMap导入数组
        values = hashMap.keySet().toArray();
        
        // 遍历数组并打印数据
        for(int i = 0;i < values.length;i++){
            System.out.print(values[i] + "\t");
            
            if(( i + 1 ) % 10 == 0){
                System.out.println("\n");
            }
        }
        
//        Iterator iter = hashMap.entrySet().iterator();
//        // 遍历HashMap
//        while (iter.hasNext()) {
//            Entry<Integer, Integer> entry = (Entry)iter.next();
//            int key = entry.getKey();
//            n++;
//            
//            System.out.print(key + "\t");
//            
//            if(n % 10 == 0){
//                System.out.println("\n");
//            }
//        }
    }
}

HashSet と HashMap の関係が近すぎるため、HashSet は最下層で使用される HashMap が実装されていますが、Value コレクションはなく、Key コレクションのみがあるため、次のコードに示すように HashSet を使用して実装することもできます。

import java.util.HashSet;
import java.util.Random;

/**
 * 使用HashSet实现
 * @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];
        HashSet<Integer> hashSet = new HashSet<Integer>();
        
        // 生成随机数字并存入HashSet
        for(int i = 0;i < values.length;i++){
            int number = random.nextInt(100) + 1;
            hashSet.add(number);
        }
        
        values = hashSet.toArray();
        
        // 遍历数组并打印数据
        for(int i = 0;i < values.length;i++){
            System.out.print(values[i] + "\t");
            
            if(( i + 1 ) % 10 == 0){
                System.out.println("\n");
            }
        }
    }
}

この実装はわずかに効率的です。 。配列の長さを制限する場合は、for ループを変更して whlie ループに設定するだけで済みます。以下に示すように:

import java.util.HashSet;
import java.util.Random;

/**
 * 使用HashSet实现
 * @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];
        HashSet<Integer> hashSet = new HashSet<Integer>();
        
        // 生成随机数字并存入HashSet
        while(hashSet.size() < values.length){
            hashSet.add(random.nextInt(100) + 1);
        }
        
        values = hashSet.toArray();
        
        // 遍历数组并打印数据
        for(int i = 0;i < values.length;i++){
            System.out.print(values[i] + "\t");
            
            if(( i + 1 ) % 10 == 0){
                System.out.println("\n");
            }
        }
    }
}

上記と比較すると、HashMap の使用効率は比較的高く、実際には、HashSet、配列、ArrayList の順に使用されます。 10,000 個のデータを生成すると、HashMap の使用時間は 0.05 秒、HashSet は 0.07 秒、配列は 0.20 秒、ArrayList は 0.25 秒であることがわかります。興味がある場合は、時間を設定して確認することができます。

もちろん、HashMap の使用に加えて、他の効率的な方法もあります。たとえば、1 ~ 100 の数値を配列に格納し、for ループで 2 つの添字をランダムに生成し、2 つの添字が等しくない場合は、配列内の要素を交換できます。実装プロセスは次のとおりです。

import java.util.Random;

/**
 * 随机调换位置实现
 * @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;
        }
        
        //随机交换values.length次   
        for(int i = 0;i < values.length;i++){   
            temp1 = Math.abs(r.nextInt()) % (values.length-1); //随机产生一个位置   
            temp2 = Math.abs(r.nextInt()) % (values.length-1); //随机产生另一个位置   
            
            if(temp1 != temp2){
                temp3 = values[temp1];   
                values[temp1] = values[temp2];   
                values[temp2] = temp3;
            } 
        }   
        
        // 遍历数组并打印数据
        for(int i = 0;i < 20;i++){
            System.out.print(values[i] + "\t");
            
            if(( i + 1 ) % 10 == 0){
                System.out.println("\n");
            }
        }
    }
}

その他の Java 関連記事については、Java 基本チュートリアル を参照してください。

以上がJavaで非反復乱数を生成する方法のまとめの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。