I am trying to map the items in 1-dimensional double[] to 2-dimensional double[][], in a way that it is arranged in a matrix. For example, [1, 2, 3, 4] would be converted into a 2*2 array with [1, 2] in the first row and then [3, 4] in the second row. No values are given, so I need to put the variables instead of the actual integers, though.
How do I do this?
I tried pushing and slicing, but they only work for int not double.
You can use modulo to map the x index and a simple division to map the y index of the two-dimensional array two the one-dimensional index.
The solution initializes the array with zeroes first. Time and memory complexity would obviously be Θ(xy).
function reshape(oneDimArray, x, y) {
if(x < 0 || y < 0) throw new RangeError(`x and y must not be negative`)
const twoDimArray = [...new Array(y)].map(_ => {
const array = new Array(x);
array.fill(0, 0, array.length);
return array;
});
for (let i = 0; i < oneDimArray.length; i++) {
const yIndex = Math.floor(i / x);
const xIndex = i % x;
twoDimArray[yIndex][xIndex] = oneDimArray[i];
}
return twoDimArray;
}
const sample = [1, 2, 3, 4];
console.log(reshape(sample, 2, 2));
console.log(reshape(sample, 2, 4));
console.log(reshape(sample, 1, 4));
console.log(reshape(sample, 3, 4));
/* StackOverflow snippet: console should overlap rendered HTML area */
.as-console-wrapper { max-height: 100% !important; top: 0; }
The same algorithm implemented in Java would look like this:
import java.util.Arrays;
public class Application {
public static void main(String[] args) {
var sample = new double[]{ 1d, 2d, 3d, 4d };
System.out.println(Arrays.deepToString(reshape(sample, 2, 2)));
System.out.println(Arrays.deepToString(reshape(sample, 2, 4)));
System.out.println(Arrays.deepToString(reshape(sample, 1, 4)));
System.out.println(Arrays.deepToString(reshape(sample, 3, 4)));
}
public static double[][] reshape(double[] oneDimArray, int x, int y)
{
if(x < 0 || y < 0) throw new IllegalArgumentException("x and y must not be negative");
var twoDimArray = new double[y][x];
for (var i = 0; i < oneDimArray.length; i++) {
var yIndex = (int)(i / x);
var xIndex = i % x;
twoDimArray[yIndex][xIndex] = oneDimArray[i];
}
return twoDimArray;
}
}
Related
I have a function public static void sortedlist(int[] l, int r) that takes an array int[] l and returns a new array where every non-negative element in the list would be added with every element until the rth element.
So here is an example.
Lets say we have l = {1, 2, -3, 4, 5, 4}, and r = 3. In this case, we would:
Replace l[0] with l[0] + l[1] + l[2] + l[3].
Replace l[1] with l[1] + l[2] + l[3] + l[4].
Not do anything to l[2] because it is negative.
Replace l[3] with l[3] + l[4] + l[5]. (We can't go further than the end of the array.)
Replace l[4] with l[4] + l[5].
Not change the value of a[5] because there are no values after l[5]. So the sum is l[5] itself.
Thus, the result after calling `sortedlist` would be {4, 8, -3, 13, 9, 4}.
Here is my code so far:
public class Practice2 {
public static void sortedlist(int[] l, int r) {
int[] A;
int sum = 0;
for (int i = 0; i < l.length + r; i+=r) {
sum = sum +=
}
}
}
As you can see, I'm not done with the code because I'm stumped on how am I supposed to move forward from this point.
What I'm trying to do is create a new Array A and then add the new values that I've received from sum into Array A.
Any help would be greatly appreciated. Furthermore, if you could explain the logic behind a working code would be extremely beneficial for me as well.
Thank you :)
Try this.
public static void sortedlist(int[] l, int r) {
for (int i = 0, max = l.length; i < max; ++i)
if (l[i] >= 0)
for (int j = i + 1; j <= i + r && j < max; ++j)
l[i] += l[j];
}
and
int[] a = {1, 2, -3, 4, 5, 4};
sortedlist(a, 3);
System.out.println(Arrays.toString(a));
output:
[4, 8, -3, 13, 9, 4]
Please find the solution below and i have also provided some explanation regarding the logic behind it.
Note: I have unit tested it for few cases and it seems working fine.
1) r is less than array length
2) r is equals to array length
3) r is greater than array length
public class Test {
public static void main(String[] args) {
int[] input = new int[]{1, 2, -3, 4, 5, 4};
int r = 3;
sortedlist(input,r);
}
public static void sortedlist(int[] l, int r) {
List<Integer> list = new ArrayList<>();
int itr = 0;
for(int i = itr; i < l.length ; i++){//This loop is for iterating over the given array
int temp = 0;
int itr2 = Math.min(itr + r, l.length-1);//This function takes the minimum value and it helps when the (itr+r) > l.length, it will consider the (l.length-1)
if(l[i] > 0){// checking whether the selected value is -ve or not
for(int j = i; j <= itr2 ; j++){ // This loop is for calculating the addition over the selected range
temp = temp + l[j];
}
} else {// if it is-ve, assigning the same value to temp
temp = l[i];
}
list.add(temp);// storing the calculated value in a list of integers
itr++; // incrementing the main loop iterator
}
System.out.println(list);
}
}
Output:
[4, 8, -3, 13, 9, 4]
Given an array of integers and a number, I need to perform left rotations on the array and return the updated array to be printed as a single line of space-separated integers.
I pass 7/9 checks, but some with large arrays fail because of time-out.
The time has to be <= 4 sec.
static int[] rotLeft(int[] a, int d) {
int x = 0;
while (x != d) {
int first = a[0];
int last = a[a.length - 1];
for (int i = 0; i < a.length - 1; i++) {
a[i] = a[i + 1];
if (i == a.length - 2)
a[a.length - 2] = last;
a[a.length - 1] = first;
}
x++;
}
return a;
}
you're rotating only one position at a time, it is very slow, it is better to shift elements to appropriate places, for example:
static int[] rotLeft(int[] a, int d) {
if (d == 0 || a == null || a.length == 0) {
return a;
}
int[] b = new int[a.length];
for (int i = 0; i < a.length; i++) {
b[i] = a[(i + d) % a.length];
}
return b;
}
There are two things you could apply to this problem to improve the runtime.
Ensure that d is less than a.length. If d is greater than a.length, then you are rotating elements past their original position and wasting cycles. An easy way to achieve this is with the modulus assignment operator (i.e., d %= a.length, which is equivalent to d = d % a.length).
Elements should be shifted by the whole distance we are rotating, rather than shifting by one space each time. This allows us to perform the entire operation is 1 action, instead of in d action(s).
Applying these two principles would give us the following code:
static int[] rotLeft(int[] a, int d) {
if (d < 0) {
d = a.length - (-d % a.length);
}
d %= a.length;
if (d == 0) {
return a;
}
int first = a[0];
int i = 0;
int position = 0;
while (i < a.length) {
a[position] = a[(position + d) % a.length];
position = (position + d) % a.length;
i++;
}
a[a.length - d] = first;
return a;
}
You make multiple passes, each time rotating by one place, which makes your program slow.
There are at least 3 approaches to improve your program:
allocate a new array and put elements in appropriate locations, instead of rotating in place
use a buffer to store d elements while rotating others in place
use a juggling algorithm https://www.google.com/amp/s/www.geeksforgeeks.org/array-rotation/amp/
The third option performs rotation in place.
It may be worthwhile to microbenchmark all 3 to compare the speed for different input sizes
Of course you can repeat the rotation d times as you did in your sample code. But much faster would be if you would calculate the shift and do it in one go:
import static java.lang.System.*;
static int[] rotLeft( int[] a, int d )
{
var len = a.length;
var shift = d % len;
var buffer = new int[len];
arraycopy( a, shift, buffer, 0, len - shift );
arraycopy( a, 0, buffer, len - shift, shift );
arraycopy( buffer, 0, a, 0, len );
return a;
}
Of course, instead of System.arraycopy() you can use a for-loop. If you are not forced to return a, you can omit the third call to arraycopy() and return buffer instead; this would leave the original array unchanged, too.
To output the array, try this:
var joiner = new StringJoiner( " " );
for( var v : a ) joiner.add( Integer.toString( v ) );
System.out.println( joiner.toString() );
For better performance, you should use the built-in array copy methods.
If you have to update the existing array, like your code is doing, I'd recommend doing it like this:
static int[] rotLeft(int[] a, int d) {
if (a == null || a.length <= 1)
return a; // nothing to rotate
int shift = (d % a.length + a.length) % a.length; // normalize d
if (shift == 0)
return a; // no or full rotation(s)
int[] t = Arrays.copyOfRange(a, 0, shift);
System.arraycopy(a, shift, a, 0, a.length - shift);
System.arraycopy(t, 0, a, a.length - shift, shift);
return a;
}
If the returned array must be different, like this other answers do, I'd do it like this:
static int[] rotLeft(int[] a, int d) {
if (a == null || a.length <= 1)
return Arrays.copyOf(a, a.length); // nothing to rotate
int shift = (d % a.length + a.length) % a.length; // normalize d
if (shift == 0)
return Arrays.copyOf(a, a.length); // no or full rotation(s)
int[] t = new int[a.length];
System.arraycopy(a, shift, t, 0, a.length - shift);
System.arraycopy(a, 0, t, a.length - shift, shift);
return t;
}
Both of the above solution allow d to exceed the size of the array, i.e. do more than a full rotation, and to use negative values, i.e. rotate right instead of left.
Test
System.out.println(Arrays.toString(rotLeft(new int[] { 1, 2, 3, 4, 5 }, 1)));
System.out.println(Arrays.toString(rotLeft(new int[] { 1, 2, 3, 4, 5 }, 3)));
System.out.println(Arrays.toString(rotLeft(new int[] { 1, 2, 3, 4, 5 }, 5)));
System.out.println(Arrays.toString(rotLeft(new int[] { 1, 2, 3, 4, 5 }, 7)));
System.out.println(Arrays.toString(rotLeft(new int[] { 1, 2, 3, 4, 5 }, -7)));
Output
[2, 3, 4, 5, 1]
[4, 5, 1, 2, 3]
[1, 2, 3, 4, 5]
[3, 4, 5, 1, 2]
[4, 5, 1, 2, 3]
You don't have to do the rotations one by one. If you rotate by d, the element at index i moves to index i - d when i >= d, and into index N + i - d when i < d. Makes sense?
int[] result = new int[a.length]
for (int i = 0; i < a.length; i++) {
if (i < d) {
result[a.length + i - d] = a[i];
} else {
result[i - d] = a[i];
}
}
return result;
To handle the case where d >= a.length, you can add d = d % a.length as a pre-processing step.
I want to divide a number x into y pieces and I want all possible configurations to do this. How can I do this efficiently?
Example x=100, y=3. I could do this:
int x = 100;
for (int a = 1; a < x; a++) {
for (int b = a; b < x; b++) {
for (int c = b; c < x; c++) {
if (a+b+c == x) {
//DO SOMETHING
}
}
}
}
I think this would work (correct me if I'm wrong) but of course is not very efficient at all because I only want the cases where the if statement is true. And with larger y it takes ages. How could I do this efficiently?
From your algorithm, I can see that you want x=a+b+c with a<=b<=c.
Obviously for y = 3, we have 1<=a<=x/3, then a<=b<=(x-a)/2, c=x-b-a
For an given y, we get: 1<=a1<=x/y, a1<=a2<=(x-a1)/(y-1), ... ai<=a(i+1)<=(x-a1-...-ai)/(y-i)
But in you want a solution for an arbitrary y, you need a recursive algorithm.
Here is a java implementation:
public void split(int number, int pieces) {
total = 0;
dosplit(number, pieces, new ArrayList<Integer>());
}
private void dosplit(int number, int pieces, List<Integer> begin) {
if (pieces == 1) {
if (begin.isEmpty() || (number >= begin.get(begin.size() - 1))) {
begin.add(number);
total += 1;
//DO SOMETHING WITH BEGIN
begin.remove(begin.size() - 1);
}
}
else {
int start, end;
start = (begin.isEmpty()) ? 1 : begin.get(begin.size() - 1);
end = 1 + (1 + number - start)/pieces;
for(int i=start; i<=end; i++) {
begin.add(i);
dosplit(number - i, pieces - 1, begin);
begin.remove(begin.size() - 1);
}
}
split(10,3) correctly yields :
[1, 1, 8]
[1, 2, 7]
[1, 3, 6]
[1, 4, 5]
[2, 2, 6]
[2, 3, 5]
[2, 4, 4]
[3, 3, 4]
with as little useless steps as possible.
But split(504, 18) would yield an unmanageable number or solutions :-(
I want to save all the int[] data in my array list so i can see every thing step by step. Only my problem is that it overrides the already existing int[] in my ArrayList.
how can i fill my array list without overriding my old int in the ArrayList?
ArrayList<int[]> lijstje = new ArrayList<int[]>();
public int[] data = {7,4,8,56,67,85,23,65,23,65,23,22};
int stemp;
int len = 10;
public void shellSort(){
while (h <= len / 3) {
h = h * 3 + 1;
}
while (h > 0) {
for (outer = h; outer < len; outer++) {
stemp = data[outer];
inner = outer;
while (inner > h - 1 && data[inner - h] >= stemp) {
data[inner] = data[inner - h];
inner -= h;
}
data[inner] = stemp;
lijstje.add(data);
}
h = (h - 1) / 3;
}
}
Arrays are stored as references, so when you change the array one place, anywhere else you directly stored it will change to. Instead, make a brand new array with the same values, and store that. To do that, do array.clone(), so for you
ArrayList<int[]> lijstje = new ArrayList<int[]>();
public int[] data = {7,4,8,56,67,85,23,65,23,65,23,22};
int stemp;
int len = 10;
public void shellSort(){
while (h <= len / 3) {
h = h * 3 + 1;
}
while (h > 0) {
for (outer = h; outer < len; outer++) {
stemp = data[outer];
inner = outer;
while (inner > h - 1 && data[inner - h] >= stemp) {
data[inner] = data[inner - h];
inner -= h;
}
data[inner] = stemp;
lijstje.add(data.clone()); // Notice here how it's data.clone() instead of just data
}
h = (h - 1) / 3;
}
}
Here's an example showing how arrays are passed by referencing, this
int[] original = { 1, 2, 3 };
int[] passedByReference = original;
int[] cloned = original.clone();
System.out.println("Before:");
System.out.println(Arrays.toString(original));
System.out.println(Arrays.toString(passedByReference));
System.out.println(Arrays.toString(cloned));
original[0]=10;
System.out.println("After:");
System.out.println(Arrays.toString(original));
System.out.println(Arrays.toString(passedByReference));
System.out.println(Arrays.toString(cloned));
will have the following output
Before:
[1, 2, 3]
[1, 2, 3]
[1, 2, 3]
After:
[10, 2, 3]
[10, 2, 3]
[1, 2, 3]
as you can see, the cloned one is not affected, whereas the original and passed-by-reference ones are. In your code, you don't want changes to the original to affect the array you store, so you must clone it some way (array.clone() is a nice simple way for a 2D array).
Say I have the following 2d array in Java set to a variable named myMap:
1 3 1
3 2 3
1 3 1
The next step in my program is to add rows and columns of zeros as follows:
1 0 3 0 1
0 0 0 0 0
3 0 2 0 3
0 0 0 0 0
1 0 3 0 1
Basically, I'm adding arrays of zero into the spaces between the previous rows/columns. I then fill them in with appropriate numbers (irrelevant to my question) and repeat the process (adding more rows/columns of zeros) a finite number of times.
My question is as follows- what is the easiest and most efficient way to do this in Java? I know I could create a new 2d array and copy everything over, but I feel like there may be a more efficient way to do this. My intuition says that a 2d ArrayList may be the better way to go.
Also, and this my be important, when my program begins, I DO know what the maximum size this 2d array. Also, I cannot expect the symmetry of the numbers that I put in for this example (these were just put in for a good visual reference).
Here's a solution with ArrayLists: (test included)
int[][] ar = new int[][]
{
{ 0, 1, 2 },
{ 3, 4, 5 },
{ 6, 7, 8 } };
ArrayList<ArrayList<Integer>> a = new ArrayList<>(ar.length);
ArrayList<Integer> blankLine = new ArrayList<>(ar.length * 2 - 1);
for (int i = 0; i < ar.length * 2 - 1; i++)
{
blankLine.add(0);
}
for (int i = 0; i < ar.length; i++)
{
ArrayList<Integer> line = new ArrayList<>();
for (int j = 0; j < ar[i].length; j++)
{
line.add(ar[i][j]);
if (j != ar[i].length - 1)
line.add(0);
}
a.add(line);
if (i != ar.length - 1)
a.add(blankLine);
}
for (ArrayList<Integer> b : a)
{
System.out.println(b);
}
Output:
[0, 0, 1, 0, 2]
[0, 0, 0, 0, 0]
[3, 0, 4, 0, 5]
[0, 0, 0, 0, 0]
[6, 0, 7, 0, 8]
Algorithm
int[][] appendRows(int[][] bag, int[]... rows) {
int[][] extendedBag = new int[bag.length + rows.length][];
int i = 0;
for (int[] row : bag) { fillRow(extendedBag, row, i++); }
for (int[] row : rows) { fillRow(extendedBag, row, i++); }
return extendedBag;
}
// WHERE #fillRow(int[][], int[], int) =
void fillRow(int[][] bag, int[] row, int i) {
bag[i] = new int[row.length];
System.arraycopy(row, 0, bag[i++], 0, row.length);
}
Demo
import java.util.Arrays;
/** Utilities for 2D arrays. */
public class Array2dUtils {
public static void main(String[] args) {
int[][] bag = new int[][] {
{ 0 },
{ 1, 1 },
{ 2, 2, 2 }
};
int[] row1 = new int[] { 3, 3};
int[] row2 = new int[] { 4 };
int[][] biggerBag = appendRows(bag, row1, row2);
System.out.println("Bag:\n" + toString(bag));
System.out.println("Bigger Bag:\n" + toString(biggerBag));
}
/** Append one or more rows to a 2D array of integers. */
public static int[][] appendRows(int[][] bag, int[]... rows) {
int[][] extendedBag = new int[bag.length + rows.length][];
int i = 0;
for (int[] row : bag) { fillRow(extendedBag, row, i++); }
for (int[] row : rows) { fillRow(extendedBag, row, i++); }
return extendedBag;
}
/* fill i-th item of the bag */
private static void fillRow(int[][] bag, int[] row, int i) {
bag[i] = new int[row.length];
System.arraycopy(row, 0, bag[i++], 0, row.length);
}
/** Pretty-prints a 2D array of integers. */
public static String toString(int[][] bag) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < bag.length; ++i) {
sb.append(Arrays.toString(bag[i])).append("\n");
}
return sb.toString();
}
}
$ javac Array2dUtils.java
$ java -cp "." Array2dUtils
Bag:
[0]
[1, 1]
[2, 2, 2]
Bigger Bag:
[0]
[1, 1]
[2, 2, 2]
[3, 3]
[4]