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).
Related
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;
}
}
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]
I have a for loop that is trying to extend an array by adding new array element that is double the previous value.
e.g.
starting at : array = {1}
ending at : array = {1, 2, 4, 8, 16, etc}
Currently my for loop spits out an array like this : array = {1, 2, 2, 4, 4, 8, 8, 16}
It puts the same number in twice for some reason.
Just see the variable "input" as 21
for (int i = 0; (nums[i] * 2) < input; i++)
{
if (i == 0)
{
nums = IncreaseArrayInt(nums, nums[(i)] * 2);
}
else
{
nums = IncreaseArrayInt(nums, nums[(i - 1)] * 2);
}
}
Heres the function i used to extend the array:
static int[] IncreaseArrayInt(int[] oldArray, int insertValue)
{
int[] newArray = new int[oldArray.length + 1];
for(int i = 0; i < oldArray.length; i++)
{
newArray[i] = oldArray[i];
}
newArray[oldArray.length] = insertValue;
return (newArray);
}
Its very close to working as intended and hoping some can see the issue im missing
Change:
nums = IncreaseArrayInt(nums, nums[(i - 1)] * 2);
to:
nums = IncreaseArrayInt(nums, nums[(i)] * 2);
The problem is that the first two passes in the for loop both make insertValue 1 * 2. you should get rid of the if else statement and just use nums = IncreaseArrayInt(nums, nums[(i)] * 2); for all of the possible values of i.
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 find the sum of product of distinct pairs in lowest Big O.
List = [3 , 2, 1 , 7, 9]
So the distinct pairs would be - (3,2) , (3,1) (3, 7), (3, 9) , (2, 1) , (2, 7), (2, 9) , (1, 7) , (1, 9) , (7, 9).
Note that - (2,3) is same as (3,2).
What I am doing:
List = [3 , 2, 1 , 7, 9]
int result = 0;
for (int inner = 0; inner < list.size()-1; inner ++){
for(int outer = inner+1; outer < list.size(); outer++){
result+= list[inner] * list[outer];
}
}
It will run in O(n^2).
I wanted to know if there is any, better solution to this which would run in time lower time than O(n^2).
Thanks.
EDIT - sum of distinct pairs -> sum of products of distinct pairs
You have the Efficient O(n) solution here:
static int findProductSum(int A[], int n)
{
// calculating array sum (a1 + a2 ... + an)
int array_sum = 0;
for (int i = 0; i < n; i++)
array_sum = array_sum + A[i];
// calcualting square of array sum
// (a1 + a2 + ... + an)^2
int array_sum_square = array_sum * array_sum;
// calcualting a1^2 + a2^2 + ... + an^2
int individual_square_sum = 0;
for (int i = 0; i < n; i++)
individual_square_sum += A[i] * A[i];
// required sum is (array_sum_square -
// individual_square_sum) / 2
return (array_sum_square - individual_square_sum) / 2;
}
// Driver code
public static void main(String[] args)
{
int A[] = {1, 3, 4};
int n = A.length;
System.out.println("sum of product of all pairs of array "
+"elements : " + findProductSum(A, n));
}
}
I think the identity
(x1+x2+...+xn)^2 =
x1^2+x2^2+...+xn^2
+2(x1x2+...+x1xn+x2x3+...+x2xn+...)
is your friend here.