How to shift 2-dimensional array from index position
int[][] x =
{
{ 1, 2, 3, 4, 5, 6, 7 },
{ 1, 2, 3, 4, 5, 6, 7 },
{ 1, 2, 3, 4, 5, 6, 7 },
{ 1, 2, 3, 4, 5, 6, 7 }
};
index = 3
int[][] y =
{
{ 5, 6, 7, 1, 2, 3, 4 },
{ 5, 6, 7, 1, 2, 3, 4 },
{ 5, 6, 7, 1, 2, 3, 4 },
{ 5, 6, 7, 1, 2, 3, 4 }
};
Any Idea? thanks
This program uses a logic in which we rotate an array by reversing array in parts. First we will reverse array upto index location and then reverse remaining array ( index+1 to last element of array).
After completing above two steps we call again reverse function but this time on whole of the array that gives us the required output.
Below is the code that will help in understanding above logic described.
public class ShiftTwoDArray {
public static void main(String[] args) {
int[][] x = { { 1, 2, 3, 4, 5, 6, 7 },
{ 1, 2, 3, 4, 5, 6, 7 },
{ 1, 2, 3, 4, 5, 6, 7 },
{ 1, 2, 3, 4, 5, 6, 7 }
};
int index = 3;
int i, j;
// System.out.println(x.length);
System.out.println("Before");
for (i = 0; i < x.length; i++) {
for (j = 0; j < x[i].length; j++) {
System.out.print(x[i][j] + " ");
}
System.out.println();
}
rotate(x, index);
System.out.println("\nAfter");
for (i = 0; i < x.length; i++) {
for (j = 0; j < x[i].length; j++) {
System.out.print(x[i][j] + " ");
}
System.out.println();
}
}
/**
* #param x
* #param index
* calls rotateUtil on each row
*/
private static void rotate(int[][] x, int index) {
for (int i = 0; i < x.length; i++) {
rotateUtil(x[i], index);
}
}
/**
* #param x
* #param index
* reverse array in parts and then reverse whole array
*/
private static void rotateUtil(int[] x, int index) {
reverse(x, 0, index);
reverse(x, index + 1, x.length - 1);
reverse(x, 0, x.length - 1);
}
/**
* #param x
* #param start
* #param end
* reverse an array
*/
private static void reverse(int[] x, int start, int end) {
int temp = 0;
while (start < end) {
temp = x[start];
x[start] = x[end];
x[end] = temp;
start++;
end--;
}
}
}
Here's one way to do it, using Guava and Java 8:
Arrays.stream(x)
.map(Ints::asList)
.forEach(list -> Collections.rotate(list, index));
Or the Java 7 version:
for (int[] array : x) {
Collections.rotate(Ints.asList(array), index);
}
This should do what you want:
int[][] x = { { 1, 2, 3, 4, 5, 6, 7 },
{ 1, 2, 3, 4, 5, 6, 7 },
{ 1, 2, 3, 4, 5, 6, 7 },
{ 1, 2, 3, 4, 5, 6, 7 } };
int index = 3;
// Create 2D array of matching size
int[][] y = new int[x.length][x[0].length];
// Loop through each row of x
for (int r = 0; r < x.length; r++) {
// Loop through each column of x[r][]
for (int c = 0; c < x[0].length; c++) {
// Put x's value in y, shifting to the right by index.
// See comment outside of code regarding %
y[r][(c + index) % x[0].length] = x[r][c];
}
}
// Print out y to see if it worked
for (int r = 0; r < y.length; r++) {
for (int c = 0; c < y[0].length; c++) {
System.out.print(y[r][c] + " ");
}
System.out.println();
}
The key here is the % x[0].length in y[r][(c + index) % x[0].length] = x[r][c];. The c + index shifts the column to the right. However, the % x[0].length handles wrapping the columns around to the start of the row, if necessary.
Related
I got this question to solve
Write a method that takes a two-dimensional array of type integer as a parameter and return
the inverse of the array (the rows become the columns and vice versa).
that is what I did through searching, but it shows a bunch of errors
public static class inverse{
public static int[][] arrayInverse(int[][] A){
int[][] B = new int[3][3];
for(int i=0; i<B.length/2;i++){
for (int j=0; j<B[i].length/2;j++) {
int swap = B[i][j];
B[B.length - i - 1] = swap;
}
}
return swap;
}
}
}
First, as mentioned in the comments, the task is to transpose the input array the rows become the columns and vice versa
If the input 2D array is square (the number of the rows is the same as the number of columns), the most efficient way would be to swap the elements below and over the main diagonal: a[i][j] ⇄ a[j][i] without using extra array:
public static int[][] transposeSquare(int[][] arr) {
for (int i = 0, n = arr.length; i < n; i++) {
// select the elements only above the main diagonal
for (int j = i + 1, m = arr[i].length; j < m; j++) {
int tmp = arr[i][j];
arr[i][j] = arr[j][i];
arr[j][i] = tmp;
}
}
return arr;
}
However, in general case of a rectangular matrix it may be needed to create a new array/matrix of size M x N instead of N x M, and copy the values from the input in appropriate order (no swap is needed then):
public static int[][] transpose(int[][] arr) {
int[][] result = new int[arr[0].length][arr.length];
for (int i = 0, n = arr.length; i < n; i++) {
for (int j = 0, m = arr[i].length; j < m; j++) {
result[j][i] = arr[i][j];
}
}
return result;
}
You need to replace between columns and rows
public class inverse {
/**
* The entry point of application.
*
* #param args the input arguments
*/
public static void main(String[] args) {
int ints[][] = {{1, 2, 3},
{5, 6, 7},
{9, 10, 11},
{12, 13, 14}
};
print2D(ints);
System.out.println("\n");
print2D(arrayInverse(ints));
}
/**
* Array inverse int [ ] [ ].
*
* #param A the a
* #return the int [ ] [ ]
*/
public static int[][] arrayInverse(int[][] A) {
if (A.length == 0 || A[0].length == 0) {
System.out.println("A.length==0 || A[0].length==0");
return A;
}
int[][] B = new int[A[0].length][A.length];
for (int i = 0; i < B.length; i++) {
for (int j = 0; j < B[i].length; j++) {
B[i][j] = A[j][i];
}
}
return B;
}
/**
* Print 2 d.
*
* #param mat the mat
*/
public static void print2D(int mat[][]) {
// Loop through all rows
for (int i = 0; i < mat.length; i++) {
for (int j = 0; j < mat[i].length; j++) {
System.out.print(mat[i][j] + " ");
}
System.out.println(" ");
}
}
}
Output:
1 2 3
5 6 7
9 10 11
12 13 14
1 5 9 12
2 6 10 13
3 7 11 14
Here is a general solution. It will transpose any matrix, including a ragged one.
List<int[][]> demo = List.of(
new int[][] { { 1 }, { 2, 3, 4 }, { 5, 6 } },
new int[][] { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 } },
new int[][] { { 1, 2, 3, 4, 5 },
{ 6, 7, 8, 9, 10 } });
for (int[][] arr : demo) {
System.out.println("Original");
for (int[] b : arr) {
System.out.println(Arrays.toString(b));
}
System.out.println("Transposed");
for (int[] b : transpose(arr)) {
System.out.println(Arrays.toString(b));
}
System.out.println();
}
prints
Original
[1]
[2, 3, 4]
[5, 6]
Transposed
[1, 2, 5]
[3, 6]
[4]
Original
[1, 2, 3]
[4, 5, 6]
[7, 8, 9]
Transposed
[1, 4, 7]
[2, 5, 8]
[3, 6, 9]
Original
[1, 2, 3, 4, 5]
[6, 7, 8, 9, 10]
Transposed
[1, 6]
[2, 7]
[3, 8]
[4, 9]
[5, 10]
first, find the resulting number of rows, which is the maximum number of columns in the source matrix.
Then simply iterate thru the matrix, creating the new rows and copying the appropriate values of each column to their new row. Since the rows may be of different lengths, a check is made to ensure the value exists in the current row.
then copy that row of the proper length to the transposed row.
public static int[][] transpose(int[][] nums) {
int maxRows = nums[0].length;
for (int[] ar : nums) {
maxRows = Math.max(maxRows, ar.length);
}
int[][] trans = new int[maxRows][];
for (int r = 0; r < maxRows; r++) {
int[] row = new int[nums.length];
int cc = 0;
for (int c = 0; c < row.length; c++) {
if (r < nums[c].length) {
row[cc++] = nums[c][r];
}
}
trans[r] = Arrays.copyOf(row, cc);
}
return trans;
}
prints
The method int[][] labelPath(int n, int[][] points) creates a new square array of length n and returns it back. Each line in data0 describes a point in a two-dimensional array. The column 0 is here always for the column index and column 1 for the row index of a point. If the return array reaches each point in data0 returns the value -1. At all other points, the return array contains the value n.
For example: n = 4 and data0 = {{3, 0}, {0, 1}, {2, 2}} should return:
[[4, 4, 4, -1], [-1, 4, 4, 4], [4, 4, -1, 4], [4, 4, 4, 4]]
My code so far:
int[][] labelPath(int n, int[][] points) {
int[][] help = new int[n][n];
for (int i = 0; i < input.length; i++) {
for (int j = 0; j < input[i].length; j++) {
int row = input[1].length;
int column = input[0].length;
for (int k = 0; k < help.length; k++) {
for (int l = 0; l < help[k].length; l++) {
if (help[i][j] == input[row][column]) {
help[i][j] = -1;
} else {
help[i][j] = n;
}
}
}
}
}
return help;
}
You can do this very simply as follows:
int[][] nPoints = { { 3, 0 }, { 0, 1 }, { 2, 2 } };
int[][] ret = labelPath(4, nPoints);
for (int[] r : ret) {
System.out.println(Arrays.toString(r));
}
Prints
[4, 4, 4, -1]
[-1, 4, 4, 4]
[4, 4, -1, 4]
[4, 4, 4, 4]
public static int[][] labelPath(int n, int[][] nPoints) {
int[][] arr = new int[n][n];
int[] row = new int[n];
for (int i = 0; i < n; i++) {
row[i] = 4;
}
// set each row to an array of n elements.
for (int i = 0; i < n; i++) {
arr[i] = row.clone(); // new instance each time.
}
// make the changes
for (int[] p : nPoints) {
arr[p[1]][p[0]] = -1;
}
return arr;
}
You can use streams to create such an array:
public static int[][] labelPath(int n, int[][] points) {
// create a new empty 2d array filled with zeros
int[][] matrix = new int[n][n];
// set all array elements to 'n'
Arrays.setAll(matrix, row -> {
Arrays.fill(matrix[row], n);
return matrix[row];
});
// iterate over the points array and set the corresponding elements to '-1'
Arrays.stream(points).forEach(row -> matrix[row[1]][row[0]] = -1);
return matrix;
}
// test
public static void main(String[] args) {
int n = 4;
int[][] data0 = {{3, 0}, {0, 1}, {2, 2}};
int[][] matrix = labelPath(n, data0);
// output
Arrays.stream(matrix).map(Arrays::toString).forEach(System.out::println);
}
[4, 4, 4, -1]
[-1, 4, 4, 4]
[4, 4, -1, 4]
[4, 4, 4, 4]
See also: What is the most efficient way to create a 2d string array of initally repetitive data?
Create help[n][n] array of 4's.
int[][] help = new int[n][n];
for(int row = 0; row < help.length; row++){
for(int col = 0; col < 4; col++){
help[row][col] = 4;
}
}
Change the value according to data0 array.
int [][]data0 = {{3, 0}, {0, 1}, {2, 2}} ;
for(int row = 0; row < data0.length; row++){
int ar[] = new int[2];
for(int col = 0, i = 0; col < data0[row].length; col++, i++){
ar[i] = data0[row][col];
}
help[ar[1]][ar[0]] = -1;
}
Print help[][] array.
for(int row = 0; row < help.length; row++){
for(int col = 0; col < help.length; col++){
System.out.print(help[row][col] + " ");
}
System.out.println();
}
Output:
4 4 4 -1
-1 4 4 4
4 4 -1 4
4 4 4 4
I am a bit confused and I would need some clarification. Not too sure if I'm on the right track, hence this thread.
Here is my code that I want to decipher into advanced foreach loop.
int[] arrayA = {3, 35, 2, 1, 45, 92, 83, 114};
int[] arrayB = {4, 83, 5, 9, 114, 3, 7, 1};
int n = arrayA.length;
int m = arrayB.length;
int[] arrayC = new int[n + m];
int k = 0;
for(int i = 0; i < n; i++)
{
for(int j = 0; j < m; j++)
{
if(arrayB[j] == arrayA[i])
{
arrayC[k++] = arrayA[i];
}
}
}
for(int i=0; i<l;i++)
System.out.print(arrayC[i] + " ");
System.out.println();
So far this is the point where I am stuck at:
int[] a = {3, 8, 2, 4, 5, 1, 6};
int[] b = {4, 7, 9, 8, 2};
int[] c = new int[a.length + b.length];
int k = 0;
for(int i : a)
{
for(int j : b)
{
if(a[i] == b[j])
{
c[k++] = a[i];
}
}
//System.out.println(c[i]);
}
for(int i=0; i<c.length;i++)
System.out.print(c[i] + " ");
System.out.println();
}
You are almost there
for(int i : a)
{
for(int j : b)
{
if(i == j)
{
c[k++] = i;
}
}
}
With for(int i : a) access the elements in the array a using i.
If a is {3, 8, 2, 4, 5, 1, 6}, then i would be 3,8,2,.. on each iteration and you shouldn't use that to index into the original array. If you do, you would get either a wrong number or a ArrayIndexOutOfBoundsException
Since you want to pick the numbers that are present in both the arrays, the length of array c can be max(a.length, b.length). So, int[] c = new int[Math.max(a.length, b.length)]; will suffice.
If you want to truncate the 0s at the end, you can do
c = Arrays.copyOf(c, k);
This will return a new array containing only the first k elements of c.
I would use a List and retainAll. And in Java 8+ you can make an int[] into a List<Integer> with something like,
int[] arrayA = { 3, 35, 2, 1, 45, 92, 83, 114 };
int[] arrayB = { 4, 83, 5, 9, 114, 3, 7, 1 };
List<Integer> al = Arrays.stream(arrayA).boxed().collect(Collectors.toList());
al.retainAll(Arrays.stream(arrayB).boxed().collect(Collectors.toList()));
System.out.println(al.stream().map(String::valueOf).collect(Collectors.joining(" ")));
Outputs
3 1 83 114
Alternatively, if you don't actually need the values besides displaying them, and you want to use the for-each loop (and less efficiently) like
int[] arrayA = { 3, 35, 2, 1, 45, 92, 83, 114 };
int[] arrayB = { 4, 83, 5, 9, 114, 3, 7, 1 };
for (int i : arrayA) {
for (int j : arrayB) {
if (i == j) {
System.out.print(i + " ");
}
}
}
System.out.println();
Temporary variables aren't indices in an array in foreach Loop. So in 0th iteration, i contains the 0th element of a, j contains the 0th element in b. Your attempt should be like this:
int[] a = {3, 8, 2, 4, 5, 1, 6};
int[] b = {4, 7, 9, 8, 2};
int[] c = new int[a.length + b.length];
int k = 0;
for(int i : a) {
for(int j : b) {
if(i == j) {
c[k++] = i;
}
} //System.out.println(c[i]);
}
Please note your c[] array will contain the order maintained in a[].
My following code does the randomization of an array, however, I am wondering if I want to group first two or three elements together always, how should I proceed?
ArrayList<Integer> numbers = new ArrayList<Integer>();
for(int i=1;i<=11;i++)
{
numbers.add(i);
}
Collections.shuffle(numbers);
for (Integer nums : numbers)
System.out.println(nums);
Example Output: 5, 7, 4, 11, 2, 3, 1, 9, 6, 8, 10
(Note that the sequence '1,2,3' is randomized within the main array.)
Something like this maybe:
final int[] array = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 };
final int iterations = 10;
final int groupOf = 3;
for (int i = 0; i < array.length; i += groupOf) {
int groupOfRemainder = array.length - i < groupOf ? array.length - i : groupOf;
for (int j = 0; j < iterations; j++) {
int rnd1 = Math.random() * groupOfRemainder;
int rnd2 = Math.random() * groupOfRemainder;
Object temp = array[i + rnd1];
array[i + rnd1] = array[i + rnd2];
array[i + rnd2] = temp;
}
}
public static void shuffleKeepingFirstRTogether(List<Integer> list, int r) {
int size = list.size();
Collections.shuffle(list.subList(0, r));
Collections.shuffle(list.subList(r, size));
Collections.rotate(list, new Random().nextInt(size - r));
}
So, i am writing a program that analyzes an entire array and displays the repeated values as well as the unique values:
int dupe = 0;
int[] range = {1, 1, 2, 2, 2, 3, 3, 3, 4, 5, 6, 6};
for (int i = 0; i < range.length; i++) {
for (int j = i + 1; j < range.length; j++) {
if (range[i] == range[j]) {
dup = range[j];
System.out.println(dup);
}
}
}
The above code outputs the repeated values correctly but when the value repeats three or more times, it outputs that value many times instead of just once
1
2
2
2
3
3
3
6
How can i fix this?
For the unique value part of the program, i don't know where to start.
Thanks!
EDIT: The only Arrays class methods i can use are: binarySearch, copyOf, equals, fill, sort, and toString
I need to write my own implementation - not to use Set, HashSet etc. Or any other tools such as iterators
You can do somthing like bellow:
int[] range = {1, 1, 2, 2, 2, 3, 3, 3, 4, 5, 6, 6};
boolean duplicate = false;
for (int i = 0; i < range.length; i++) {
duplicate = false;
for (int j = i + 1; j < range.length; j++) {
if (range[i] == range[j]) {
duplicate = true
}
}
if(!duplicate){
System.out.println(range[i]);
}
}
You can add your values to Set. it will do all work for you.
int end = arr.length;
Set<Integer> set = new HashSet<Integer>();
for(int i = 0; i < end; i++){
set.add(arr[i]);
}
If you cannot use other data structures, here is a good solution: https://stackoverflow.com/a/17974322/2290763
Other solution are correct but they will give O(n^2), you don't need to use two for loops. This will give you O(n)
int[] range = {1, 1, 2, 2, 2, 3, 3, 3, 4, 5, 6, 6};
int temp = range[0];
if(temp != range[range.length-1]){
for (int i = 1; i < range.length; i++) {
if(temp != range[i]){
System.out.println(temp);
temp = range[i];
}
}
}
else
System.out.println(temp);
Try after sorting the array:
int[] range = { 1, 1, 2, 2, 2, 3, 3, 3, 4, 5, 6, 6 };
Arrays.sort(range);
System.out.println(range.length > 0 ? range[0]
: "No sufficient elements");
for (int i = 1; i < range.length; i++) {
if (range[i - 1] != range[i]) {
System.out.println(range[i]);
}
}
Each value in the array is either unique or occurs multiple times. There are no other cases.
So your task can be stripped down to just remove the duplicates and print everything else.
If the array is sorted then it is sufficient to just check against the last value while iterating to recognize duplicates.
I would do this:
int[] range = {1, 1, 2, 2, 2, 3, 3, 3, 4, 5, 6, 6};
Arrays.sort(range);
for (int i = 0; i < range.length; i++) {
if (i == 0) {
System.out.println(range[0]);
} else if (range[i - 1] != range[i]) {
System.out.println(range[i]);
}
}
Edited. Try this:
int[] range = { 1, 1, 2, 2, 2, 3, 3, 3, 4, 5, 6, 6};
for (int i = 0; i < range.length; i++) {
int j = i + 1;
for (; j < range.length && range[i] == range[j]; j++) {
// do nothing
}
if (j >= i + 2) {
System.out.println(range[i]);
i = j;
}
}
}
The problem in your solution is int this part
for (int i = 0; i < range.length; i++) {
for (int j = i + 1; j < range.length; j++) {
For every element in array you are checking is there element with same value, and index is greater than index of element.
For example, for element with index 2 (value 2) it's checking all (indexes: 3, 4, 5, 6, ...). And there are two matches (elements with index 3 and 4).
Edit: (After #FabianBarney comment)
Solution:
String uni = "Uniques: ";
String dup = "Duplicates: ";
int[] range = { 1, 1, 2, 2, 2, 3, 3, 3, 4, 5, 6, 6};
for (int i = 0; i < range.length; i++) {
if (i + 1 < range.length && range[i + 1] == range[i]) {
dup += range[i] + " ";
int j = i + 1;
while (j < range.length && range[i] == range[j]) {
j++;
}
i = j - 1;
} else {
uni += range[i] + " ";
}
}
System.out.println(uni);
System.out.println(dup);