この記事では、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 サイトの他の関連記事を参照してください。