I've a 5x5 2D array filled like this :
-----
-----
-----
-----
I'm trying to fill this array by percentage, for example 40% :
-e--e
---f-
-i-h-
-ghh-
---ii
As you can see 40 % of 25 is 10 so 10 characters have been added to the array, my code is :
private static char[][] fillArrayWithThisPercentage(int percentage, char[][] arrayOfChars, char startChar, char endChar) {
int size = 5;
int arraySize = size * size;
float percentageOfSize = (percentage / 100f * arraySize);
int filled = 0;
while (filled <= percentageOfSize) {
int i = getRandomNumber(size);
int j = getRandomNumber(size);
arrayOfChars[i][j] = getRandomChar(startChar, endChar);
filled ;
}
}
Get a random character in range of two characters :
private static char getRandomChar(char startChar, char endChar) {
String alphabet = "a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z";
List<String> alphabetList = Arrays.asList(alphabet.split(","));
int max = alphabetList.indexOf(startChar "");
int min = alphabetList.indexOf(endChar "");
int randomNumber = (int) ((Math.random() * (max - min)) min);
return alphabetList.get(randomNumber).charAt(0);
}
Output :
b----
--db-
--a--
-----
a----
CodePudding user response:
You're implementing the brute force approach, which is fine for a SMALL matrix. Just keeping picking spots until you find one that is available:
private static void fillArrayWithThisPercentage(int percentage, char[][] arrayOfChars, char startChar, char endChar) {
int size = 5;
int arraySize = size * size;
int percentageOfSize = (int)(percentage / 100f * arraySize);
int filled = 0;
while (filled < percentageOfSize) {
int i;
int j;
do {
i = getRandomNumber(size);
j = getRandomNumber(size);
} while (arrayOfChars[i][j] != '-');
arrayOfChars[i][j] = getRandomChar(startChar, endChar);
filled ;
}
}
Note that I changed the return type to void
and also changed your percentageOfSize
to an int
and made it while (filled < percentageOfSize)
.
CodePudding user response:
As I suggested in the comments above, you can first fill out the array with the values from beginning, and then shuffle an array. First, we need to fill 5x5 array with given number of characters (10 in your case), so resulting array will look like this:
a b c d e
f g h i j
. . . . .
. . . . .
. . . . .
Then, we need to randomly shuffle this array. Several options are possible here. One option may look like this:
- for every first N symbols in array // N = 40% of array capacity in your case
- randomly choose a new pair of coordinates
- swap that symbol with a symbol in chosen coordinates;
The task is greatly simplified if you present your two-dimensional array in the form of a one-dimensional array.
private static void fillArrayWithThisPercentage(int percentage, char[][] arrayOfChars, char startChar, char endChar) {
int size = arrayOfChars.length;
int percentageOfSize = (int)(percentage / 100 * size * size);
Random random = new Random();
// fill entire array with '-' symbol
for (var line : arrayOfChars) {
Arrays.fill(line, '-');
}
// place N random chars to array from beginning
for (int i = 0; i < percentageOfSize; i ) {
arrayOfChars[i / size][i % size] = (char) random.nextInt(startChar, endChar);
}
// shuffle an array
for (int i = 0; i < percentageOfSize; i ) {
int newPosition = random.nextInt(size * size);
swap(arrayOfChars, i, newPosition);
}
}
private static void swap(char[][] arr, int i, int j) {
char temp = arr[i / arr.length][i % arr.length];
arr[i / arr.length][i % arr.length] = arr[j / arr.length][j % arr.length];
arr[j / arr.length][j % arr.length] = temp;
}
You may test this approach with something like this:
char[][] arr = new char[5][5];
fillArrayWithThisPercentage(40, arr, 'a', 'z');
for (var row : arr) {
System.out.println(Arrays.toString(row));
}