I would like to loop over half of an array in Java; this is because the matrix will be completely symmetric. If I loop throw i columns and j rows, every time I do an operation of matrix[i][j] I will do the exact same operation to matrix[j][i]. I should be able to save time by not looping over half of the matrix. Any ideas on the easiest way to do this?
If you're trying to get a triangle:
for(int i=0; i<array.length; i++){
for(int j=0; j<=i; j++){
..do stuff...
}
}
for (i = 0;i < size; ++i) {
for (j = 0; j < i; ++j) {
result = do_operation(i,j);
matrix[i][j] = result;
matrix[j][i] = result ;
}
}
So you invoke the operation method do_operation only once for each pair.
for(int i = 0; i<array.length; i++){
for(int j = 0; j < array[i].length - i; j++){
// operation here
}
}
Maybe I'm missing something here, but let's say you have two arrays representing your rows and columns respectively, and assuming that it's symmetric (as you say):
int dimension = rows.Length;
for(int i=0; i<dimension; i++)
{
int j = (dimension-1) - i; //need dimension-1 to avoid an off-by-one error
DoSomething(matrix[i][j]);
DoSomehting(matrix[j][i]);
}
This solution has the runtime complexity benefit of only iterating over one loop as opposed to two.
Related
I'm trying a simple intuition to transpose a matrix in place.
I'm trying to swap elements of matrix[i][j] and matrix[j][i] but it is not working, I'm wondering what is happening behind the scene.
class Solution {
public int[][] transpose(int[][] matrix) {
for(int i = 0; i < matrix.length; i++){
for(int j = 0; j < matrix[0].length; j++){
int temp = matrix[i][j];
matrix[i][j] = matrix[j][i];
matrix[j][i] = temp;
}
}
return matrix;
}
}
Output
For matrix -> [[1,2,3],[4,5,6],[7,8,9]]
It is giving output -> [[1,2,3],[4,5,6],[7,8,9]]
but the expected output should be -> [[1,4,7],[2,5,8],[3,6,9]]
You are transposing each pair of elements twice, which puts them back how they were.
One solution would be to change for(int j = 0; in the inner loop to for(int j = i + 1;. This would make sure that each pair of elements is only transposed once.
Also be aware that this general solution only works for square matrices.
how about this way?
public int[][] transpose(int[][] matrix) {
int[][] result = new int[matrix.length][matrix[0].length];
for(int i = 0; i < matrix[0].length; i++){
for(int j = 0; j < matrix.length; j++){
result[j][i] = matrix[i][j];
System.out.println(Arrays.deepToString(result));
}
}
return result;
}
I'm trying to evaluate a hand to see if they have a pair and I feel like this is right but i keep getting errors. Any idea on what im doing wrong?
public boolean isPair() {
String[] values = new String[5];
int counter = 0;
//Put each cards numeric value into array
for(int i = 0; i < cards.length; i++){
values[i] = cards[i].toString();
}
//Loop through the values. Compare each value to all values
//If exactly two matches are made - return true
for(int j = 0; j < values.length; j++){
for(int k = 0; k < cards.length; k++){
if(values[j].equals(cards[k].toString()))
counter++;
if(counter == 2)
return true;
}
counter = 0;
}
return false;
}
The first obvious error I can see, is that you re comparing the first card with itself here :
for(int j = 0; j < values.length; j++){
for(int k = 0; k < cards.length; k++){
Your index k should not be verified if it equals j.
Secondly, why are you using a your variable "hand" in the comparison when you bothered to create a array of String containing your hand ?
values[j].equals(cards[k].toString())
You can write :
values[j].equals(values[k])
I dont think it is responsible for any errors, but it s much easier to understand.
And finally, your counter is false. A pair, is by definition two cards of the same value. So, you have to check if a value is present only two times(that means 1 equality) in your hand.
So you'll have :
for(int j = 0; j < values.length; j++){
for(int k = 0; k < cards.length; k++){
if(k!=j){
if(values[j].equals(values[k]))
counter ++;
}
}
if (counter ==1 ) //Counter==1 means the a value matched with an other value in your hand only once, involving one pair.
return true;
else counter = 0;
}
return false;
String[] values = new String[5];
should be
String[] values = new String[cards.length];
However, even better would be to not use values anyway, since it's almost a copy of cards.
I apologize if I'm not clear. I'm new to programming. So lets say I have a char[10][10]. And there are two+ chars I want to assign at intervals for example i[0][0] to i[5][7] have Y and the rest have N. How would I do that if its possible? I've been trying to figure it out for 6+ hours.
One possible solution would be to have a 'for' block that goes through the rows and another 'for' block that goes through the columns. it could be something like
char[] arr= {'Y','N'};
int counter = 0; // <- these are optional depending on what you choose below
for(int j=0;j<10;j++){
for(int k=0;k<10;k++){
// i[j][k]= here you should assign the value
counter++;
}
}
The way to assign the value depends on what you want to do. If you want to have it to generate randomly you can do something like i[j][k]= arr[(int)(Math.random()*2)] or if you want to have it alternate between Y and N you could have a counter variable and assign i[j][k]= arr[counter%2] . If you want to assign the first half to 'Y' and the other half to 'N' i[j][k]= (counter<=50)?'Y':'N';. And the particular case you ask would be i[j][k]= (j<=5 && k<=7)?'Y':'N';It really depends much on what you want to do
This can be done with loops.
for(int i = 0; i < 5; i++){
for(int j = 0; j < 7; j++){
i[i][j] = 'N';
}
for(int j = 7; j < 10; j++){
i[i][j] = 'Y';
}
}
for(int i = 5; i < 10; i++){
for(int j = 0; j < 10; j++){
i[i][j] = 'Y';
}
}
char[][] theArray = new char[10][10]
upToX = 5; // limit for rows
upToY = 7; // limit for columns
for(int i = 0; i < 10; i++ ){
for(int j = 0; j< 10; j++ ){
if((i+1)*(j+1) <= (upToX+1)*(upToY+1)){
theArray[i][j] = 'Y';
}
else{
theArray[i][j] = 'N';
}
}
}
Try using for-loops and if-else. Since you are looking for yes/no type values, I just used boolean type in my example
boolean[][] arr = new boolean[10][10];
for(int i = 0; i < arr.length; i++) {
for(int j = 0; j < arr[i].length; j++) {
if(i < 6 && j < 8)
arr[i][j] = true;
else
arr[i][j] = false;
}
}
I wrote the following code in JAVA.
package threed;
import java.util.Scanner;
public class Threed_Array {
/**
* #param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
int b1,b2,b3;
System.out.print("Enter the number of elements in 1st bracket->");
Scanner sc=new Scanner(System.in);
b1=sc.nextInt();
System.out.print("Enter the number of elements in 2nd bracket->");
b2=sc.nextInt();
System.out.print("Enter the number of elements in 3rd bracket->");
b3=sc.nextInt();
int threedarray[][][]=new int[b1][b2][b3];
for(int i=1; i<=b1; i++)
{
for(int j=1; i<=b2; j++)
{
for(int k=1; i<=b3; k++)
{
System.out.print("Enter element->");
threedarray[i][j][k]=sc.nextInt();
}
}
}
for(int i=1; i<=b1; i++)
{
for(int j=1; i<=b2; j++)
{
for(int k=1; i<=b3; k++)
{
System.out.print(" "+threedarray[i][j][k]);
}
}
}
}
}
I am getting ArrayIndexOutOfBoundsException for this code. This is showing in the line:
threedarray[i][j][k]=sc.nextInt();
Can anybody help me out where the error is occurring? Thank you.
You should always start at index 0, it is the index of the first element of your array:
for(int i=0; i<b1; i++)
{
for(int j=0; j<b2; j++)
{
for(int k=0; k<b3; k++) {
System.out.print("Enter element->");
threedarray[i][j][k]=sc.nextInt();
}
}
}
for(int i=0; i<b1; i++)
{
for(int j=0; j<b2; j++)
{
for(int k=0; k<b3; k++)
{
System.out.print(" "+threedarray[i][j][k]);
}
}
}
furthermore make the check with < not <=
With the last loop you access the array element n+1 where n is the size of that array. Thats the reason for the exception.
I'd say the conditions in your loops are not correct :
for(int i=1; i<=b1; i++)
{
for(int j=1; i<=b2; j++)
{
for(int k=1; i<=b3; k++)
{
it should be :
for(int i=1; i<=b1; i++)
{
for(int j=1; j<=b2; j++)
{
for(int k=1; k<=b3; k++)
{
Also, you should start at 0 in each of them.
I think you want j and k in the 2 inside for loops instead of i. Also, arrays in Java start in index 0, so it should look like this:
for(int i=0; i<b1; i++)
{
for(int j=0; j<b2; j++)
{
for(int k=0; k<b3; k++)
{
...
}
}
}
Arrays in Java are zero-based, try to iterate from 0 to b1-1:
for(int i=0; i<b1; i++)
{
for(int j=0; i<b2; j++)
{
for(int k=0; i<b3; k++)
{
System.out.print("Enter element->");
threedarray[i][j][k]=sc.nextInt();
}
}
}
[b1][b2][b3]
You create an array using the inputs b1,b2,b3
The array created has length of bx but subscripts from 0 to bx-1. Hence you must loop from 0 to bx-1
Indices start at 0, not 1. Start your three for loops at 0 and iterate to one less than the number provide:
for(int i = 0; i < b1; i++)
{
for(int j = 0; i < b2; j++)
{
for(int k = 0; i < b3; k++)
{
System.out.print(" "+threedarray[i][j][k]);
}
}
}
Apart from the array index problem (see Stefan Beike's answer), you could you an ArrayList.
This would avoid having to ask the user for the number of elements you want to have in your matrix.
Still if you want to keep primitive arrays, you could use System.arrayCopy to reallocate to a greater size array.
The problem here is that you are starting the loop from 1 till the b1,b2,b3 respectively. Array indexes start from 0 not from 1 and ends at the size of the array - 1. So to fix your code you need to modify the code to be the following:
for(int i = 0; i < b1; i++) {
for(int j = 0; j < b2; j++) {
for(int k = 0; k < b3; k++) {
System.out.print("Enter element->");
threedarray[i][j][k]=sc.nextInt();
}
}
}
More generally if you don't know the length/size of the array you are looping on, you can make the loop more generally to be less than the array length. So it would be i < threedarray.length and j < threedarray[i].length and k < threedarray[i][j].length.
The key idea is that the array indexing starts from 0 and ends at its size/length - 1, so to get the last element you access array[array.length-1] and to access the first element you access array[0]
Hope this answers your question.
I have a NxN matrix and it trying to transpose it by this code:
for(int i = 0; i < mat_size; ++i) {
for(int j = 0; j < mat_size; ++j) {
double tmpJI = get(j, i);
put(j, i, get(i, j));
put(i, j, tmpJI);
}
}
it doesn't work, what is the problem? thanks in advance.
It doesn't work since you're swapping the whole matrix with itself. What you need to do is exchange the upper triangle with the lower one:
for(int j = 0; j < i; ++j) {
is one way.
Going from 0 to mat_size will get you reorder the whole matrix two times, getting the original one again.
change to :
for(int i = 0; i < mat_size; ++i) {
for(int j = 0; j < i; ++j) {
double tmpJI = get(j, i);
put(j, i, get(i, j));
put(i, j, tmpJI);
}
}
You need to swap only if j > i. So the inner loop must start at i+1. For j==i (the center diagonal) no swapping is needed, too.
Your solution doesn't work because you're actually swapping twice (once with j=x and i=y and once with j=y and i=x.
For example the (2,5) is swapped for i=2,j=5 and i=5,j=2. Swap twice does nothing.
for(int i = 0; i < mat_size; ++i) {
for(int j = 0; j < i; ++j) {
double tmpJI = get(j, i);
put(j, i, get(i, j));
put(i, j, tmpJI);
}
}
This is because the elements that you swap in the lower triangle of the matrix gets swapped again when the iteration reaches the other side of the diagonal. That is the element is swapped twice which results in nothing.
Try:
for(int i = 0; i < mat_size; ++i) {
for(int j = 0; j < i; ++j) {
double tmpJI = get(j, i);
put(j, i, get(i, j));
put(i, j, tmpJI);
}
}