Rotate array by arbitrary step size without creating second array - java

So for a step size of 1, I want the array:
{1, 2, 3, 4}
To become:
{4, 1, 2, 3}
And for a step of size 2 the result will be:
{3, 4, 1, 2}
This is the code I'm using now:
private static int[] shiftArray(int[] array, int stepSize) {
if (stepSize == 0)
return array;
int shiftStep = (stepSize > array.length ? stepSize % array.length : stepSize);
int[] array2 = new int[array.length];
boolean safe = false;
for (int i = 0; i < array.length; i++) {
if (safe) {
array2[i] = array[i - shiftStep];
}
else {
array2[i] = array[array.length - shiftStep + i];
safe = (i+1) - shiftStep >= 0;
}
}
return array2;
}
The code is working great, but is it possible to achieve this without creating a helper array (which is array2 in the code above)?
Thanks!

You can do it without creating as big an array:
// void return type as it shifts in-place
private static void shiftArray(int[] array, int stepSize) {
// TODO: Cope with negative step sizes etc
int[] tmp = new int[stepSize];
System.arraycopy(array, array.length - stepSize, tmp, 0, stepSize);
System.arraycopy(array, 0, array, stepSize, array.Length - stepSize);
System.arraycopy(tmp, 0, array, 0, stepSize);
}
So for a 100,000 array and a step size of 10, it creates a 10-element array, copies the last 10 elements into it, copies the first 999,990 elements to be later, then copies from the temporary array back to the start of the array.

Use not the i++, but i += shiftSize and several loops (amount of them would be equal to gcd of array.length and shifSize).
Then you'll need only one int as buffer and execution time will be almost the same.

You could do it with a couple of loops, but its not easy. Using recursion is simpler in this case.
public static void main(String... args) {
for (int i = 0; i < 12; i++) {
int[] ints = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
rotateLeft(ints, i);
System.out.println(Arrays.toString(ints));
}
}
public static void rotateLeft(int[] array, int num) {
rotateLeft(array, num, 0);
}
private static void rotateLeft(int[] array, int num, int index) {
if (index >= array.length) return;
int tmp = array[(index + num) % array.length];
rotateLeft(array, num, index + 1);
array[index] = tmp;
}
prints
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
[2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 1]
[3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 1, 2]
[4, 5, 6, 7, 8, 9, 10, 11, 12, 1, 2, 3]
[5, 6, 7, 8, 9, 10, 11, 12, 1, 2, 3, 4]
[6, 7, 8, 9, 10, 11, 12, 1, 2, 3, 4, 5]
[7, 8, 9, 10, 11, 12, 1, 2, 3, 4, 5, 6]
[8, 9, 10, 11, 12, 1, 2, 3, 4, 5, 6, 7]
[9, 10, 11, 12, 1, 2, 3, 4, 5, 6, 7, 8]
[10, 11, 12, 1, 2, 3, 4, 5, 6, 7, 8, 9]
[11, 12, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
[12, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]

Yes it's possible, you'd only need to temporary store one element additional to the array.
Basically what you want to do is to:
store last element in tmp var
shift all elements to the right by one starting with the second to last element
sotre tmp var as first element
repeat from step 1 depending on your stepsize

This is not tested ...
public void rotateByStep(int[] array, int step) {
step = step % array.length;
if (step == 0) {
return;
}
int pos = step;
int tmp = array[0];
boolean inc = array.length % step == 0;
for (int i = 0; i < array.length; i++) {
int tmp2 = array[pos];
array[pos] = tmp;
tmp = tmp2;
pos = (pos + step) % array.length;
if (inc && pos < step) {
array[pos] = tmp;
pos++;
tmp = array[pos];
}
}
}
The idea I'm trying to implement is as follows:
If step isn't a factor of length, then incrementing an index (pos) by step modulo length starting from zero will visit every array element once after length iterations.
If step is a factor of length, then index (incremented as above) will get back to its starting point after length / step iterations. But if you then increment by one, you can process the cycle starting at 1, and then at 2, and so on. After length iterations, we'll have visited every array element once.
The rest is just rippling the element values as we cycle through the element indexes ... with some adjustment when we increment to the next cycle.
The other complete solutions have the advantage that they are much easier to understand, but this one requires no extra heap storage (i.e. no temporary array), and does the job in array.length loop iterations.

In n- 1 iterations
#include <stdio.h>
int main(int argc, char **argv) {
int k = 0, x = 0;
int a[] = {-5,-4,-1,0,1,2,30,43,52,68,700,800,9999};
int N = 0, R = 57; /*R = No of rotations*/
int temp = 0, temp2 = 0, start = 0, iter = 0;
x = 0;
temp2 = a[x];
N = sizeof(a) / sizeof(a[0]);
for ( k = 0; k < N - 1; k++) {
x = x + R;
while ( x >= N ) {
x = x - N;
}
temp = a[x];
a[x] = temp2;
temp2 = temp;
if ( x == start ) {
start = start + 1;
x = x + 1;
temp2 = a[x];
}
iter++;
}
a[start] = temp2;
for ( k = 0; k < N; k++) {
printf(" %d", a[k]);
}
printf("\n");
printf("Done in %d iteration\n", iter);
return 0;
}

Related

How to sort array based on multiples of 3 using Java

I have an array like this one-
{1, 2, 3, 4, 5, 6}
I want to sort it in the order of multiples of 3 with remainders 0, 1 and 2. (the first group is multiples of 3, the second one is multiples of 3 with remainder 1 and the last one is multiples of 3 with remainder 2) and I want to preserve the order in which elements appear in the array.
The result should be -
{3, 6, 1, 4, 2, 5}
I have this code-
int current = 0;
int b = 0;
for (int i = 0; i < 3; i++) { //3 groups
for (int j = current; j < numbers.length; j++) {
if (numbers[j] % 3 == i) { //reminder should be 0,1 or 2
b = numbers[j];
numbers[j] = numbers[current];
numbers[current] = b;
current++;
}
}
}
But this code does not preserve the order in which elements appear in the array. The result I got is-
{3, 6, 1, 4, 5, 2}
But I want the result to be like {3, 6, 1, 4, 2, 5}. How can I achieve this?
Using stream and comparator
int[] array = {1, 2, 3, 4, 5, 6};
List<Integer> lst = Arrays.stream(array)
.boxed()
.sorted(Comparator.comparingInt(o -> o % 3))
.collect(Collectors.toList());
System.out.println(lst);
In your solution you are swapping the elements in place, which shuffles them from the initial order. That's why you don't have the same ordering at the end. I'm not sure if there is another way apart from having a second array to keep the sorted elements, while at the same time iterating over the original one like so:
public static void main(String[] args) {
int[] numbers = new int[]{1, 2, 3, 4, 5, 6};
int[] result = new int[numbers.length];
int b = 0;
int current = 0;
for (int i = 0; i < 3; i++) { //3 groups
for (int j = 0; j < numbers.length; j++) {
if (numbers[j] % 3 == i) { //reminder should be 0,1 or 2
result[current] = numbers[j];
current++;
}
}
}
System.out.println(Arrays.toString(result));
}
Output: [3, 6, 1, 4, 2, 5]
You can use an IntStream and a Comparator to sort the stream:
int[] arr = {1, 2, 3, 4, 5, 6};
int[] arrSorted = IntStream.of(arr).boxed()
.sorted(Comparator.comparingInt(i -> i % 3))
.mapToInt(Integer::intValue)
.toArray();
System.out.println(Arrays.toString(arrSorted));
Output:
[3, 6, 1, 4, 2, 5]
Note: From IntStream.of() javadoc:
Returns a sequential ordered stream whose elements are the specified
values.
I would create a new array of the same size and then place the elements in the correct order. For example like this:
int[] array = {1, 2, 3, 4, 5, 6};
int[] sorted = new int[array.length];
int counter = 0;
for (int i = 0; i < 3; i++) {
for (int j = 0; j < array.length; j++) {
if (array[j] % 3 == i) {
sorted[counter] = array[j];
counter++;
}
}
}
System.out.println(Arrays.toString(sorted));
Output:
[3, 6, 1, 4, 2, 5]
Alternatively, you can use Java 8 features to reduce the amount of code like this:
int[] array = {1, 2, 3, 4, 5, 6};
int[] sorted = Arrays.stream(array).boxed().sorted(Comparator.comparingInt(a -> (a % 3))).mapToInt(i -> i).toArray();
Output:
[3, 6, 1, 4, 2, 5]

How can I shift the elements of an Array to the order I desire? [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 1 year ago.
Improve this question
I'm working on a problem that says "Given an array of N items, take the item from the first position and arrange the array such that the item in its final ordered position and all of the items <= to that item come before it and all of the items >= come after it. The list is not sorted. Only one item is in its final order." What I am trying to do is sort an array so the I get the elements that are smaller than or equal to the element at array[0] to be in the array first then a[0], and at the end of the array should the elements that are greater than or equal to array[0]. For Example, if I have an array of 10 numbers like this "[3, 2, 8, 1, 9, 5, 1, 9, 5, 9]" My new array should be "[2, 1, 1, 3, 8, 9, 5, 9, 5, 9]". I've tried writing the code below but it doesn't work as it should. The output I get is instead [3, 5, 1, 2, 9, 9, 1, 9, 8, 5]. Can someone help me figure out how to fix this?
import java.util.Arrays;
import java.util.Random;
public class Q1 {
public static void main(String[] args) {
int[] d = createRandomIntArray(10);
System.out.println("Original Array: " + Arrays.toString(d));
changeOrder(d);
System.out.println("New Array: " + Arrays.toString(d));
}
public static int[] createRandomIntArray(int n) {
Random random = new Random();
int[] result = new int[n];
for (int i = 0; i < n; i++)
result[i] = random.nextInt(n);
return result;
}
public static void swap(int[] x, int i, int j) {
int temp = x[i];
x[i] = x[j];
x[j] = temp;
}
public static void changeOrder(int[] array) {
int count = 0;
for (int i = 0; i < array.length - 1; i++) {
if (array[0] <= array[i + 1]) {
swap(array, array[0], array[count++]);
} else if (array[0] >= array[i + 1]) {
swap(array, array[i + 1], array[array.length - 1]);
}
}
}
}
It seems that the algorithm should be reconsidered just to move the lower elements before the head element starting at position 0:
if current element is less than head, rotate all elements from head to current position to the right by 1.
Example implementation:
static void arrange(int[] arr) {
int head = 0;
for (int i = head + 1; i < arr.length; i++) {
if (arr[i] < arr[head]) {
rotate(arr, head, i);
head++;
}
}
}
static void rotate(int[] arr, int head, int i) {
int tmp = arr[i];
for (int j = i; j > head; j--) {
arr[j] = arr[j - 1];
}
arr[head] = tmp;
}
Test:
int[] arr = {3, 2, 8, 1, 9, 5, 1, 9, 5, 9};
System.out.println("before: " + Arrays.toString(arr));
arrange(arr);
System.out.println("after: " + Arrays.toString(arr));
Output:
before: [3, 2, 8, 1, 9, 5, 1, 9, 5, 9]
after: [2, 1, 1, 3, 8, 9, 5, 9, 5, 9]
int[] arr = {9, 2, 8, 1, 9, 5, 1, 9, 5, 9};
System.out.println("before: " + Arrays.toString(arr));
arrange(arr);
System.out.println("after: " + Arrays.toString(arr));
Output:
before: [9, 2, 8, 1, 9, 5, 1, 9, 5, 9]
after: [2, 8, 1, 5, 1, 5, 9, 9, 9, 9]

Fibonacci Sequence printing out all values in an array EDIT

Okay my new question is how I can let the array print out all numbers of the segment. At the moment I can input a number and the code will print out the corresponding value in Fibonacci. However, I would like the array to print out all values leading up to the answer. Ex. Input = 7, array prints out 0, 1, 1, 2, 3, 5, 8 instead of just 8
package math;
public class Fibonacci {
public static long getFib(int n) {
long Fibby[] = new long[n+1];
Fibby[0] = 1;
Fibby[1] = 1;
for(int i = 2; i<=n; i++) { //initialize loop
Fibby[i] = Fibby[i-1] + Fibby[i-2];
} // end of for loop
return Fibby[n]; //end method getfib
}
}
And the runner
package math;
Scanner key = new Scanner(System.in);
Fibonacci f = new Fibonacci();
int p;
System.out.println("Fib value : ");
p = key.nextInt();
System.out.println( "Fib Value of "+ p +" :: " + f.getFib(p) );
}
How can this happen? My question has been downsized.
You can't run your main method, because System.out.println() expects a parameter it can print. However, your fib() method returns void, so there is nothing to print. Add a return type to your fib() method, and your error in main() will be resolved. Here's a demonstration of printing the 0th to 12th Fibonacci numbers:
FibonacciRunner.java
public class FibonacciRunner
{
public static void main(String[] args)
{
for(int i = 0; i <= 12; i++)
{
System.out.println(Fibonacci.fib(i));
}
for(int i = 0; i <= 12; i++)
{
System.out.println(Fibonacci.fibList(i));
}
}
}
Fibonacci.java
public class Fibonacci
{
public static long fib(int n)
{
long current = 0;
long next = 1;
for(int i = 0; i < n/2; i++)
{
current += next;
next += current;
}
return n % 2 == 0 ? current : next;
}
public static List<Long> fibList(int n)
{
List<Long> ret = new ArrayList<>(n == 0 ? List.of(0L) : List.of(0L, 1L));
long current = 0;
long next = 1;
for(int i = 0; i < n/2; i++)
{
current += next;
next += current;
if(i*2+1 <= n)
ret.add(current);
if(i*2+2 < n)
ret.add(next);
}
return ret;
}
}
Output:
0
1
1
2
3
5
8
13
21
34
55
89
144
[0]
[0, 1]
[0, 1, 1]
[0, 1, 1, 2]
[0, 1, 1, 2, 3]
[0, 1, 1, 2, 3, 5]
[0, 1, 1, 2, 3, 5, 8]
[0, 1, 1, 2, 3, 5, 8, 13]
[0, 1, 1, 2, 3, 5, 8, 13, 21]
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34]
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144]
One problem with your code is that Fibonacci.fib doesn't return anything, so what are you expecting the FibonacciRunner to print?
Another is that arrays in Java have fixed length. Consider using a List instead:
List fibby = new ArrayList();
fibby.add(0);
fibby.add(1);
for (int i = 2; i < n; i++){
fibby.add(fibby.get(i - 1) + fibby.get(i - 2));
}

Concatenating two arrays with alternating values

What is the best way to concatenate two arrays with alternating values?
Let's say array1 is:
[1, 3, 5, 7]
array2 is:
[2, 4, 6, 8]
I want to combine these two arrays, so that the result is:
[1, 2, 3, 4, 5, 6, 7, 8]
In Java:
int[] a1 = { 1, 3, 5, 7 };
int[] a2 = { 2, 4, 6, 8 };
int[] concat = new int[a1.length * 2];
for (int i = 0; i < concat.length; i++) {
// concatenation
}
System.out.println(concat.toString());
// should be [1, 2, 3, 4, 5, 6, 7, 8]
Update: No sorting is required, as the arrays are already sorted, using Arrays.sort(array)
A basic way
int[] concat = new int[a1.length * 2];
int index = 0;
for (int i = 0; i < a1.length; i++) {
concat[index++] = a1[i];
concat[index++] = a2[i];
}
assuming that both array will be of same size.
Put the elements of both array in a list and then sort it.You can use lambdas also
Integer[] a1 = { 1, 3, 5, 7 };
Integer[] a2 = { 2, 4, 6, 8 };
List<Integer> list = new ArrayList<>();
list.addAll(Arrays.asList(a1));
list.addAll(Arrays.asList(a2));
System.out.println("Before Sorting "+list);
Collections.sort(list,(a, b) -> Integer.compare(a,b));
System.out.println("After Sorting "+list);
Output
Before Sorting [1, 3, 5, 7, 2, 4, 6, 8]
After Sorting [1, 2, 3, 4, 5, 6, 7, 8]
If you want to zip together any length arrays (where then lengths differ, the remaining is appended to the result):
public static int[] zip(int[] a, int[] b){
int[] result = new int[a.length + b.length];
int index = 0;
final int minLen = Math.min(a.length, b.length);
for (int i = 0; i < minLen; i++) {
result[index++] = a[i];
result[index++] = b[i];
}
if(a.length > minLen)
System.arraycopy(a, minLen, result, index, a.length - minLen);
else if(b.length > minLen)
System.arraycopy(b, minLen, result, index, b.length - minLen);
return result;
}
Try it like this:
int[] concat = new int[a1.length + a2.length];
int k = 0, m = 0;
for (int i = 0; i < concat.length; i++) {
if( k < al.length && a1[k] <= a2[m])
concat[i] = a1[k++];
else
concat[i] = a2[m++];
}
NB: The result will be sorted as in your desired output.
you could also use two variables in your loop like this
int[] a1 = { 1, 3, 5, 7 };
int[] a2 = { 2, 4, 6, 8 };
int[] concat = new int[a1.length + a2.length];
for (int i = 0, j = 0; i+j < concat.length;) {
if(i<a1.length) {
concat[i+j] = a1[i++];
}
if(j<a2.length) {
concat[i+j] = a2[j++];
}
}
System.out.println(Arrays.toString(concat));
Try This if it solves ur problem
int[] a1 = { 1, 3, 5, 7 };
int[] a2 = { 2, 4, 6, 8 };
int[] concat = new int[a1.length + a2.length];
System.arraycopy(a1, 0, concat, 0, a1.length);
System.arraycopy(a2, 0, concat, a1.length, a2.length);
Arrays.sort(concat);
System.out.println(Arrays.toString(concat));
Output:
[1, 2, 3, 4, 5, 6, 7, 8]
There are utility methods for example addALL() method from ArrayUtil class. But what they do is simple concatenate. For your problem you need to write your own logic. For example the following code ensures correct alternate concatenation even if arrays are of unequal length.
int[] a1 = { 1, 3, 5, 7 };
int[] a2 = { 2, 4, 6, 8, 9, 10, 122 };
int totalLen = a1.length + a2.length;
int[] concat = new int[totalLen];// I made a change here incase the
// arrays are not of equal length
int i = 0; // this will be the concat array index counter
int j1 = 0; // this will be the a1 array index counter
int j2 = 0; // this will be the a2 array index counter
while (i < totalLen) {
if ((j1 < a1.length)) {
concat[i] = a1[j1];
i++;
j1++;
}
if ((j2 < a2.length)) {
concat[i] = a2[j2];
i++;
j2++;
}
}

How to remove a row from a 2d array?

I have a simple array, sort of like this:
1 2 3 4 5 6 7 8 9
6 2 7 2 9 6 8 10 5
2 6 4 7 8 4 3 2 5
9 8 7 5 9 7 4 1 10
5 3 6 8 2 7 3 7 2
So, let's call this matrix[5][9]. I wish to now remove every row within this matrix that contains a certain value, in this case 10, so I am left with...
1 2 3 4 5 6 7 8 9
2 6 4 7 8 4 3 2 5
5 3 6 8 2 7 3 7 2
Here's a sample class you can run that I believe does what you're looking for. Removing rows from 2D arrays is tricky business because like #KalebBrasee said, you can't really "remove" them, but rather you have to make a whole new 2D array instead. Hope this helps!
import java.util.ArrayList;
import java.util.List;
public class Matrix {
private double[][] data;
public Matrix(double[][] data) {
int r = data.length;
int c = data[0].length;
this.data = new double[r][c];
for (int i = 0; i < r; i++) {
for (int j = 0; j < c; j++) {
this.data[i][j] = data[i][j];
}
}
}
/* convenience method for getting a
string representation of matrix */
public String toString() {
StringBuilder sb = new StringBuilder(1024);
for (double[] row : this.data) {
for (double val : row) {
sb.append(val);
sb.append(" ");
}
sb.append("\n");
}
return (sb.toString());
}
public void removeRowsWithValue(final double value) {
/* Use an array list to track of the rows we're going to want to
keep...arraylist makes it easy to grow dynamically so we don't
need to know up front how many rows we're keeping */
List<double[]> rowsToKeep = new ArrayList<double[]>(this.data.length);
for (double[] row : this.data) {
/* If you download Apache Commons, it has built-in array search
methods so you don't have to write your own */
boolean found = false;
for (double testValue : row) {
/* Using == to compares doubles is generally a bad idea
since they can be represented slightly off their actual
value in memory */
if (Double.compare(value, testValue) == 0) {
found = true;
break;
}
}
/* if we didn't find our value in the current row,
that must mean its a row we keep */
if (!found) {
rowsToKeep.add(row);
}
}
/* now that we know what rows we want to keep, make our
new 2D array with only those rows */
this.data = new double[rowsToKeep.size()][];
for (int i = 0; i < rowsToKeep.size(); i++) {
this.data[i] = rowsToKeep.get(i);
}
}
public static void main(String[] args) {
double[][] test = {
{1, 2, 3, 4, 5, 6, 7, 8, 9},
{6, 2, 7, 2, 9, 6, 8, 10, 5},
{2, 6, 4, 7, 8, 4, 3, 2, 5},
{9, 8, 7, 5, 9, 7, 4, 1, 10},
{5, 3, 6, 8, 2, 7, 3, 7, 2}};
//make the original array and print it out
Matrix m = new Matrix(test);
System.out.println(m);
//remove rows with the value "10" and then reprint the array
m.removeRowsWithValue(10);
System.out.println(m);
}
}
Use System.arraycopy or use java.util.List instead of arrays. ArrayList has fast access to random elements and a slow remove method, it's the opposite with LinkedList. You have to choose for yourself.
At the and you have to recreate the array and discard the old one. Changing the dimension of an existing array is not possible - if want this type of datastructure, then you should build the matrix based on Collections (ArrayList<ArrayList<Double>>), there you can remove a row easily.
Back to arrays - the idea is to collect all rows (double[] arrays) that you want to keep, create a result array with those rows and replace the old one with the new on on Matrix:
public void doSomethingWith(Matrix in) {
List<double[]> survivingRows = new ArrayList<double[]>();
for (double[] row:in.getRows()) {
if (isAGoodOne(row)) {
survivingRows.add(row);
}
}
double[][] result = new double[survivingRows][];
for (int i = 0; i < result.length; i++) {
result[i] = survivingRows.get(i);
}
in.setArray(result);
}
You can't remove elements from the Java built-in array data structure. You'll have to create a new array that has a length one less than the first array, and copy all the arrays into that array EXCEPT the one you want to remove.
My java syntax is a little rusty, but the following, if treated as pseudocode will work
public Matrix removeRows(Matrix input) {
int[][] output = new int[input.numRows][input.numColumns]();
int i = 0;
for (int[] row : input.rows()) { // Matrix.rows() is a method that returns an array of all the rows in the matrix
if (!row.contains(10)) {
output[i] = row;
}
}
return output
My take:
import java.util.Arrays;
public class RemoveArrayRow {
private static <T> T[] concat(T[] a, T[] b) {
final int alen = a.length;
final int blen = b.length;
if (alen == 0) {
return b;
}
if (blen == 0) {
return a;
}
final T[] result = (T[]) java.lang.reflect.Array.newInstance(a.getClass().getComponentType(), alen + blen);
System.arraycopy(a, 0, result, 0, alen);
System.arraycopy(b, 0, result, alen, blen);
return result;
}
public static void main(String[] args) {
double[][] d = { {11, 2, 3, 4, 5, 6, 7, 8, 9, 0},
{12, 2, 3, 4, 5, 6, 7, 8, 9, 1},
{13, 2, 3, 4, 5, 6, 7, 8, 9, 2},
{14, 2, 3, 4, 5, 6, 7, 8, 9, 3},
{15, 2, 3, 4, 5, 6, 7, 8, 9, 4} };
//remove the fourth row:
// (1)
double[][] d1 = concat(Arrays.copyOf(d, 3), Arrays.copyOfRange(d, 4, 5));
// (2)
double[][] d2 = new double[d.length - 1][d[0].length];
System.arraycopy(d, 0, d2, 0, 3);
System.arraycopy(d, 4, d2, 3, 1);
System.out.print(d1.length);
System.out.print(d2.length);
}
}
(1)
If you exclude the concat() function used for concatenating two arrays, it's done in one line:
double[][] d1 = concat(Arrays.copyOf(d, 3), Arrays.copyOfRange(d, 4, 5));
See this question as well. That's where the code for the concat() function comes from.
(2)
This method is faster and only uses already available functions.
Since it cannot avoid creating new 2D array to contain the after-removed data, firstly, create a new 2D int[][] b with same dimension as a[][]. secondly, loop through a[][], assign a to b and move b row up when a contain specific value. and sanity check the last row, which can contain specific data.
public static int[][] remove(int[][] a, int v) {
int r = a.length;
int c = a[0].length;
int[][] b = new int[r][c];
int red = 0;
boolean s = false;
for (int i = 0; i < r; i++) {
for (int j = 0; j < c; j++) {
b[i - red][j] = a[i][j];
if (a[i][j] == v) {
red += 1;
if(i==r-1){
s = true;
}
break;
}
}
}
//check last row
if(s){
for(int i = r-red;i <r-red +1; i++ )
for (int j = 0; j<c; j++){
b[i][j] = 0;
}
}
return b;
}
public static void main(String[] args){
int[][] a = { {1, 2, 3, 4, 5, 6, 7, 8, 1},
{6, 2, 7, 2, 9, 6, 8, 10, 5},
{2, 6, 4, 7, 8, 4, 2, 2, 5},
{9, 8, 7, 5, 9, 7, 4, 1, 1},
{5, 3, 6, 8, 2, 7, 3, 1, 1} };
print(remove(a, 10));
}
public static void print(int[][] a) {
int r = a.length;
int c = a[0].length;
int red = 0;
for (int i = 0; i < r; i++) {
System.out.printf("\nrow %d, \n", i);
for (int j = 0; j < c; j++) {
System.out.printf("%d, ", a[i][j]);
}
}
}
This may not be an exact solution but a concept of how you can achieve it using System.arraycopy.
In the example below, I want to copy all the rows except the first row. In your case, you can skip those rows which contain 10.
String[][] src = getSheetData(service, spreadSheetId, range);
String[][] dest = new String[src.length-1][src[0].length];
for (int i = 1; i < src.length; i++) {
System.arraycopy(src[i], 0, dest[i-1], 0, src[0].length-1);
}
Reference: https://docs.oracle.com/javase/6/docs/api/java/lang/System.html#arraycopy%28java.lang.Object,%20int,%20java.lang.Object,%20int,%20int%29
You can use IntStream.noneMatch method for this purpose:
int[][] arr1 = {
{1, 2, 3, 4, 5, 6, 7, 8, 9},
{6, 2, 7, 2, 9, 6, 8, 10, 5},
{2, 6, 4, 7, 8, 4, 3, 2, 5},
{9, 8, 7, 5, 9, 7, 4, 1, 10},
{5, 3, 6, 8, 2, 7, 3, 7, 2}};
int[][] arr2 = Arrays.stream(arr1)
.filter(row -> Arrays.stream(row).noneMatch(i -> i == 10))
.toArray(int[][]::new);
// output
Arrays.stream(arr2).map(Arrays::toString).forEach(System.out::println);
Output:
[1, 2, 3, 4, 5, 6, 7, 8, 9]
[2, 6, 4, 7, 8, 4, 3, 2, 5]
[5, 3, 6, 8, 2, 7, 3, 7, 2]

Categories