Fill array with zero in random places - java

So, what I am trying to do is to fill a 2D array with zeros in random places a specific amount of times. Let's say that it has to be 20 zeros in an array of 90 places. What I have done so far is to declare a 2D array and fill it with random numbers. And my next thought was to simply choose random positions and replace them with zeros. Any idea how I could do that?
int[][] myboard = new int[9][9];
for (int i = 0; i < myboard.length; i++) {
for (int j = 0; j < myboard[i].length; j++) {
myboard[i][j] = (int) (Math.random() * 10);
}
}

It is a rather simple way to achieve the goal, but it should do the job. So you need to get the length of each row. After you have done that you can call a function that will give you a random number between some start point and the length of the row. Here is some code sample to show you what I mean:
import java.util.concurrent.ThreadLocalRandom;
import java.util.Arrays;
public class Example {
public static void main(String []args) {
int[][] myboard = new int[9][9];
for (int i = 0; i < myboard.length; i++) {
for (int j = 0; j < myboard[i].length; j++) {
// fill the row with random vals
myboard[i][j] = GetRandomNumber(0, myboard[i].length);
}
// sneak as much zeros as your heart content
int random = GetRandomNumber(0, myboard[i].length);
myboard[i][random] = 0;
}
System.out.println(Arrays.deepToString(myboard));
}
private static int GetRandomNumber(int min, int max) {
/*
min is the start point
max is the curr row len
*/
return ThreadLocalRandom.current().nextInt(min, max);
}
}

A pseudo code would look like:
while (num_zeros_filled < 20):
row = random()%total_rows
col = random()%total_cols
if (arr[row][col] == 0): # already filled in with 0
continue
else:
arr[row][col] = 0
num_zeros_filled += 1
This, however, could take infinite time theoretically if only those cells are generated which have already been filled with 0. A better approach would be to map the two-dimensional array into a 1-d array, and then sample out only from those cells which haven't been filled with 0 yet.

Related

How to rotate 2-D Array in Java

[SOLVED]
The title of this question is vague but hopefully this will clear things up.
Basically, what I am looking for is a solution to rotating this set of data. This data is set up in a specific way.
Here is an example of how the input and output would look like:
Input:
3
987
654
321
Output:
123
456
789
The '3' represents the number of columns and rows that will be used. If you input the number '4', you will be allowed to input 4 sets of 4 integers.
Input:
4
4567
3456
2345
1234
Output:
1234
2345
3456
4567
The goal is to find a way to rotate the data only if needed. You have to make sure the smallest corner number is at the top left. For example, for the code above, you rotated it so 1 is at the top left.
The problem I have is that I don't know how to rotate the data. I am only able to rotate the corners but not the sides. This is what my code does so far:
take the input of each line and turn them into strings
split those strings into separate characters
store those characters in an array
I just do not know how to compare those characters and in the end rotate the data.
Any help would be appreciated! Any questions will be answered.
A detailed description of the problem is here(problem J4).
This is just a challenge I assigned myself for practice for next year's contest, so giving me the answer won't "spoil" the question, but actually help me learn.
Here is my code so far:
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner kb = new Scanner(System.in);
int max = kb.nextInt();
int maxSqrt = (max * max);
int num[] = new int[max];
String num_string[] = new String[max];
char num_char[] = new char[maxSqrt];
int counter = 0;
int counter_char = 0;
for (counter = 0; counter < max; counter++) {
num[counter] = kb.nextInt();
}
for (counter = 0; counter < max; counter++) {
num_string[counter] = Integer.toString(num[counter]);
}
int varPos = 0, rowPos = 0, charPos = 0, i = 0;
for (counter = 0; counter < maxSqrt; counter++) {
num_char[varPos] = num_string[rowPos].charAt(charPos);
i++;
if (i == max) {
rowPos++;
i = 0;
}
varPos++;
if (charPos == (max - 1)) {
charPos = 0;
} else {
charPos++;
}
}
//
for(int a = 0 ; a < max ; a++){
for(int b = 0 ; b < max ; b++)
{
num_char[counter_char] = num_string[a].charAt(b);
counter_char++;
}
}
//here is where the code should rotate the data
}
}
This is a standard 90 degree clockwise rotation for a 2D array.
I have provided the solution below, but first a few comments.
You said that you're doing this:
take the input of each line and turn them into strings
split those strings into separate characters
store those characters in an array
Firstly youre essentially turning a int matrix into a character matrix. I do not think you need to do this, since even if you do want to compare values, you can use the ints provided.
Secondly, there is no need to compare any 2 data elements in the matrix, since the rotation does not depend on any value.
Here is an adapted solution for java, originally written in C# by Nick Berardi on this question
private int[][] rotateClockWise(int[][] matrix) {
int size = matrix.length;
int[][] ret = new int[size][size];
for (int i = 0; i < size; ++i)
for (int j = 0; j < size; ++j)
ret[i][j] = matrix[size - j - 1][i]; //***
return ret;
}
If you wanted to do a counterCW rotation, replace the starred line with
ret[i][j] = matrix[j][size - i - 1]

How can I create a new instance of array dynamically if my array size is full in java

I am working on a java program. where I have taken an input string and I am putting each char from a string in a 4*4 matrix. If the input string length is small than 16 i.e 4*4 matrix, then I am adding padding '#' char.
But Now, suppose the input string length is more than 16 then I want to create a new array and put remaining chars into it. I can't use a vector, set, map. So How can I code now?
here is some code. key=4.
char[][] giveMeNewArray() {
char[][] matrix = new char[key][key];
return matrix;
}
void putCharIntoMatrix() {
int counter = 0;
char[][] myArray = giveMeNewArray();
System.out.println("myArray: " + myArray);
for (int i = 0; i < key; i++) {
for (int j = 0; j < key; j++) {
if (counter >= inputString.length()) {
myArray[i][j] = '#';
} else {
myArray[i][j] = inputString.charAt(key * i + j);
}
counter++;
}
}
for (int i = 0; i < key; i++) {
for (int j = 0; j < key; j++) {
System.out.print(myArray[i][j] + " ");
}
System.out.println();
}
}
So if I'm understanding this question correctly, you want to create a matrix to hold the characters of an input string, with a minimum size of 4*4?
You're probably better off creating a proper matrix rather than expanding it:
Do you want your matrix to always be square?
Get the next-highest (self-inclusive) perfect square using Math.sqrt
int lowRoot = (int)Math.sqrt(inString.length());
int root;
if(lowRoot * lowRoot < inString.length())
root = lowRoot+1;
else
root = lowRoot;
Create your matrix scaled for your input, minimum four
int size = (root < 4) ? 4 : root;
char[][] matrix = new char[size][size];
But if you really want to expand it, you can just create a new matrix of a greater size:
char[][] newMatrix = new char[oldMatrix.length+1][oldMatrix[0].length+1];
And copy the old matrix into the new matrix
for(int i = 0; i < oldMatrix.length; ++i){
for(int j = 0; j < oldMatrix[i].length; ++j){
newMatrix[i][j] = oldMatrix[i][j];
}
}
If you expand by one each time you'll do tons of expands, if you expand by more you might expand too far.
This is really inefficient versus just doing some math at the beginning. Making a properly sized matrix from the start will save you a bunch of loops over your data and regularly having two matrices in memory.
If understand you request correctly, if the string length is bigger than 16 you just create a new array, well how about making a list of array initilized at one array and if there are more than 16 chars just add an array to the list using your method that returns an array.

Generation of 4 non repeating random numbers using arrays in java

I have this array
int [] marc = new int[4];
i need to insert a set of non repeating random numbers in the range of 1-10 to it
i'm using this for loop to set random numbers
for (he = 0; he < 4; he++) {
marc[he] = rn.nextInt(10 - 1 + 1) + 1;
marc[he]++;
}
it gives me random numbers but repeated ones inside the array
i'm also using
java.util.Random;
Well, yes, numbers can be repeated while being random. You need to do your own logic to validate if they're already on the array, this can be done with the following code:
In the code I used an array of 10 elements to observe there aren't repeated numbers even on that situation.
import java.util.Random;
public class RandomNumbersNoRepeating {
public static void main(String[] args) {
int array[] = new int[10];
Random random = new Random();
//Fills the array
for (int i = 0; i < array.length; i++) {
boolean found = false;
int r = 0;
do {
found = false;
r = random.nextInt(10) + 1;
//Here we check if the number is not on the array yet
for (int j = 0; j < array.length; j++) {
if (array[j] == r) {
found = true;
break;
}
}
} while (found);
array[i] = r;
}
//Prints the array
for (int i = 0; i < array.length; i++) {
System.out.println(array[i]);
}
}
}
Another possible solution, as given in a comment could be to shuffle an array from 1-10, and get the first four numbers
Using java.util.Random; will generate repetitive numbers more often when your range is small, which in your case is only 10. There is no condition in your code that checks whether the generated random number already exists in your array or not.
Before inserting a generated number in to the array, you first need to check whether that number already exists in your array. If it does not, you insert that number in the array, otherwise you generate a next random number.

How to fill a 2D array with random non duplicate numbers in Java

I'm having a hard time figuring out how to fill my 2D array with random numbers without duplicates. I currently have it filed with random numbers within the correct range, but I just cant think of a solution to have non duplicates. How could i do this using very basic java methods? I have not yet learned anything such as arraylists, or anything like that, only the very basic methods.
Given a MxN integer array, you could fill the array with numbers from 1 to M*N using two for-loops, and then swap them using the Fisher-Yates algorithm.
EDIT:
I changed the algorithm so that it now does not create a new integer-array every time the algorithm is called. It uses one loop, and calculates m, n, i j from a random value and the iterating varaible l. Assuming the given array is not null, rectangular and at least 1x0 in size:
public static void fillRandomlyUniqe(int[][] a) {
/*
fill up the array with incrementing values
if the values should start at another value, change here
*/
int value = 1;
for (int i = 0; i < a.length; i++) {
for (int j = 0; j < a[i].length; j++)
a[i][j] = value++;
}
// swap them using Fisher-Yates algorithm
Random r = new Random();
int max = a.length * a[0].length;
for (int l = max - 1; l > 0; l--) {
//calculate a two dimensional index from random number
int index = r.nextInt(l + 1);
int m = index % a.length;
int n = index / a.length;
//calculate two dimensional index from the iterating value
int i = l % a.length;
int j = l / a.length;
int temp = a[i][j];
a[i][j] = a[m][n];
a[m][n] = temp;
}
}
If your 2D array is NxM, and you want numbers from (say) 1 to NxM randomly placed in your 2D array, the simplest is to create an array/list with the numbers from 1 to NxM, shuffle it, then fill in your 2D array sequentially from the shuffled data. You are guaranteed to not have any duplicates because the original non-shuffled data is full of unique values.
List<Integer> data = IntStream.rangeClosed(1, M * N).boxed().collect(Collectors.toList());
Collections.shuffle(data);
Iterator<Integer> iter = data.iterator();
for (int i = 0; i < M; i++) {
for (int j = 0; j < N; j++) {
array[i][j] = iter.next();
}
}
There is probably a way to do the second half with the stream API too, but it escapes me at the moment.

Transferring the contents of a one-dimensional array to a two-dimensional array

I'm trying to make an encryption program where the user enters a message and then converts the "letters into numbers".
For example the user enters a ABCD as his message. The converted number would be 1 2 3 4 and the numbers are stored into a one dimensional integer array. What I want to do is be able to put it into a 2x2 matrix with the use of two dimensional arrays.
Here's a snippet of my code:
int data[] = new int[] {10,20,30,40};
*for(i=0;i<2;i++)
{
for(j=0;j<2;j++)
{
for (int ctr=0; ictr<data.length(); ictr++){
a[i][j] = data[ctr];}
}
}
I know there's something wrong with the code but I am really lost.
How do I output it as the following?
10 20
30 40
(instead of just 10,20,30,40)
Here's one way of doing it. It's not the only way. Basically, for each cell in the output, you calculate the corresponding index of the initial array, then do the assignment.
int data[] = new int[] {10, 20, 30, 40, 50, 60};
int width = 3;
int height = 2;
int[][] result = new int[height][width];
for(int i = 0; i < height; i++) {
for(int j = 0; j < width; j++) {
result[i][j] = data[i * width + j];
}
}
Seems like you want to output a 2xn matrix while still having the values stored in a one-dimensional array. If that's the case then you can to this:
Assume the cardinality m of your set of values is known. Then, since you want it to be 2 rows, you calculate n=ceil(m/2), which will be the column count for your 2xn matrix. Note that if m is odd then you will only have n-1 values in your second row.
Then, for your array data (one-dimension array) which stores the values, just do
for(i=0;i<2;i++) // For each row
{
for(j=0;j<n;j++) // For each column,
// where index is baseline+j in the original one-dim array
{
System.out.print(data[i*n+j]);
}
}
But make sure you check the very last value for an odd cardinality set. Also you may want to do Integer.toString() to print the values.
Your code is close but not quite right. Specifically, your innermost loop (the one with ctr) doesn't accomplish much: it really just repeatedly sets the current a[i][j] to every value in the 1-D array, ultimately ending up with the last value in the array in every cell. Your main problem is confusion around how to work ctr into those loops.
There are two general approaches for what you are trying to do here. The general assumption I am making is that you want to pack an array of length L into an M x N 2-D array, where M x N = L exactly.
The first approach is to iterate through the 2D array, pulling the appropriate value from the 1-D array. For example (I'm using M and N for sizes below):
for (int i = 0, ctr = 0; i < M; ++ i) {
for (int j = 0; j < N; ++ j, ++ ctr) {
a[i][j] = data[ctr];
}
} // The final value of ctr would be L, since L = M * N.
Here, we use i and j as the 2-D indices, and start ctr at 0 and just increment it as we go to step through the 1-D array. This approach has another variation, which is to calculate the source index explicitly rather than using an increment, for example:
for (int i = 0; i < M; ++ i) {
for (int j = 0; j < N; ++ j) {
int ctr = i * N + j;
a[i][j] = data[ctr];
}
}
The second approach is to instead iterate through the 1-D array, and calculate the destination position in the 2-D array. Modulo and integer division can help with that:
for (int ctr = 0; ctr < L; ++ ctr) {
int i = ctr / N;
int j = ctr % N;
a[i][j] = data[ctr];
}
All of these approaches work. Some may be more convenient than others depending on your situation. Note that the two explicitly calculated approaches can be more convenient if you have to do other transformations at the same time, e.g. the last approach above would make it very easy to, say, flip your 2-D matrix horizontally.
check this solution, it works for any length of data
public class ArrayTest
{
public static void main(String[] args)
{
int data[] = new int[] {10,20,30,40,50};
int length,limit1,limit2;
length=data.length;
if(length%2==0)
{
limit1=data.length/2;
limit2=2;
}
else
{
limit1=data.length/2+1;
limit2=2;
}
int data2[][] = new int[limit1][limit2];
int ctr=0;
//stores data in 2d array
for(int i=0;i<limit1;i++)
{
for(int j=0;j<limit2;j++)
{
if(ctr<length)
{
data2[i][j] = data[ctr];
ctr++;
}
else
{
break;
}
}
}
ctr=0;
//prints data from 2d array
for(int i=0;i<limit1;i++)
{
for(int j=0;j<limit2;j++)
{
if(ctr<length)
{
System.out.println(data2[i][j]);
ctr++;
}
else
{
break;
}
}
}
}
}

Categories

Resources