I was wondering if this is the most efficient or even good code practice to add arrays to a single array as far as my knowllage goes its time would be O(n). This is only for practice and I want to do it for int [] not for the code to be changed so it is a List.
static int[] allArrayDirections(int row[], int col [], int diag []) {
int counter = 0;
int allDirectionsInMatrix [] = new int [row.length + col.length + diag.length];
for(int i = 0; i < row.length; i++) {
allDirectionsInMatrix[counter++] = row[i];
}
for(int j = 0; j < col.length; j++) {
allDirectionsInMatrix[counter++] = col[j];
}
for(int i = 0; i < diag.length; i++) {
allDirectionsInMatrix[counter++] = diag[i];
}
return allDirectionsInMatrix;
}
You could compare your linear solution to a sort of unravelled:
Find the longest of the three arrays, take its length as counter boundary
assign the longest array to a new variable first, the other two to second and third – just fiddling with the references so the for looks straightforward
loop once from 0 to the counter boundary
fill your target array in three steps, using the other array's length as offset – unless the smaller arrays are already exhausted, so skip them
This will need some add operation for the offset calculation to write to allDirectionsInMatrix and two greater then checks. Depending on the VM's optimization/ array lengths/ call frequency this might cut it in half.
The single for-loop looks similar to this:
// assuming first.length >= second.length >= third.length;
for(int i=0;i<largestLength;i++) {
allDirectionsInMatrix[i]=first[i];
if (second.length > i)
allDirectionsInMatrix[i+first.length]=second[i];
// I assume when called often enough VM does auto trickery
// with the repeated addition of i and first.length
if (third.length > i)
allDirectionsInMatrix[i+first.length+second.length]=third[i];
}
But this might also break other VM optimizations when treating the arrays independently. So really compare runtime. I'd appreciate to read about your measurements.
Just FYI (and not a reals answer to your question, but maybe interesting for comparison)
One way to concatenate integer arrays (using Streams) would be
int[] a = {1,2,3};
int[] b = {4,5,6,7};
int[] c = IntStream.concat(Arrays.stream(a), Arrays.stream(b)).toArray();
System.out.println(Arrays.toString(c));
(Stream.concat for arrays of other types)
Related
trying to write a method reverseIntArray(int[] array) which should return a reverse copy of an integer array. For example, if array = [1,2,3,4], then the method should return the array [4,3,2,1].
The program compiles without any error messages. What are the errors causing incorrect incorrect behavior of the program at runtime?
public static int[] reverseIntArray(int[] array) {
int[] result = new int[10];
int j = array.length;
for (int i = 1; i < array.length; i++ ) {
result[i] = array[j];
j++;
}
return result;
}
how should the error be corrected?
what exactly is the error?
what effect the error would have?
You need to set j to be array.length -1 instead of array.length and decrement it instead of incrementing it, and start your for loop index at 0 not 1.
There are a couple of issues with your code:
Your result array is being created with a size of 10 rather than the size of the array being passed in. This will cause an issue if you pass in an array with a smaller or larger size than 10. You can resolve this with: int[] result = new int[array.length];
You're initializing i with a value of 1. Java arrays start at index 0, so your loop will skip populating the first element of the array. You instead want: for (int i = 0; i < array.length; i++) {
Because java arrays start at index 0, the last element's index will be 1 less than array's size. You want: int j = array.length - 1;
You want to retrieve array's elements in reverse order, but your code is incrementing j rather than decrementing it. You want j-- where you have j++
To solve array related problem you must know only about its storage in memory and its index.
In your solution you are trying to overwrite values. In your solution you need to make sure that you are saving older value before writing any new value to any index.
NOTE: You must know that how to swap two numbers.
int[] arr={1,2,3,4};
int i=0;
int j=arr.length-1;
while(i<j)
{
//Swapping two numbers
int temp=arr[i];
arr[i]=arr[j];
arr[j]=temp;
i++;
j--;
}
You can also do the same using for loop.
For example, if I have:
int Myarray[][] = new int[][] {{1,2}, {3,4}};
for (int line=0; line < Myarray.length; line++) {
for (int column = 0; column < Myarray[0].length; column++) {
// do something ...
}
}
How could I go through the entire array without the two loops?
Well you could use just a single loop:
for (int i = 0; i < Myarray.length*Myarray.length; i++) {
int row = i / Myarray.length;
int col = i % Myarray.length;
System.out.println(Myarray[row][col]);
}
But this assumes that your 2D array is square, i.e. its width and length are the same everywhere. Another way of saying this is that the 2D array is not jagged.
Demo
Note: As #Thilo mentioned above, this won't make things run faster. If you need to touch every element in your array, then my suggested code and your current double loop basically have the same complexity.
If you don’t need to know the line or column in the “do something” code (not stated in question), you could:
Arrays.stream(Myarray).flatMap(Arrays:stream)
.forEach(n -> /* do something with “n”, the cell value */);
You can iterate without any loops:
void recursive(int[][] array, int r, int c) {
if (r >= array.length) return;
if (c >= array[r].length) {
recursive(array, r+1, 0);
} else {
System.out.println(array[r][c]);
recursive(array, r, c+1);
}
}
Then invoke with recursive(array, 0, 0) to get started.
But there is no practical benefit in doing so. This would perform poorly, because of all the extra effort involved in calling a method vs just incrementing an int. (Plus, depending upon the size of the array, you could end up with a stack overflow).
I have an array of terms (terms meaning an object with a coefficient and a degree, represented as for example 1.0x^6). The array that I have right now contains 3 terms:
[1.0x^6, 4.0x^5, 10.0x^0].
My goal is to create a bigger array with these terms, but ALSO with terms with a 0 coefficient that are not represented in my array. That probably was not too clear, so here is basically what I want my new array to look like:
[1.0x^6, 4.0x^5, 0.0x^4, 0.0x^3, 0.0x^2, 0.0x^1, 10.0x^0].
Currently, I am iterating through my original array, and if the degree equals the new array.length - 1, I am setting newArray[i] = array[i], if that makes sense. For example, for the first term and i = 0, the degree is 6, and so if 6 = newArray.length - 1 (which is 6), then newArray[i] = array[i].
The problem, however is that array is smaller than newArray, so I am getting an out of bounds error. Any ideas on how to fix this? Sorry for the long post, thanks!
EDIT: Here is my actual code. Sorry if the explanation was unclear.
int max = 0;
Term temp;
for(int i=0; i<array.length; i++) {
max = i;
for(int j=i; j< array.length; j++) {
if(array[j].getDegree() > array[max].getDegree()) {
max = j;
}
}
temp = array[i];
array[i] = array[max];
array[max] = temp;
}
Above, the array is sorted in terms of descending degree. I want to now have the new array contain the old terms, but also 0x^i for all the i that are not used in my set of terms.
Term[] newArray = new Term[this.degree()+1];
for (int c = 0; c < newArray.length; c++) {
if (array[c].getDegree()==newArray.length-1-c) {
newArray[c] = array[c];
}
else {
newArray[c] = new Term(0, newArray.length-1-c);
}
}
There are issues in my code above, and I can see that now because in that for loop, array[c] is not defined for any c > 2. Eclipse is telling my that I have an out of bounds error.
Arrays have a fixed size. If you want to create a bigger array, you need to know the size beforehand and define it accordingly. Also, it seems that you are going through both the arrays using the same iteration variable.
I assume you are doing something like this:
for(i=0;i<newArray.length;i++){
newArray[i] = array[i]; //size of newArray is bigger than array
}
Then you will always get an array index out of bounds exception because "array" is smaller than "newArray" and you go out of bounds when i>=array.length.
You need to fix your code logic.
I am trying to create a method (without using arraylist) to return a new array that removes all instances of some integer (call it x). (For example, b=[2,5,3,2,7] b.remove(2) would return [5,3,7]. This code I have been working on (one of several hours worth of different attempts) seems to work when there is one occurence of X, but not many. When there are many, it sizes the new array correctly, but does not copy the data correctly for at/after the second occurence of X.
What I am trying to do is set a counter for each time X occurs, then set a new array that has length (old array length - count variable). Then I need to shift all the data after any occurence of X left. Here's my current code:
public Sequence remove(int n) {
int count = 0;
int a = 0;
for (int z=0; z < this.values.length; z++) {
if (this.values[z] == n)
count++;
}
Sequence newSequence = new Sequence(this.values.length - count);
for (int b=0; b < this.values.length - count; b++) {
if (this.values[a] != n) {
newSequence.values[a] = this.values[a];
a++;
} else {
newSequence.values[a]=this.values[a+1];
}
}
return newSequence;
}
I think the logic for populating the new resized array should be something like this:
walk through the entire original array
if a given value be the one you want removed, do nothing
otherwise add it to the new array and also increment the index in the new array
int pos = 0; // keeps track of position in newSequence.values
for (int i=0; i < this.values.length; i++) {
if (this.values[i] != n) {
newSequence.values[pos] = this.values[i];
pos++;
}
}
To be honest I did not completely get what you trying to do. But I understood the problem and your code. I would follow these steps to solve this problem.
Iterate through the array and count the number of times n (assuming you want to remove n) occurs. This count is stored in count variable.
Create a new array with size values.length-count (here values is the array)
Copy numbers from values array to new array.
This gives a O(n) solution.
The problem I am facing is this one:
I have an array of doubles from which I want to keep the top k greater values.
I have seen some implementations involving Arrays.sort. For example in this example with relative issue it is suggested to use this approach.
Since I am only interested in the first k elements I have also experimented with MinMaxPriorityQueue. I have created a MinMaxPriorityQueue with a maximumSize:
Of course there is again autoboxing.
Builder<Comparable> builder = MinMaxPriorityQueue.maximumSize(maximumSize);
MinMaxPriorityQueue<Double> top2 = builder.create();
The problem is that the order is the ascending one that it's the opposite of the one I want. So I cannot use it this way.
To state the problem's real parameters my arrays is about 50 elements long and I am interested in up to the top k = 5 elements.
So is there any way to bypass this problem using the second approach? Should I stay with the first one even though I don't really need all elements sorted? Do you know if there is any significant difference in speed performance (I will have to use this in a lot of situations so that's where the speed is needed)? Is there any other solution I could use?
As for the performance, I know I can theoretically check it myself but I am a bit out of time and if someone have any solution I am happy to hear it (or read it anyway).
If you only have like 50 elements, as noted in my comment, just sort it and take the last k elements. It's 2 lines only:
public static double[] largests(double[] arr, int k) {
Arrays.sort(arr);
return Arrays.copyOfRange(arr, arr.length - k, arr.length);
}
This modifies (sorts) the original array. If you want your original array unmodified, you only need +1 line:
public static double[] largests2(double[] arr, int k) {
arr = Arrays.copyOf(arr, arr.length);
Arrays.sort(arr);
return Arrays.copyOfRange(arr, arr.length - k, arr.length);
}
You can use System.arraycopy on a sorted array:
double[] getMaxElements(double[] input, int k) {
double[] temp = Arrays.copyOf(input, input.length);
Arrays.sort(temp); // Sort a copy to keep input as it is since Arrays.sort works in-place.
return Arrays.copyOfRange(temp, temp.length - k, temp.length); // Fetch largest elements
}
For 50 elements, it is much faster to sort an array than to mess with generics and comparables.
I will write up an additional "fast" algorithm...
double[] getMaxElements2(double[] input, int k) {
double[] res = new double[k];
for (int i = 0; i < k; i++) res[i] = Double.NEGATIVE_INFINITY; // Make them as small as possible.
for (int j = 0; j < input.length; j++) // Look at every element
if (res[0] < input[j]) { // Keep the current element
res[0] = input[j];
Arrays.sort(res); // Keep the lowest kept element at res[0]
}
return res;
}
This is O(N*k*log(k)) while the first one is O(N*log(N)).