Whats the most efficient way of doing this? - java

I've got an array array of size N. For every 3 indexes in it I want to take them out and declare and assign those values to another array of size 3. I then want to go back to that array and take the next 3 and put it in a different array of size 3. I'll iterate like this for 3 different arrays of size 3 a1,a2,a3 once this is done I want to empty a1,a2,a3 and re add the NEXT 3 values to the 3 arrays of size 3 repeating this on till we reach array.length
What would be the best / most efficient way of doing this?

As a general strategy I would not worry about efficiency at first.
Code it as explicitly as possible, and then write a load of unit tests confirming it works. The iteratively improve performance.
Its easier to make correct code fast than it is to make fast code correct.

for (int i=0; i<=N-9; i+=9) {
System.arrayCopy(arrayN, i, a1, 0, 3);
System.arrayCopy(arrayN, i+3, a2, 0, 3);
System.arrayCopy(arrayN, i+6, a3, 0, 3);
// presumably do other stuff here
}
That's a pretty brittle but fast way of doing it. Each time the previous values are overwritten, so no need to clear. If you do need to have arrayN clear, you can just Arrays.fill(arrayN, null) after the loop.
EDIT: For the less brittle answer, I'm going to assume you'd be inflating m x n arrays. Instead of hard coding a1, a2, ... am, make a 2D array a[m][n].
for (i=0; i<=N-m*n; i+=m*n) {
for (int j=0; j<m; j++) System.arrayCopy(arrayN, i+n*j, a[j], 0, n);
// presumably do other stuff here
}
and, as Adrian suggests in the comments, declare i outside the loop and use its value relative to N to deal with leftovers as appropriate.

Its very easy, you can do it in the following way....
It is code snippet below....
byte[] YourBigArray = new byte[SomeValue];
int temp = 0;
while(temp < YourBigArray.size - 1 )
{
System.arrayCopy(YourBigArray, temp, smallarray, 0, 3);
temp+=3;
}
Try this code and also see the documentation of arrayCopy function....
Enjoy.....

for(int i = 0; i < ##; i++){if(i%3==0){startNewArray}}

Related

Method to copy primes from one array to another in Java

I'm rather new to Java, and I'm trying to figure out a way to copy all primes inside of an array and copy those to another array.
To do so, I've implemented a separate isPrime() method to check whether the element is a prime, and another method that counts the number of primes in that array countPrimes(), such that I can determine the new array's size.
Here is where I'm kind of stuck:
public static int[] primesIn(int[] arr) {
int primeHolder = countPrimes(arr);
int[] copyArr = new int[primeHolder];
for (int i = 0; i < arr.length; i++) {
if (isPrime(arr[i]) == true) {
copyArr[>Needs to start from 0<] = arr[i];
}
}
return copyArr;
}
int[] arrayMan = {3,5,10,15,13};
At copyArr the position should be 0, followed by +1 everytime it finds a prime. If I were to give it i position, as in copyArr[i] = arr[i], then say the prime is at position 5, it would try to save the prime onto position 5of copyArr, which doesn't exist if there are only three primes in the original array, which would've given copyArr a length of only three.
Something tells me a different for loop, or maybe even an additional one would help, but I can't see how I should implement it. Help is greatly appreciated!
Have a second index variable int primeCount, and increment it whenever you find a prime. No need for a 2nd loop.
In modern days of abundant memory, things are usually not done like this. If you don't have some extra hard requirements, you could just use a resizable ArrayList<Integer>, and add() stuff in there. (and convert it back to int[] at the end if needed). This is also better in this case, because typically your countPrimes call will run much slower than ArrayList reallocations.
Read your words carefully:
At copyArr the position should be 0, followed by +1 everytime it
finds a prime.
That means that index in a new array does not depend on its position in the old array. Create a counter. And each time you place a prime number into a new array, increment it by 1. Thus you can always know where to put a new number.

Is there any way to shorten a for-each loop in java?

I want to iterate just the half of an array in java. Is there any elegant way to shorten this up, eg with a for-each loop?
int[] array = {0,1,2,3,4,5};
for (int i = 0; i<array.length/2; i++)
{
System.out.println(array[i]);
}
If you converted the array into a list using the asList method of the Arrays class in Java, then you can use the forEach method in the List class in Java to print out each element of the list in one single line,
Arrays.asList(array).forEach(System.out::println);
To print only half the array, I'd suggest copying half the array into a new array using the copyOfRange method,
Integer[] newArray = Arrays.copyOfRange(array, 0, array.length/2);
Arrays.asList(newArray).forEach(System.out::println);
EDIT: Like Marko Topolnik pointed out, we're actually starting out with an array of primitive types instead of object types, so in order to use the asList method we're going to have to convert the array into an array of objects (from int to Integer using Integer[] integerArray = ArrayUtils.toObject(array);). However this just seems tedious/inefficient and OP asked for a shorter way so my suggestion would be to use Marko's method,
Arrays.stream(array).limit(array.length/2).forEach(System.ou‌​t::println);
EDIT 2: Like Amber Beriwal pointed out, it should be noted that although the one-line solution above looks pretty due to its conciseness, it is still very inefficient/slow compared to the OP's original method. Therefore, I would like to reiterate Amber's comments that the OP and others should just stick with the original for-loop.
for (int i = 0; i < array.length/2; i++)
{
System.out.println(array[i]);
}
How about:
IntStream.range(0, array.length / 2).map(i -> array[i]).forEach(System.out::println);
One line, and no array copies.
Broken down:
IntStream.range(0, array.length / 2) //get the range of numbers 0 - (array length)/2
.map(i -> array[i]) //map from index to value
.forEach(System.out::println); //print result
The answer you have posted is good. Although, I couldn't find a better way to make it compact keeping the performance same, but performance can be improved. Remember following practices while coding:
Algorithm's memory requirement should be optimum
Algorithm's time i.e. performance should be optimum
Algorithm's complexity should not be too much. For significant gains in 1 & 2, this can be skipped.
Considering 1 & 2, lines of code comes at least priority.
Solution 1: This solution will be 4-5 times slower than your approach, plus Stream will take extra space.
Arrays.stream(array).limit(array.length/2).forEach(System.ou‌​t::println);
Solution 2: This solution is faster than the above code and your code (based on my testing), but Stream will take extra space. Also, it is not compact.
Arrays.stream(array).limit(array.length / 2).forEach(new IntConsumer() {
#Override
public void accept(int value) {
System.out.println(value);
}
});
Solution 3: As suggested by you.
int[] array = new int[] { 0, 1, 2, 3, 4, 5 };
int limit = array.length / 2;
for (int i = 0; i < limit; i++) {
System.out.println(array[i]);
}
Recommendation: Don't go over to reduce the LOC at the stake of losing performance and memory. It is better to keep up with the solution that gives you best performance..

What is the fastest way to copy a 2D int array in Java?

I want to copy an array in less than time proportional to N^2. I'm just using a double for loop right now...
int[][] copy = new int[N][N];
for(int i = 0; i < N; i++){
for(int j = 0; j < N; j++){
copy[i][j] = original[i][j];
}
}
Is there a faster way?
int[][] copy = new int[N][N];
for(int i = 0; i < N; i++){
System.arrayCopy(original[i], 0, copy[i], 0, N);
}
http://docs.oracle.com/javase/7/docs/api/java/lang/System.html#arraycopy(java.lang.Object,%20int,%20java.lang.Object,%20int,%20int)
Java is JIT compiled, and the native code compiler can do all sorts of clever things to make simple loops go fast. So it is not obvious that a implementation of arraycopy makes a significant difference.
So the answer provided by #Brett Okken doesn't have to be faster than yours. But to be "sure" you can use his way. It's the "fastest".
System.arrayCopy(original[i], 0, copy[i], 0, N);
I know I'm late to the party, but maybe this is useful to most people:
IF YOU'RE JUST STORING THE DATA ON A NEW ARRAY BECAUSE THE ARRAY YOU'RE USING IS FULL, which means that the steps are:
1 -alloc a new and bigger array;
2 -copy the values from the older array to the new one;
3 -"point" the variable to the new array.
I've seen this algorithm:
int[][] newArray = new int[oldArray.length + 1][];
for (int n = oldArray.length; n-- != 0; newArray[n] = oldArray[n]) {}
oldArray = newArray;
The idea here is not to copy the values but to 'point' to them, this is specially usefull when the bigger structure is an 3d array. It seems that this algorithm is the fastest available.
This is not useful if you don't want to change the initial array, were, as it is obvious, the option is to send a copy of the original one.
It must be mentioned that I saw this code, or something close in an API named "fastUtil". It is available here
Please feel free to correct me if I said any nonsense.

Transpose matrix stored in a 1-dimensional array without using extra memory [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
In-place transposition of a matrix
Recently attended an Technical Written Interview. Came through the following question.
I have an array as say
testArray = {a1,a2,a3,...an,b1,b2,b3,....bn,c1,c2,c3,.....,cn}
I need to sort this array as `
testArray = {a1,b1,c1,a2,b2,c2,a3,b3,c3,.....,an,bn,cn}
Constraint is I should not use extra memory, should not use any inbuilt function.
Should write complete code, it can be in any language and can also use any data structure.
eg:
Input: {1,2,3,4,5,6,7,8,9}, n = 3
Output: {1,4,7,2,5,8,3,6,9}
I could not get any solution within the constraint, can anyone provide solution or suggestion?
This is just a matrix transpose operation. And there is even a problem and solution for in-place matrix transposition on Wikipedia.
No extra space is impossible, since you need to at least go through the array. O(1) additional memory is possible, with heavy penalty on the time complexity.
The solution is built on follow-the-cycle algorithm in the Wikipedia page: for each cell, we will find the cell with the smallest index in the cycle. If the cell with the smallest index is greater than or equal (>=) to the index of the current cell, we will perform chain swapping. Otherwise, we ignore the cell, since it has been swapped correctly. The (loosely analyzed) upper bound on time complexity can go as high as O((MN)2) (we go through M * N cells, and the cycle can only be as long as the total number of cells).
Impossibility
It is impossible to implement this algorithm without extra use of memory and an arbitrary length because you need a an iterator to traverse the list and that takes up space.
Finding the right indices to swap
For fixed lengths of the array and fixed n you can use a matrix transpose algorithm.
and in order to swap the elements y
The algorithm you are looking for is a matrix transpose algorithm.
so you have to swap every element exactly once iterating through it.
http://en.wikipedia.org/wiki/Transpose
basically you have to swap the m -th element in the n - th component with the n - th element in the m -th component. This can be done by a double loop.
m = length(array)/n;
for (i = 0; i < m; i++)
for (j = 0; j < n; j++)
{
index_1 = i * m + j;
index_2 = j * m + i
swap(index_1, index_2);
}
Note: For fixed m and n this loop can be completely unrolled and therefore m, i, j can be replaced by a constant.
Swaping without Memory consumption
In order to swap every element without using extra space you can use the XOR swap algorithm as pointed out in the comments:
X := X XOR Y
Y := Y XOR X
X := X XOR Y
The simplest way to swap two numbers (a and b) without using a temporary variable is like this:
b = b + a;
a = b - a;
b = b - a;
If you write that in a function, then you're part of the way there. How you keep track of which variable to swap within the arrays without using a temporary variable eludes me right now.
Bear in mind voters: he doesn't actually need to sort the array, just swap the right values.
Edit: this will work with large values in Java (and in C/C++ unless you turn on some very aggressive compiler optimisations - the behaviour is undefined but defaults to sane). The values will just wrap around.
Second edit - some (rather untested) code to flip the array around, with I think 4 integers over the memory limit. It's while technically massively unthreadsafe, but it would be parallelisable just because you only access each array location once at most:
static int[] a = {1,2,3,4,
5,6,7,8,
9,10,11,12,
13,14,15,16};
static int n = 4;
public static void main(String[] args)
{
for(int i = 0; i < a.length/n; i++) // 1 integer
for(int j = 0; j < n; j++) // 1 integer
if(j > i)
swap(i*n+j, j*n+i);
}
static void swap(int aPos, int bPos) // 2 integers
{
if(a[aPos] != a[bPos])
{
a[bPos] = a[aPos] + a[bPos];
a[aPos] = a[bPos] - a[aPos];
a[bPos] = a[bPos] - a[aPos];
}
}
Apologies if this misunderstands the question; I read it carefully and couldn't work out what was needed other than this.
Take a look at Quicksort algorithm
For more information about available algorithms, go to Sorting algorithm page.

Solving Codility Algorithm

I tried the sample demo at Codility website, and posted my solution but I've a simple mistake but couldn't determine it.
The problem is described here (The problem is only described please don't care about the analysis there as that wasn't not my solution)
http://codility.com/cert/view/certHNPV9B-7M4GAQR985B54VYF/details
my solution is here:
public static int min_router_peripherality ( int[] T ) {
// write your code here
int sum=0;
for(int i=0;i<T.length;i++) sum+= T[i];
int min = sum;
int index = 0;
int array [] = new int [T.length];
for(int i=0;i<T.length;i++) {
min = sum -T[i];
array[i] = min;
}
int x = array[0];
for (int i=0; i<array.length;i++)
{
if (array[i]<x)
{
x = array[i];
index = i;
}
}
return index;
}
What I see as mistakes are the following:
for(int i=0;i<T.length;i++)
sum+= T[i];
Here you treat T[i] like some weight. But Node-Ids are no weights. Summing up node ids is useless.
Then: The text says: "if T[P] = Q and P ≠ Q, ...". I don't see anything which takes this into account.
Then: Not understanding the algorithm I tried a simple "line" like this:
int[] T = {1, 2, 3, 4, 5, 6, 7, 8, 9, 9};
The result is 8. But in a line the result should be somewhere in the middle.
Therefore I doubt that the linked page shows the results of the code you have posted.
When looking at the results I would say that your program is correct, but too slow to successfully complete all test cases. So you need to come up with better algorithm.
EDIT: As Ivan Benko Ivan Benko noted, your solution is O(N), so i looked at your code and I came up with a following input:
{ 4, 9, 4, 9, 4, 4, 8, 9, 0, 0 }
Although it is not the example input, it does describe the same network as in the task description. So the output should be same, but your solution gives a different answer.
All I did was look at your code, and the first thing I noticed is that it doesn't look like you need that array array at all, or that third for loop. The second for loop can just keep track of the lowest min value it generates as it goes, along with the index associated with that lowest min value, rather than storing all the values and making a second run like you're doing now.
Edit:
Like everyone else, I assumed that your link was to your own results. I'm not going to post an answer, because I think you're supposed to come up with that yourself. However, it looks to me like you got confused where they said "find the sum of distances to all other nodes", and that might be why you're starting off summing up the entire array. The array they're passing into your function isn't a set of distances by any means. It's a list of existing connections. If the first element (the one at the 0 index) in the array is a 5, then that means Router 0 has a connection to Router 5. So it looks to me like you're approaching it all wrong.
Two adjacent node has a one edge and its weight is 1.

Categories