Delete column and row of 2d Array after every iteration - java

wihin an project i need to calculate max value for a given score. Afterwards this particular row and related column should be deleted in order to get just one max value in every row. So my result should look like this:
Result
This is what i have so far.
float max = Float.MIN_VALUE;
int remove_row = firstCluster.size()+1;
int remove_column = firstCluster.size()+1;
float[ ][ ] scores = new float[firstCluster.size()][secondCluster.size()];
for(int i=0; i<scores.length; i++){
if ( i == remove_row)
continue;
for(int j=0; j<scores[i].length; j++){
if ( j == remove_column){
continue;
}
else{
System.out.print(scores[i][j]);
if(scores[i][j] >= max)
{
max = Math.max(max, scores[i][j]);
remove_row = i;
remove_column = j;
System.out.print("Max: "+max);
}
}
}
System.out.println("##############################");
}
The idea is to skip column and row of previous max value but if you are in 3 iteration then you just skip the column and row of previous one and not of all previous iterations. Is there any better way to solve this? I don't need to use necessary 2d array

Just summing up the comments to build a proper answer:
Instead of putting zeroes in the cells, maintain two Set's - usedRows and usedColumns - that keeps tracked of the rows and columns you've crossed out, and ship those using an extra if statement just before if(scores[i][j] >= max)
Remember to reset max in the beginning of each iteraton:
max = Float.MIN_VALUE

Related

Smallest element in largest row

I came across this problem in class and I'm stuck on it. I did plenty of research but I'm not being able to fix my code.
I need to create a matrix and find the smallest value in the row of the largest value (I believe this element is called minimax). I'm trying to do with a simple 3 x 3 matrix. What I have so far:
Scanner val = new Scanner(System.in);
int matrizVal[][] = new int[3][3];
for (int a = 0; a < matrizVal.length; a++) {
for (int b = 0; b < matrizVal.length; b++) {
System.out.print("(" + a + ", " + b + "): ");
matrizVal[a][b] = val.nextInt();
}
}
int largest = matrizVal[0][0];
int largestrow = 0;
int arr[] = new int[2];
for (int row = 0; row < matrizVal.length; row++){
for (int col = 0; col < matrizVal.length; col++){
if (largest < matrizVal[row][col]){
largest = matrizVal[row][col];
largestrow = row;
}
}
}
To find the so called minimax element I decided to create a for each loop and get all the values of largestrow except the largest one.
for (int i : matrizVal[largestrow]){
if (i != largest){
System.out.print(i);
}
}
Here's where I'm stuck! I'd simply like to 'sort' this integer and take the first value and that'd be the minimax. I'm thinking about creating an array of size [matrizVal.length - 1], but not sure if it's gonna work.
I did a lot of research on the subject but nothing seems to help. Any tips are welcome.
(I don't think it is but I apologize if it's a duplicate)
Given the code you have provided, matrizVal[largestrow] should be the row of the matrix that contains the highest valued element.
Given that your task is to extract the smallest value in this array, there are a number of options.
If you want to simply extract the minimum value, a naive approach would go similarly to how you determined the maximum value, just with one less dimension.
For example:
int min = matrizVal[largestrow][0];
for (int i = 0; i < matrizVal.length; i++) {
if (matrizVal[largestrow][i] < min) {
min = matrizVal[largestrow][i];
}
}
// min will be the target value
Alternatively, if you want to sort the array such that the first element of the array is always the smallest, first ensure that you're making a copy of the array so as to avoid mutating the original matrix. Then feel free to use any sorting algorithm of your choice. Arrays.sort() should probably suffice.
You can simplify your approach by scanning each row for the maximum and minimum values in that row and then deciding what to do with those values based on the maximum value found in previous rows. Something like this (untested) should work:
int largestValue = Integer.MIN_VALUE;
int smallestValue = 0; // anything, really
for (int[] row : matrizVal) {
// First find the largest and smallest value for this row
int largestRowValue = Integer.MIN_VALUE;
int smallestRowValue = Integer.MAX_VALUE;
for (int val : row) {
smallestRowValue = Math.min(smallestRowValue, val);
largestRowValue = Math.max(largestRowValue, val);
}
// now check whether we found a new highest value
if (largestRowValue > largestValue) {
largestValue = largestRowValue;
smallestValue = smallestRowValue;
}
}
This doesn't record the row index, since it didn't sound like you needed to find that. If you do, then replace the outer enhanced for loop with a loops that uses an explicit index (as with your current code) and record the index as well.
I wouldn't bother with any sorting, since that (1) destroys the order of the original data (or introduces the expense of making a copy) and (2) has higher complexity than a one-time scan through the data.
You may want to consider a different alternative using Java 8 Stream :
int[] maxRow = Arrays.stream(matrizVal).max(getCompertator()).get();
int minValue = Arrays.stream(maxRow).min().getAsInt();
where getCompertator() is defined by:
private static Comparator<? super int[]> getCompertator() {
return (a1, a2)->
Integer.compare(Arrays.stream(a1).max().getAsInt(),
Arrays.stream(a2).max().getAsInt()) ;
}
Note that it may not give you the (undefined) desired output if two rows include the same highest value .

Print characters as a Matrix

Below problem has a list of characters and number of columns as the input. Number of columns is not a constant and can vary with every input.
Output should have all the rows fully occupied except for the last one.
list: a b c d e f g
colums: 3
Wrong:
a b c
d e f
g
Wrong:
a d g
b e
c f
Correct:
a d f
b e g
c
I have tried below:
public static void printPatern(List<Character> list, int cols) {
for (int i = 0; i < cols; i++) {
for (int j = i; j < list.size(); j += cols) {
System.out.print(list.get(j));
}
System.out.println();
}
}
It gives output as (which is wrong):
a d g
b e
c f
I am trying to come with an algorithm to print the correct output. I want to know what are the different ways to solve this problem. Time and Space complexity doesn't matter. Also above method which I tried is wrong because it takes columns as the parameter but that's actually acting as the number of rows.
FYI: This is not a HOMEWORK problem.
Finally able to design the algorithm for this problem
Please refer below java code same
public class puzzle{
public static void main(String[] args){
String list[] = { "a", "b", "c","d","e","f","g","h","i","j" };
int column = 3;
int rows = list.length/column; //Calculate total full rows
int lastRowElement = list.length%column;//identify number of elements in last row
if(lastRowElement >0){
rows++;//add inclomplete row to total number of full filled rows
}
//Iterate over rows
for (int i = 0; i < rows; i++) {
int j=i;
int columnIndex = 1;
while(j < list.length && columnIndex <=column ){
System.out.print("\t"+list[j]);
if(columnIndex<=lastRowElement){
if(i==rows-1 && columnIndex==lastRowElement){
j=list.length; //for last row display nothing after column index reaches to number of elements in last row
}else{
j += rows; //for other rows if columnIndex is less than or equal to number of elements in last row then add j value by number of rows
}
}else {
if(lastRowElement==0){
j += rows;
}else{
j += rows-1; //for column greater than number of element in last row add j = row-1 as last row will not having the column for this column index.
}
}
columnIndex++;//Increase column Index by 1;
}
System.out.println();
}
}
}
This is probably homework; so I am not going to do it for you, but give you some hints to get going. There are two points here:
computing the correct number of rows
computing the "pattern" that you need when looping your list so that you print the expected result
For the first part, you can look into the modulo operation; and for the second part: start iterating your list "on paper" and observe how you are printing the correct result manually.
Obviously, that second part is the more complicated one. It might help if you realize that printing "column by column" is straight forward. So when we take your correct example and print the indexes instead of values, you get:
0 3 6
1 4 7
2 5
Do that repeatedly for different input; and you will soon discover the pattern of indexes that you need to print "row by row".

Iterating through the subdiagonal of a 2D Array

I am trying to iterate through a randomly generated 2d array of 0s, and 1s. In this method which I am stuck on I am trying to see if the subdiagonal has all the same numbers, all 1s, all 0s, or different numbers.
sub diagonal meaning:
110
101
011
The 0s are the subdiagonal.
this is the code I have as of now. I am trying to iterate starting at the last row and counting up to the first row diagonally.
int firstValue= matrix[matrix.length-1][0];
int result = -1;
for(int row = matrix.length-1; row > 0; row--)
{
int column = row;
if(firstValue == matrix[row][column])
{
result = firstValue;
continue;
}
else
{
result = -1;
break;
}
}
if(result== 1)
{
System.out.println("All " + firstValue + "s on the subdiagonal");
}
else if (result == 0)
{
System.out.println("All " + firstValue + "s on the subdiagonal");
}
else
{
System.out.println("Numbers on subdiagonal are different");
}
}
I'm almost certain my issue is with the firstValue and/or the for loop counting up the diagonal.
Any help would be appreciated, thanks much
Your issue seems to be at the following line,
for(int row = matrix.length-1; row > 0; row++) {
...
}
you are doing a
row = matrix.length-1; // row = array length - 1
row++ //this will increase the row's value beyond your array length
Then you will be accessing a index that does not exist causing a ArrayIndexOutOfBoundsException
Edit
what you'd want to do is,
for(int row = matrix.length-1; row >= 0; row--) {
....
}
This way you'd be able to iterate though your array from largest index to the smallest (0).
Edit 2
Let's say Staring array called arr has 4 elements. It'll be structured as below,
arr[0] = "test1";
arr[1] = "test2";
arr[2] = "test3";
arr[3] = "test4";
Array indexes always starts from 0, so the highest index in the above array is 3.
So if you want to iterate from smallest index to the largest, you'd do
for(int i = 0; i < arr.length; i++) {
//i's initial value is 0 and itll increment each time the loop runs
//loop will terminate when i is no longer < 4
System.out.println(arr[i]);
}
and to iterate through the array in reverse order you'd do,
for(int i = (arr.length - 1); i <= 0; i--) {
//i's initial value is (4 - 1) and it'll decrement each time the loop runs
//loop will terminate when i smaller or equal to 0
System.out.println(arr[i]);
}
So we want to check if all of the values in the subdiagonal are the same value, and if they are then we want to print the value that is the same. First we set aside a comparison to check the other indices
int checkValue = arr[0][arr[0].length-1];
This is the last value in the first row. Then we set a flag to catch whenever our index that we are checking matches our first value. We'll set it to false because we'll assume that the values don't match.
boolean flag = false;
Now that we have that, we need to iterate through each row in our array. We will start with the second row (arr[1]) and then we need to check the value one down and one over compared to the last value we checked (arr[1][arr.length - 1 - i]). If our first value (we assigned it's value to checkValue) and the value we are checking are the same, change the flag to true.
for (int i = 1; i < arr.length; i++)
if (arr[i][arr.length - 1 - i] != checkValue)
flag = true;
That'll run through all of the rows in the array. Now we have to check the state of our flag and print out the appropriate response. If the flag is true, print out that the values on the row are the same. Else we will say that the subdiagonal does not match all the way through.
if (!flag)//remember our flag is set to false, double negative equals true.
System.out.println("All of the values on the subdiagonal are the same");
else
System.out.println("All of the values on the subdiagonal are not the same");

Shift elements in 2D ArrayList

I have 2D ArrayList which was filled with elements (objects which contain images etc.) so the 2D array was full. After calling removing functions my array looks like the picture on the left side; on the right side you can see the desired result. Could someone please give me the idea how to reorganize my array as you can see on the picture?
The idea was to go from to bottom to top. If I find the gap (the gap means that I set the background of element to null, respectively, imageIcon is set to null) I will switch it for the previous element. And because I have switched it I have to do it for the whole column. Problem is, when they are 2 or more gaps and also, this algorithm does nothing.
for (int i = 0; i < 10; i++) {
for (int j = 7; j > 0; j--) {
Item currentItem = this.elements.get(j).get(i).getItem();
if (currentItem.getBack().getIcon() == null) {
int count = j;
while (count > 1) {
Position temp = this.elements.get(count).get(i);
Position zero = this.elements.get(count).get(i);
Position previous = this.elements.get(count - 1).get(i);
zero = previous;
previous = temp;
count--;
}
}
}
}
The arrayed data size is limited to 10x8 because of my gameboard panel. The items in array are not distinguishable, they only have different backgrounds (type of JLabel component). The items have to "fall from top to down".
PS: I am creating a clone of Bejeweled
From what you have shown in the pictures, you want the column's elements to be "dropped to bottom"? If that is the case, you should probably use a regular 2D array instead of ArrayList, with an array for each of your columns, and assume the bottom is indexed 0 - why? because ArrayList doesn't have fixed size, and your problem statement shows you want the container to be of fixed size. The solution would then be (roughly, because you shown only a part of your code, not a SSCCE):
//Item[][] items;
for( Item[] arr : items )
for( int i = arr.length - 2; i >= 0; i-- )
if ( arr[i] == null ) // or arr[i].getBack().getIcon() == null or whatever
for( int j = i; j < arr.length - 1; j++ )
arr[j] = arr[j+1];
This is a crude bubble sort, suitable for small arrays. There are other solutions possible (as this is a sorting problem by itself - you may look up qsort for this), but this one is arguably the simplest.
Note: You may implement the very same solution for ArrayLists, yet I strongly advocate against it. Using nested ArrayLists to mimic multi-dim arrays is seldom a good idea - it'll create the arrays anyway, but you'll get a large overhead, making the code both slower and less readable - anyway you can do so by replacing []s with get()/set() etc.
For the sake of reference:
//ArrayList<ArrayList<Item>> items;
//int columnHeight;
for( ArrayList<Item> arr : items )
for( int i = columnHeight - 2; i >= 0; i-- )
if ( arr.get(i) == null ) //or arr.get(i).getIcon()==null or whatever
for( int j = i; j < columnHeight - 1; j++ )
arr.set(j, arr.get(j+1));
or simply, by providing a comparator:
//ArrayList<ArrayList<Item>> items;
//int columnHeight;
for( ArrayList<Item> arr : items )
Collections.sort(arr, new Comparator<Item>() {
#Override
public int compare(Item i1, Item i2) {
return ...; // place the sorting rule here
}
});
For more info, see docs for Collections.sort() & Comparator.
Also, if this is indeed for Bejewelled clone - you may consider doing the "dropping" by doing an iteration dropping all jewels with an empty field beneath by one step, counting the amount of dropped jewels, and repeating this iteration till the amount of drops == 0. That's the algo I used in my clone in the days of the past.
As #vaxquis has already mentioned, it's better to rewrite your code in some more elegant way.
for (int i = 0; i < 10; i++) {
// Perfoming bubble sort for each column
boolean swapped = true;
for(int j = 6; j > 0 && swapped; j--) {
swapped = false;
for (int k = 0; k < j; k++) {
Item currentItem = this.elements.get(k).get(i).getItem();
Item nextItem = this.elements.get(k+1).get(i).getItem();
if (currentItem.getBack().getIcon() != nextItem.getBack().getIcon()) {
swap(currentItem, nextItem); // implement this yourself
swapped = true;
}
}
}
}
Besides the algorithm issues addressed by the other answers, your main problem is that you never change anything in the arrays. The following code just moves some values between local variables:
Position temp = this.elements.get(count).get(i);
Position zero = this.elements.get(count).get(i);
Position previous = this.elements.get(count - 1).get(i);
zero = previous;
previous = temp;
You probably have a setItem() method to set things back into a Position object? Then a swap would be:
Position current = this.elements.get(count).get(i);
Position previous = this.elements.get(count - 1).get(i);
Item temp = current.getItem();
current.setItem(previous.getItem();
previous.setItem(temp);

Adding elements to last array position

Im trying to add an element to an array at its last position in Java, but I am not able to...
Or rather, I don't know how to. This is the code at the moment:
String[] values = split(line, ",");
int[][] coordinates = new int[2][values/2];
for(int i = 0; i < values.length; i++) {
if(i % 2 == 0) { //THIS IS EVEN VALUES AND 0
coordinates[0][coordinates[0].length] = values[i];
} else { //THIS IS ODD VALUE
coordinates[1][coordinates[1].length] = values[i];
}
}
EDITED VERSION:
String[] values = split(line, ",");
int[][] coordinates = new int[2][values/2];
int x_pos = 0;
int y_post = 0;
for(int i = 0; i < values.length; i++) {
if(i % 2 == 0) { //THIS IS EVEN VALUES AND 0
coordinates[0][x_pos] = values[i];
x_pos++;
} else { //THIS IS ODD VALUE
coordinates[1][y_pos] = values[i];
y_pos++;
}
}
values is being read from a CSV file. My code is I believe wrong, since it will try to add the values always at the maximum array size for coordinates[] in both cases.
How would I go around adding them at the last set position?
Thanks!
/e: Would the EDITED VERSION be correct?
Your original code has two problems:
it addresses the array badly, the las element in a Java array is at position length-1, and this would result in an ArrayOutOfBoundsException
even if you'd correct it by subtracting 1, you would always overwrite the last element only, as the length of a Java array is not related to how many elements it contains, but how many elements it was initialised to contain.
Instead of:
coordinates[0][coordinates[0].length] = values[i];
You could use:
coordinates[0][(int)Math.round(i/2.0)] = values[i];
(and of course, same with coordinates[1]...)
EDIT
This is ugly of course:
(int)Math.round(i/2.0)
but the solution I'd use is far less easy to understand:
i>>1
This is a right shift operator, exactly the kind of thing needed here, and is quicker than every other approach...
Conclusion: this is to be used in a live scenario:
Use
coordinates[0][i>>1] = values[i];
EDIT2
One learns new things every day...
This is just as good, maybe a bit slower.
coordinates[0][i/2] = values[i];
If you know you'll definitely have an even number of values you can do
for(int i = 0; i < values.length / 2; i++) {
coordinates[0][i] = values[2*i];
coordinates[1][i] = values[2*i + 1];
}
You have to store the last position somewhere. .length gives you the size of the array.
The position in the array will always be the half of i (since you put half of the elements in one array and the other half in the other).
String[] values = split(line, ",");
int[][] coordinates = new int[2][values/2];
for(int i = 0; i < values.length; i++) {
if(i % 2 == 0) { //THIS IS EVEN VALUES AND 0
coordinates[0][ i / 2] = values[i];
} else { //THIS IS ODD VALUE
coordinates[1][ i / 2 + 1 ] = values[i];
}
}
The array index for java is from "0" to "array length - 1".
http://docs.oracle.com/javase/tutorial/java/nutsandbolts/arrays.html
Each item in an array is called an element, and each element is accessed by its numerical index. As shown in the above illustration, numbering begins with 0. The 9th element, for example, would therefore be accessed at index 8.
why not:
String[] values = split(line, ",");
int[][] coordinates = new int[2][values/2];
for(int i = 0; i < values.length; i+=2) {
coordinates[0][i/2] = values[i];
coordinates[1][i/2] = values[i+1];
}

Categories

Resources