Replacing values of a two dimensional array - java

I have a given two dimensional array of doubles, called imgMatrix and I'm trying to make a new two dimensional array of integers either 1 or 0, depending on the values of the doubles in imgMatrix (value <= 0.5 makes a 0 in the new array; value > 0.5 makes a 1 in the new array).
Here's the code I have so far:
int[][] newMatrix = new int[imgMatrix.length][];
for (a=0; a <= imgMatrix.length; a++) {
for (b=0; b <= imgMatrix[a].length; b++) {
for (c=0; c <= imgMatrix[a].length; c++) {
if (imgMatrix[a][c] <= 0) {
newMatrix[a][c] = 0;
}
else {
newMatrix[a][c] = 1;
}
}
}
}
Obviously something is wrong. Can anybody help me correct this?

do following changes into your code,
int[][] newMatrix = new int[imgMatrix.length][];
for (int a=0; a < imgMatrix.length; a++) { // remove = from older code
newMatrix[a] = new int[imgMatrix[a].length];
for (int b=0; b < imgMatrix[a].length; b++) { // remove = from older code
//remove : for (c=0; c <= imgMatrix[a].length; c++) {
if (imgMatrix[a][b] <= 0.5) {
newMatrix[a][b] = 0;
}
else {
newMatrix[a][b] = 1;
}
// remove : }
}
}

Related

Java – Working with 2 dimensional array and constructor (Beginner)

This post is going to be really long, but I would be so glad if the community can help me.
This is a question from a former class test. I have to expect a similar one this time and I'm currently stuck. I'm new to Java and its concepts.
The result of the test should look like this:
The result
I'm facing multiple problems at once. I will try to be as specific as I can. First I will explain the task, which has given conditions that can't be changed.
The task
Create an array field with 2 dimensions. The field should work with various sizes. Besides the size, the array field should contain the following pattern(see picture).
1.) Create an constructor that creates a rectangle array field from the parameter passed in, with to extra conditions.
1.1) If the parameter is less than 5, the field should be forced to appear as a 5/5 field.
1.2) If the paramter is more than 5 it should always appear as an n/n array.
public class Pattern {
char[][] field;
public Pattern(int n) {
// Here goes my code for creating the field
}
2.) Write a method that fills the constructor.
public void fillArray() {
// Here goes my code.
}
My approach so far
public Pattern(int n) {
field = new char[n][n];
int i, j;
if (field.length < 5) {
for (i = 1; i <= 5; i++) {
for (j = 1; j <= 5; j++) {
// ? what to do with the array here?
}
System.out.println();
}
}
public void fillArray() {
// no fu**ing idea...
}
public static void main (String[]args){
Pattern cross = new Pattern(2);
cross.fillArray();
System.out.println(cross);
}
Questions
1.) What value should be returned in the constructor?
2.) How can I access the object in the method and set a for loop, that gets the predefined field size? Should I use this ?
I'm sorry for my bad understanding on how to pass array information and execute these correctly.
public class Pattern {
private final int size;
private final char[][] field;
public Pattern(int n) {
size = Math.max(n, 5);
field = new char[size][size];
}
public void fillArray() {
for (int row = 0, i = size - 1; row < size; row++, i--) {
for (int col = 0, j = size - 1; col < size; col++, j--) {
if (row == col || row == j)
field[row][col] = '*';
else if (col > row)
field[row][col] = col < i ? '1' : '2';
else
field[row][col] = col > i ? '3' : '4';
}
}
}
public void print() {
for (int row = 0; row < size; row++) {
for (int col = 0; col < size; col++)
System.out.print(field[row][col] == '\0' ? ' ' : field[row][col]);
System.out.println();
}
}
public static void main(String... args) {
Pattern cross = new Pattern(2);
cross.fillArray();
cross.print();
}
}
You are putting what should be in fillArray in the constructor. The constructor should just be this:
public Pattern(int n) {
if (n < 5) {
field = new char[5][5];
} else {
field = new char[n][n];
}
}
And the two for loops should be in the fillArray method:
public void fillArray() {
// you should loop until field.length and field[x].length
for (int x = 0; x < field.length; x++) {
for (int y = 0; y < field[x].length; y++) {
// ...
}
}
}
Try to write your own logic of how to fill in the array.
If you are stuck, here is my solution:
for (int x = 0 ; x < field.length ; x++) {
for (int y = 0 ; y < field[x].length ; y++) {
/*
The '1' area can be represented by these inequalities:
x - y < 0
x + y < array.length - 1
The '2' area can be represented by these inequalities:
x - y < 0
x + y > array.length - 1
The '3' area can be represented by these inequalities:
x - y > 0
x + y > array.length - 1
The '4' area can be represented by these inequalities:
x - y > 0
x + y < array.length - 1
Everywhere that does not satisfy any of the inequalities are *s
*/
int xMinusY = x - y;
int xPlusY = x + y;
if (xMinusY < 0 && xPlusY < field.length - 1) {
field[x][y] = '1';
} else if (xMinusY < 0 && xPlusY > field.length - 1) {
field[x][y] = '2';
} else if (xMinusY > 0 && xPlusY > field.length - 1) {
field[x][y] = '3';
} else if (xMinusY > 0 && xPlusY < field.length - 1) {
field[x][y] = '4';
} else {
field[x][y] = '*';
}
}
}
// ...
// printing the array out:
for (int x = 0 ; x < field.length ; x++) {
for (int y = 0 ; y < field.length ; y++) {
System.out.print(field[x][y]);
}
System.out.println();
}
Answers to your questions:
Constructors does not return anything.
You don't need to use "this" since the 2-dimensional array is a field which can be accessed anywhere in the class Pattern. If you want to access the size of the array, you can use field.length.
Before you fill the array, you should first check if n is less than 5 (if it is, it should be set to 5). This is done in the constructor. Then you create the array.
After that, you have the for loops in which you have to figure out how to create the pattern. This should be done in the fillArray method.
Okay, so here is the solution. To get this kind of patterns draw it first on paper, then just write the columns and rows and search for the Pattern.
The only way you can learn this is by practice.
A constructor is like a method but does not have a return and uses the name of the Class.
The constructor will be always called when you instanciate a new Object of that class.
Example:
Pattern p = new Pattern(3);
Leave the constructor for the things you will need to do when you create an Object of that class. In your case decide the size of your Pattern.
Example:
public Pattern(int fS) { //fS = fieldSize
if (fS < 5)
fS = 5;
field = new char[fS][fS];
}
Then you have the methods, once an Object is created you can use all the methods from his Instance. In your case you will have a method called "fillArray".
Solution:
public void fillArray() {
int fS = field.length;
char c = ' ';
int len = fS - 1;
for (int row = 0; row < fS; row++)
for (int col = 0; col < fS; col++) {
if (row == col || row + col == len) c = '*';// This will make the asterisc cross
if (row < col && row < len - col) c = '1'; //This will do the 1 part
if (row < col && row > len - col) c = '2'; //This will do the 2 part
if (row > col && row > len - col) c = '3';//This will do the 3 part
if (row > col && row < len - col) c = '4';//This will do the 4 part
field[row][col] = c;
}
}
Remember:
In this case your Array will be not filled until you call the method fillArray()
Example:
Pattern p = new Pattern(7);
p.fillArray();
To print your Pattern I recommend you use the toString() method. You will need to Override it.
How to:
#Override //Important
public String toString() {
StringBuilder s = new StringBuilder();
for (char[] row : field) {
for (char col : row)
s.append("\t").append(col);
s.append("\n");
}
return s.toString();
}
Use the "#Override" tag to see if you did any typo writing the mehod toString. Now to print your pattern use:
Pattern p = new Pattern(7);
p.fillArray();
System.out.println(p); //This line
PD: Sorry if I did any grammar mistake my mother language is not english. Hope it helps.

Get all indexes of a multidimensional table

I am having trouble to create a (recursive) function that prints all possible indexes for a multi dimensional table.
I got the information about the multi-dimensionality as an array.
Example:
int[]{6,6} would be a 2-dimensional table with 6x6 = 36 fields, so the result would be [0,0],[0,1],[1,1],[1,2],[2,2]... and so on.
Another example:
int[]{2,2,2} would be a 3-dimensional table with 8 possible indexes: [0,0,0],[0,0,1],[0,1,1]... and so on
I'm trying to do this in Java 7.
Edit: As requested, what I got so far. Code is producing OutOfBound Exception.
loop(new int[2], new int[]{6, 6}, 0);
private void loop(int[] index, int[] dimensionSizes, int dimensionIndex) {
if (index[dimensionIndex] < dimensionSizes[dimensionIndex] && dimensionIndex < dimensionSizes.length) {
System.out.println(Arrays.toString(index));
index[dimensionIndex] = index[dimensionIndex] + 1;
if (index[dimensionIndex] < dimensionSizes[dimensionIndex]) {
loop(index, dimensionSizes, dimensionIndex);
} else {
loop(index, dimensionSizes, dimensionIndex + 1);
}
}
}
I think this code could respond to your question:
public static void printAllIndex(int[] dimensions) {
int[] index = new int[dimensions.length];
int stepNumber = 0;
// Initialization
for (int i : index) { index[i] = 0; } // init index to 0
for (int d : dimensions) { stepNumber += d; } // count number of iteration needed
System.out.println(Arrays.toString(index)); // print first index [0,0,...]
for(int s = 0; s <= stepNumber - 1; s++) {
boolean allEquals = true;
int value = index[index.length - 1];
for (int i = index.length - 1; i >= 0; i--) {
if(index[i] != value) {
index[i]++;
allEquals = false;
break;
}
}
if (allEquals) { index[index.length - 1]++; }
System.out.println(Arrays.toString(index));
}
}

How to determine if numbers in an array list if divisible by the numbers in another array list?

I am trying to determine if the numbers in an array list are divisiable by all of numbers in antoher arraylist. My code below outputs all of the numbers from the listdiv list that are disible by any divisors in the listdivisor. I would like to output the values that are divisible by all divisiors in the list not any of them. For example If I have listdiv = [1,2,3,,5,8] and listdivisor= [2,4]. the expected output should be 8 , but this code outputs 2 and 8 .
Thank you !your effort will be greatly appreciated!
for (int i = 0; i < listdiv.size(); i++) {
for (int c = 0; c < listdivisor.size(); c++) {
if (listdiv.get(i) % listdivisor.get(c) == 0) {
System.out.println("final results are : " + listdiv.get(i));
}
}
}
Other way with java 8:
List<Integer> collect = listdiv.stream().filter(p ->
listdivisor.stream().allMatch(d -> p % d == 0)
).collect(Collectors.toList());
Or better performance with parallelStream():
List<Integer> collect = listdiv.parallelStream().filter(p ->
listdivisor.parallelStream().allMatch(d -> p % d == 0)
).collect(Collectors.toList());
Your error appears to be caused by that you were counting a dividend as being divisible by all divisors upon hitting the first matching divisor. Instead, you need to add logic which keeps track of all divisors and ensures that each one works with a given dividend.
System.out.println("final results are: ");
for (int i=0; i < listdiv.size(); i++) {
boolean isDivisible = true;
for (int c=0; c < listdivisor.size(); c++) {
if (listdiv.get(i) % listdivisor.get(c) != 0) {
isDivisible = false;
break;
}
}
if (isDivisible) {
System.out.println(listdiv.get(i));
}
}
Your condition checks for values divisible by at least a single divisor, which is not what you want.
You need to check all the divisors before generating output :
for (int i = 0; i < listdiv.size(); i++) {
boolean divisible = true;
for (int c = 0; c < listdivisor.size() && divisible; c++) {
if (listdiv.get(i) % listdivisor.get(c) != 0) {
divisible = false;
}
}
if (divisible) {
System.out.println("final results are : " + listdiv.get(i));
}
}
In the below solution I continue the outer for loop when an element from the first list is not divisible to any in the second list. If no such case happens the println will get called.
outer:
for (int i = 0; i < listdiv.size(); i++) {
for (int c = 0; c < listdivisor.size(); c++) {
if (listdiv.get(i) % listdivisor.get(c) != 0) {
continue outer;
}
}
System.out.println("Found : " + listdiv.get(i));
}
This solution doesn't need any extra variables (such as a boolean to keep status of divisibility) and uses the less known loop labels
All the algorithms presented so far are O(N*M). It is possible to get O(N+M) by first finding the LCM of the first list and using that to filter the second list.
int thelcm = 1
for(int i : listdivisor) {
thelcm = lcm(thelcm, i);
}
ArrayList<Integer> result = new ArrayList<>();
for(int j : listdiv) {
if( j % thelcm == 0 ) {
result.put(j);
}
}
We can use Set for getting the expected output, I have modified your code,
Set<Integer> firstIteration = new HashSet<>();
Set<Integer> nextIteration = new HashSet<>();
for (int c = 0; c < divisors.size(); c++) {
for (int i = 0; i < numbers.size(); i++) {
if (numbers.get(i) % divisors.get(c) == 0) {
if (c == 0) {
firstIteration.add(numbers.get(i));
} else {
nextIteration.add(numbers.get(i));
}
}
}
if (c != 0) {
// We will perform Set intersection here for each iteration
firstIteration.retainAll(nextIteration);
}
}
System.out.println(firstIteration);
Hope this will solve your issue

Shuffle the order of a 2D array in java

I'm creating my own memory game. Everything is going well so far. Just to let you know I'm using processing for Java. I have created a 2 dim PImage array. This is the code for filling the 2D array:
int g = 0;
for(int i = 0; i < 4; i++) {
for (int j = 0; j < 6; j++) {
if (j % 2 == 0) {
kaart[i][j] = loadImage( g + ".jpg" );
kaart[i][j].resize(vlakGrootte - 1, vlakGrootte - 1);
g++;
} else if (j % 2 == 1) {
kaart[i][j] = kaart[i][j-1];
}
}
}
I want the items in this array to be shuffled. It seems like java collections does not support to shuffle a 2D PImage array? Please correct me if im wrong.
Thanks to you all for helping me out.
1).Shuffle per-outter index :
YourType [][] kaart = new YourType [..][..];
List <YourType[]> list = (List<YourType[]> ) Arrays.asList(kaart);
Collections.shuffle(list);
kaart = (YourType[][]) list.toArray(new YourType[0][]);//convert back to a array
// just for checking
for(YourType[] k:kaart ){System.out.println(Arrays.toString(k));}
Replace YourType with the type of kaart.
2). Shuffle per-Outter+Inner index :
YourType[][] kaart = new YourType[..][..];
List<YourType[]> temp = new ArrayList<>();
for(YourType[] k:kaart ){
List <YourType> list = (List<YourType> ) Arrays.asList(k);
Collections.shuffle(list);//shuffle
YourType[] tempArray = (YourType[]) list.toArray();
temp.add(tempArray);
}
Collections.shuffle(temp);
kaart= (YourType[][]) temp.toArray(new YourType[0][]);//convert back to a array
// just for checking
for(YourType[] k:kaart ){System.out.println(Arrays.toString(k)); }
Replace YourType with the type of kaart.
3). Shuffle in The easiest way:
Just put all elements into a single List then call Collections.shuffle()
I would do this the same way you would deal those cards in real world. First you shuffle the deck:
ArrayList<Integer> pieces = new ArrayList<Integer>();
for (int i = 0; i < 4 * 6 / 2; i++) {
for (int j = 0; j < 2; j++) {
pieces.add(i);
}
}
Collections.shuffle(pieces);
Then you deal cards out of shuffled deck:
for(int i = 0; i < 4; i++) {
for (int j = 0; j < 6; j++) {
int g = pieces.remove(pieces.size()-1);
kaart[i][j] = loadImage( g + ".jpg" );
kaart[i][j].resize(vlakGrootte - 1, vlakGrootte - 1);
}
}

Completely stumped on a multiple loop Java program

The following is NOT a homework problem, it's just a set of problems that I've been working through for practice and I was wondering if anybody else could figure it out:
http://codingbat.com/prob/p159339
Return an array that contains exactly the same numbers as the given array, but rearranged so that every 3 is immediately followed by a 4. Do not move the 3's, but every other number may move. The array contains the same number of 3's and 4's, every 3 has a number after it that is not a 3 or 4, and a 3 appears in the array before any 4.
*SOLVED - here is my working code:
public int[] fix34(int...nums)
{
int[] returnArray = new int[nums.length];
//ASSIGN ARRAY
//We know that all 3's can't be moved, and after every 3 there
//will automatically be a 4
for(int i = 0; i<nums.length; i++)
{
if(nums[i] == 3)
{
returnArray[i] = 3;
returnArray[i+1] = 4;
}
}
//REBUILD ARRAY - UNMOVED INDEXES
//If a value was not moved/affected by the above, it will get placed into the array
//in the same position
for (int i = 0; i < nums.length; i++)
{
if (returnArray[i] != 3 && returnArray[i] != 4 && nums[i] != 3 && nums[i] != 4)
{
returnArray[i] = nums[i];
}
}
//REBUILD ARRAY - MOVED INDEXES
//changed values = 0 in returnArray, as a result, any time we hit a 0 we
//can simply assign the value that was in the 4's place in the nums array
OuterLoop: for (int i = 0; i < nums.length; i++)
{
if (returnArray[i] == 0)
{
for (int n = 0; n < returnArray.length; n++)
{
if (returnArray[n] == 4)
{
returnArray[i] = nums[n];
continue OuterLoop;
}
}
}
}
return returnArray;
}
I don't know java, but maybe I can help anyway. i dont want to give you the solution, but think of it like this:
you can move every number that isn't a 3. that's our only limit. that being said:
the only spots you need to change are the spots following 3s....so....every time you loop through, your program should be aware if it finds a spot after a 3 that isn't a 4....
it should also be aware if it finds any 4s not preceded by a 3......
during each loop, once it's found the location of each of those two things, you should know what to do.
Initialize all the variables
for(int i = 0; i<n-1; i++)
{
if(arr[i] == 3)
{
if(arr[i+1] == 4)
continue;
else
{
temp = 0;
while(arr[temp] != 4)
temp++;
//Write your own code here
}
//Complete the code
}
I have NOT provided the entire code. Try completing it as you said it was for your practice.
public int[] fix34(int[] nums) {
int[] arr = new int[nums.length];
int index = 0;
int tempVal= 0,j=0;
for(int i=0;i<nums.length;i++){
if(nums[i]==3){
arr[i] = nums[i];
index=i+1;
tempVal = nums[i+1];
j=index;
while(j<nums.length){
if(j<nums.length && nums[j]==4){
//System.out.println(j+"\t="+nums[j]);
nums[j]=tempVal;
nums[index] = 4;
break;
}
j++;
}
tempVal=0;
index=0;
}else{
arr[i] = nums[i];
}
}
index =0;
for(int i=0;i<nums.length;i++){
if(nums[i]==3 && nums[i+1]==4){
i+=1;
}else if(nums[i]==4){
index = i;
j=index;
while(j<nums.length){
if(nums[j]==3 && nums[j+1]!=4){
arr[index] = nums[j+1];
arr[j+1] = 4;
}
j++;
}
}
}
return arr;
}
Here's mine: A little overkill, but is always right, anyways i make 2 additional arrays and I make 2 passes in the loop putting the correct elements in the correct places. See Logic Below.
public int[] fix34(int[] nums) {
int index1 = 0;
int index2 = 0;
int index3 = 0;
int[] only4 = fours(nums); //holds all 4's in nums
int[] misc = new int[count4(nums)]; //will hold numbers after 3
for(int a = 0; a < nums.length - 1; a++){
if(nums[a] == 3){
misc[index1] = nums[a + 1]; //get it for later use
index1++;
nums[a + 1] = only4[index2]; //now the number after 3 is a 4, from the
index2++; //only4 array
}
}
for(int b = 1; b < nums.length; b++){
if(nums[b] == 4 && nums[b - 1] != 3){ //finds misplaced 4's
nums[b] = misc[index3]; //replaces lone 4's with the
index3++; //right hand side of each 3 original values.
}
}
return nums;
}
public int count4(int[] nums){
int cnt = 0;
for(int e : nums){
if(e == 4){
cnt++;
}
}
return cnt;
}
public int[] fours(int[] nums){
int index = 0;
int[] onlyFours = new int[count4(nums)]; //must set length
for(int e : nums){
if(e == 4){
onlyFours[index] = e;
index++;
}
}
return onlyFours;
}
I solved mine using two ArrayLists which contain the places of 3's and 4's.
I hope this helps.
public int[] fix34(int[] nums)
{
//Create a copy of nums to manipulate.
int[] ret = nums;
//Create two ArrayLists which carry corresponding places of 3 and 4;
ArrayList<Integer> threePositions = new ArrayList<Integer>();
ArrayList<Integer> fourPositions = new ArrayList<Integer>();
//Get the places of 3 and 4 and put them in the respective ArrayLists.
for (int i = 0; i < ret.length; i++)
{
if (ret[i] == 3)
{
threePositions.add(i);
}
if (ret[i] == 4)
{
fourPositions.add(i);
}
}
//Swap all ints right after the 3 with one of the 4s by using the referenced
//ArrayLists values.
for (int i = 0; i < threePositions.size(); i++)
{
int temp = ret[threePositions.get(i) + 1];
ret[threePositions.get(i) + 1] = ret[fourPositions.get(i)];
ret[fourPositions.get(i)] = temp;
}
//Return the ret array.
return ret;
}

Categories