[英]Insert String elements of array into 2D array randomly Java
int[] howMany = {2, 3, 4};
String[] elements = {"🏠", "🌾", "🌳"};
String[][] village = new String[3][3];
我想從elements
創建一個 2D village
數組。 在howMany
數組中有元素出現的次數。 如何將這些元素(在howMany
中具有最大值)隨機插入到二維數組中?
您可以持有 ArrayList 與村庄中所有可能的元素 go 。
在您的情況下,列表將如下所示:
someList = new ArrayList<String>();
for(int i = 0; i < elements.length; i++) {
for(int j = 0; j < howMany[i]; j++) {
someList.add(elements[i]);
}
}
有了這個,我們就有了一個包含所有可能元素的列表。 現在我們將開始用我們的隨機元素填充矩陣,一個一個地丟棄我們使用的每個元素。
Random rand = new Random();
int n;
for(int x = 0; x < village.length; x++)
for(int y = 0; y < village[0].length; y++)
n = rand.nextInt(someList.size());
village[x][y] = someList.get(n);
someList.remove(n);
}
}
顯然,在我的示例中,您應該導入 Random 和 ArrayList。
如果您將 2D 3x3 數組視為 1D 1x9 數組,則可以使用Collections.shuffle(list)
來獲取其中的隨機元素數。
演示:
public static String[][] generate3x3Village() {
int[] howMany = {2, 3, 4};
String[] elements = {"🏠", "🌾", "🌳"};
String[][] village = new String[3][3];
//1. fill 1x9 array with all necessary elements
String[] tmp = new String[9];
int index = 0;
for (int i = 0; i < elements.length; i++) {
for (int j = 0; j < howMany[i]; j++) {
tmp[index++] = elements[i];
}
}
//2. shuffle
Collections.shuffle(Arrays.asList(tmp));
//3. convert 1x9 array to 3x3 array
for (int i = 0; i < tmp.length; i++) {
village[i / 3][i % 3] = tmp[i];
}
return village;
}
用法:
public static void showVillage(String[][] village) {
for (String[] row : village) {
System.out.println(Arrays.toString(row));
}
}
public static void main(String[] args) throws Exception {
for (int i = 0; i < 3; i++) {//lets see few villages
String[][] village = generate3x3Village();
showVillage(village);
System.out.println("-----------");
}
}
Output:
[🌳, 🌳, 🏠]
[🌾, 🌳, 🌳]
[🏠, 🌾, 🌾]
-----------
[🌳, 🌾, 🌳]
[🌳, 🏠, 🌾]
[🌳, 🏠, 🌾]
-----------
[🌳, 🌳, 🏠]
[🏠, 🌾, 🌳]
[🌳, 🌾, 🌾]
-----------
這是一種方法。 使用 java.util.Random 中的隨機class,只需循環遍歷每個元素,無論它在 howMany 中出現多少次,使用 while 循環遍歷隨機坐標,直到它到達尚未填充的坐標。 用當前元素填充它,然后繼續。
int[] howMany = {2, 3, 4};
String[] elements = {"🏠", "🌾", "🌳"};
String[][] village = new String[3][3];
Random rand = new Random();
for (int i = 0; i < elements.length; i++)
{
for (int j = 0; j < howMany[i]; j++)
{
int x = rand.nextInt(village[0].length);
int y = rand.nextInt(village.length);
while (village[y][x] != null)
{
x = rand.nextInt(village[0].length);
y = rand.nextInt(village.length);
}
village[y][x] = elements[i];
}
}
for (int i = 0; i < village.length; i++)
{
for (int j = 0; j < village[0].length; j++)
{
System.out.print(village[i][j]);
}
System.out.println();
}
這是另一種方法:
int arrSize = 3;
int[] howMany = {2, 3, 4};
String[] elements = {"🏠", "🌾", "🌳"};
String[][] village = new String[arrSize][arrSize];
int[] histogram = new int[arrSize];
for(int i = 0; i < arrSize; i++)
{
for(int j = 0; j < arrSize; j++)
{
boolean found_element = false;
while(!found_element)
{
int randIndex = getRandomNumber(0, arrSize);
if(histogram[randIndex] < howMany[randIndex])
{
village[i][j] = elements[randIndex];
histogram[randIndex]++;
found_element = true;
}
}
}
}
for(int i = 0; i < arrSize; i++)
{
for(int j = 0; j < arrSize; j++)
{
System.out.printf(village[i][j]);
}
System.out.println();
}
這是'getRandomNumber' function:
public static int getRandomNumber(int min, int max) {
return (int) ((Math.random() * (max - min)) + min);
}
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
static void buildVillage(int[] howMany, String[] elements, String[][] village) {
List<Integer> flatElIds = IntStream.range(0, howMany.length)
.flatMap(i -> IntStream.range(0, howMany[i]).map(__ -> i)).boxed().collect(Collectors.toList());
Collections.shuffle(flatElIds);
String[] flatElements = flatElIds.stream().map(x -> elements[x]).toArray(String[]::new);
for (int i = 0, xs = village[0].length, ys = village.length; i < ys; i++)
village[i] = Arrays.copyOfRange(flatElements, i * xs, (i + 1) * xs);
}
我喜歡Aleksa的答案和 Pshemo的答案。
以下是他們主題的三個變體。 這里沒有大的突破,但也許很有趣。
record
Java 16 提供了新的記錄功能。 記錄是編寫 class 的簡單方法,其主要目的是透明且不可變地通信數據。 編譯器隱式創建構造函數、getter、 equals
& hashCode
和toString
。
我們可以使用記錄來匹配輸入對,表情符號字符被用作圖標以及我們希望看到該字符的出現次數。 這使我們的意圖比使用兩個單獨的 arrays 作為輸入更加清晰和明確。
請注意,可以在方法中本地定義記錄。 (順便說一句,從 Java 16 開始,接口和枚舉也是如此。)
record EmojiCount ( String emoji , int count ) {}
將您的輸入定義為不可修改的列表。
final List < EmojiCount > emojiCounts =
List.of(
new EmojiCount( "🏠" , 2 ) ,
new EmojiCount( "🌾" , 3 ) ,
new EmojiCount( "🌳" , 4 )
);
使用 stream 獲取要生成的所有表情符號字符的計數。
final int countEmoji = emojiCounts.stream().mapToInt( emojiCount -> emojiCount.count ).sum();
// Define the village.
final int width = 3, height = 3;
if ( countEmoji > ( width * height ) ) throw new IllegalStateException( "The village is not large enough to contain all your desired emoji icons. Message # 1348468a-1102-4ad4-bc39-426fbe9c86a3." );
final String[][] village = new String[ width ][ height ];
Collections.nCopies
重復生成我們需要的所有表情符號。 我們可以為每種表情符號制作一個List
,使用Collections.nCopies
來填充每個列表。 我們將這些列表加入到主列表中。 然后通過調用Collections.shuffle
隨機搖動它們。
List < String > emojis = new ArrayList <>( countEmoji );
for ( EmojiCount emojiCount : emojiCounts )
{
emojis.addAll( Collections.nCopies( emojiCount.count , emojiCount.emoji ) );
}
Collections.shuffle( emojis );
我們將這些生成的表情符號分布在我們村庄網格的行和列中,我們的二維數組。 我們只需要一對嵌套的for
循環,以訪問每一行,然后是每一列。 當我們 go 時,我們增加一個索引號來移動我們要放置在網格中的表情符號列表。
int index = 0;
for ( int x = 0 ; x < width ; x++ )
{
for ( int y = 0 ; y < height ; y++ )
{
village[ x ][ y ] = emojis.get( index );
index++;
}
}
最后,轉儲到控制台。 注意緊湊for
循環轉儲二維數組,使用這種 for-each 語法: for ( String[] row: village )
。
System.out.println( "emojis = " + emojis );
String output = Arrays.toString( village );
for ( String[] row : village ) System.out.println( Arrays.toString( row ) );
將所有代碼放在一起。
package work.basil.demo.village;
import java.util.*;
public class App
{
public static void main ( String[] args )
{
// Define the emoji characters we use as icons.
record EmojiCount( String emoji , int count ) {} // New record feature in Java 16. Compact way to write an immutable data-carrier class.
final List < EmojiCount > emojiCounts =
List.of(
new EmojiCount( "🏠" , 2 ) ,
new EmojiCount( "🌾" , 3 ) ,
new EmojiCount( "🌳" , 4 )
);
final int countEmoji = emojiCounts.stream().mapToInt( emojiCount -> emojiCount.count ).sum();
// Define the village.
final int width = 3, height = 3;
if ( countEmoji > ( width * height ) ) throw new IllegalStateException( "The village is not large enough to contain all your desired emoji icons. Message # 1348468a-1102-4ad4-bc39-426fbe9c86a3." );
final String[][] village = new String[ width ][ height ];
// Populate the village.
// Generate all the emoji icons.
List < String > emojis = new ArrayList <>( countEmoji );
for ( EmojiCount emojiCount : emojiCounts )
{
emojis.addAll( Collections.nCopies( emojiCount.count , emojiCount.emoji ) );
}
Collections.shuffle( emojis );
// Lay out the terrain.
int index = 0;
for ( int x = 0 ; x < width ; x++ )
{
for ( int y = 0 ; y < height ; y++ )
{
village[ x ][ y ] = emojis.get( index );
index++;
}
}
// Dump to console.
System.out.println( "emojis = " + emojis );
String output = Arrays.toString( village );
for ( String[] row : village ) System.out.println( Arrays.toString( row ) );
}
}
跑的時候。
emojis = [🌳, 🌳, 🌳, 🏠, 🌾, 🌳, 🌾, 🌾, 🏠]
[🌳, 🌳, 🌳]
[🏠, 🌾, 🌳]
[🌾, 🌾, 🏠]
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.