So, for example i have an array: int[] {1,2,3,4,5}. I need to print the product of even positions, 0 position will be considered even, so it will be: 1 * 3 * 5 = 15.
When I am summing an array, I am doing something like this:
int sum = 0;
for (int i = 0; i < arr.length; sum += arr[i++])
and I am receiving the answer correct.
Now, I thought of using the same method for getting the product:
int produs = 1;
for (int i = 0; i < arr.length; produs *= arr[i = i + 2])
Here I always get an error. I don't know why, but if I am doing:
int produs = 1;
for (int i = 0; i < arr.length; i++) {
if ( (i & 1) == 0) {
produs *= arr[i];
}
}
or
int produs = 1;
for (int i = 0; i < arr.length; i = i + 2) {
produs *= arr[i];
}
I am also getting correct answer.
so, my question is why my method with inline for does not work?
int produs = 1;
for (int i = 0; i < arr.length; produs *= arr[i = i + 2])
this one.
If you perform a suffix increment operation, the compiler puts the old value on the stack, e.g.
int[] arr = new int[] { 0, 10, 20, 30 };
int i = 0;
int x = arr[i++]; // x will be 0, i is incremented to 1
On the other hand, if you would use a prefix increment operation, the compiler puts the new value on the stack, e.g.
int[] arr = new int[] { 0, 10, 20, 30 };
int i = 0;
int x = arr[++i]; // x will be 10, i is incremented to 1
Lastly, a variable assignment operation puts the resulting value on the stack, e.g.
int[] arr = new int[] { 0, 10, 20, 30 };
int i = 0;
int x = arr[i = i + 3]; // x will be 30, i is increased by 3
Therefore, if you use arr[i = i + 2] as post-block statement, you actually access the following array elements: 2, 4, 6, yielding an ArrayIndexOutOfBoundsException.
I strongly recommended (also for the sake of readability) that you restructure your algorithm to use the for-block to do the actual calculation and to use the post-block statement to increase the variable i:
for (int i = 0; i < arr.length; i+=2) {
// TODO Calculation
}
You run into an ArrayIndexOutOfBoundsException, because you try to access an element beyond the array boundary. That is because the condition i < arr.length will not be checked when you do produs *= arr[i = i + 2] in the last section of the for-loop.
You can just split up your code inside the increment section, in fact you can chain as many statements in there as you wish, you just have to separate them with a comma ,:
int produs = 1;
for (int i = 0; i < arr.length; produs *= arr[i], i += 2);
The reason you cannot implement a for-loop like this inline is that in the incremental part produs *= arr[i = i + 2] you will have i reaching an index out of the bound of your array because it jumps through 2 steps. Basically in its final iteration, i will reach value of 6 which is out of the indices of your array (the final index of your array is 4) and the part produs *= arr[i = i + 2] will produce an error.
In this case, it is better to use the way that worked for you:
int produs = 1;
for (int i = 0; i < arr.length; i = i + 2) {
produs *= arr[i];
}
You always instantiate your produs with 0.
If you multiply something with zero, than it will be zero.
You have to instantiate it with 1, then should your last example work
int produsOfEven(int[] array) {
int produs = 1;
// step by 2
for (int i = 0; i < array.length; i += 2) {
produs *= array[i];
}
return produs;
}
Edit
To your question, why the last example wont work: As already pointed out in the comments, your condition will be checked to "late".
Let us imagine you have the code for (int i = 0; i < arr.length; produs *= arr[i = i + 2]) and array of length 3. Then this steps will be computed:
Init i with 0.
Check condition i < arr.length, it is true.
Exec body - no body, nothing will happen.
Increase i by running produs *= arr[i = i + 2], i is now 2, produs is changed by array-index 2.
Check condition i < arr.length, it is true.
Exec body - no body, nothing will happen.
Increase i by running produs *= arr[i = i + 2], i is now 4, produs is changed by array-index 4. ArrayIndexOutOfBoundsException was thrown.
You had better use stream
java.util.concurrent.atomic.AtomicInteger index = new java.util.concurrent.atomic.AtomicInteger();
int produs = java.util.Arrays.stream(new int[] {1,2,3,4,5})
.filter(i -> index.getAndIncrement() % 2 == 0).reduce(1, (a, b) -> a * b);
Related
The only difference is the nested for loop in the first one is assigned the value of i+1 instead of just +1(second one). Why is the first one considered better than the second one?
int[] nums = { 3, 2, 4 };
int target = 6;
for (int i = 0; i < nums.length; i++) {
for (int j = i + 1; j < nums.length; j++) {
int answer = nums[i]+nums[j];
System.out.println(answer);//answer should be value of target
}
}
int[] nums = { 3, 2, 4 };
int target = 6;
for (int i = 0; i < nums.length; i++ ) {
for (int j = 1; j < nums.length; j++) {
int answer = nums[i]+nums[j];
System.out.println(answer);//answer should be value of target
}
}
These two codes are don't seem accomplishing the same to me. however as you said in the comment I'm trying to figure out.
In terms of run time, in the first code, the nested for loop runs nums.length - (i+1) times. Here the best case scenario for nested for loop runs 0 times and for the worst case scenario runsnums.length - 1 times.
int[] nums = { 3, 2, 4 };
int target = 6;
for (int i = 0; i < nums.length; i++) {
for (int j = i + 1; j < nums.length; j++) {
int answer = nums[i]+nums[j];
System.out.println(answer);//answer should be value of target
}
}
On the other hand in the 2nd code the nested for loop runs nums.length times. Here the best case and worst case scenario for nested for loop are the same which is runs nums.length times.
int[] nums = { 3, 2, 4 };
int target = 6;
for (int i = 0; i < nums.length; i++ ) {
for (int j = 1; j < nums.length; j++) {
int answer = nums[i]+nums[j];
System.out.println(answer);//answer should be value of target
}
}
Therefore, Based on best and worst case scenario we can say that the first code is more efficient.
The number of iterations in the first code sample is a sum of sequence: n - 1, n - 2, ... 1 that is it's a sum of arithmetic progression of n - 1 elements:
S = (1 + n - 1) * (n - 1) / 2 = n * (n - 1) / 2 = (n^2 - n) / 2
The number of iterations in the second code sample is n * (n - 1) = n^2 - n, that is, it has twice as much iterations as the first one.
However, when estimating complexity (big-O), the constant values such as 2 and expressions of lower order are omitted, thus in both cases O(N) = N^2.
Why is is giving me ArrayIndexOutOfBoundsException in second For loop?
public class Ass1Ques2 {
void rotate() {
int[] a = {3, 8, 9, 7, 6};
int r = 2;
int[] t1 = new int[(a.length - r) + 1];
int[] t2 = new int[r + 1];
for (int y = 0; y <= r; y++) {
t2[y] = a[y];
}
// This loop is giving error
for (int i = 0; i <= a.length - r; i++) {
t1[i] = a[i + r];
}
for (int f = 0; f <= t1.length; f++) {
System.out.println(t1[f] + " ");
}
for (int n = 0; n <= t2.length; n++) {
System.out.println(t2[n] + " ");
}
}
public static void main(String[] args) {
Ass1Ques2 r = new Ass1Ques2();
r.rotate();
}
}
I don't know how to fix this error,i think i have given the right length to t2.
I want to internally rotate the array clockwise according to r.
You access a[i+r], consider the last iteration of the loop. i = a.length-r so i+r = a.length-r + r = a.length which is out of bounds.
If you want to rotate the array, I recommend using the modulo (%) operator to compute the new position of an index. So in practice, add the rotation to all indices and modulo over the length of the array to get the new positions.
At the last iteration of the loop, you will be accessing a.length, which returns the entire length of the array starting at 1; which causes an IndexOutOfBounds exception since indices start at 0. In order to fix this, just do:
for (int i = 0; i < a.length - r; i++) {
t1[i] = a[i + r];
}
This will prevent the for loop from iterating to the very last spot of the array with an equal sign, which would've caused an IndexOutOfBounds exception.
So I have a problem, this method is supposed to sort an array of integers by using counting sort. The problem is that the resulting array has one extra element, zero. If the original array had a zero element (or several) it's fine, but if the original array didn't have any zero elements the result starts from zero anyway.
e.g. int input[] = { 2, 1, 4 }; result -> Sorted Array : [0, 1, 2, 4]
Why would this be happening?
public class CauntingSort {
public static int max(int[] A)
{
int maxValue = A[0];
for(int i = 0; i < A.length; i++)
if(maxValue < A[i])
maxValue = A[i];
return maxValue;
}
public static int[] createCountersArray(int[] A)
{
int maxValue = max(A) + 1;
int[] Result = new int[A.length + 1];
int[] Count = new int[maxValue];
for (int i = 0; i < A.length; i++) {
int x = Count[A[i]];
x++;
Count[A[i]] = x;
}
for (int i = 1; i < Count.length; i++) {
Count[i] = Count[i] + Count[i - 1];
}
for (int i = A.length -1; i >= 0; i--) {
int x = Count[A[i]];
Result[x] = A[i];
x--;
Count[A[i]] = x;
}
return Result;
}
}
You are using int[] Result = new int[A.length + 1]; which makes the array one position larger. But if you avoid it, you'll have an IndexOutOfBounds exception because you're supposed to do x-- before using x to access the array, so your code should change to something like:
public static int[] createCountersArray(int[] A)
{
int maxValue = max(A) + 1;
int[] Result = new int[A.length];
int[] Count = new int[maxValue];
for (int i = 0; i < A.length; i++) {
int x = Count[A[i]];
x++;
Count[A[i]] = x;
}
for (int i = 1; i < Count.length; i++) {
Count[i] = Count[i] + Count[i - 1];
}
for (int i = A.length -1; i >= 0; i--) {
int x = Count[A[i]];
x--;
Result[x] = A[i];
Count[A[i]] = x;
}
return Result;
}
Here you go: tio.run
int maxValue = max(A) + 1;
Returns the highest value of A + 1, so your new array with new int[maxValue] will be of size = 5;
The array Result is of the lenght A.lenght + 1, that is 4 + 1 = 5;
The first 0 is a predefinied value of int if it is a ? extends Object it would be null.
The leading 0 in your result is the initial value assigned to that element when the array is instantiated. That initial value is never modified because your loop that fills the result writes only to elements that correspond to a positive number of cumulative counts.
For example, consider sorting a one-element array. The Count for that element will be 1, so you will write the element's value at index 1 of the result array, leaving index 0 untouched.
Basically, then, this is an off-by-one error. You could fix it by changing
Result[x] = A[i];
to
Result[x - 1] = A[i];
HOWEVER, part of the problem here is that the buggy part of the routine is difficult to follow or analyze (for a human). No doubt it is comparatively efficient; nevertheless, fast, broken code is not better than slow, working code. Here's an alternative that is easier to reason about:
int nextResult = 0;
for (int i = 0; i < Count.length; i++) {
for (int j = 0; j < Count[i]; j++) {
Result[nextResult] = i;
nextResult++;
}
}
Of course, you'll also want to avoid declaring the Result array larger than array A.
`I have following array {9, 0, 2, -5, 7} and from this array i need to find the the square pairs <2, 7> and <7, 9> where first element must be less than second.
And <-5, 9> and <0, 9> are not square pairs, even though they sum to perfect squares,
because both members of a square pair have to be greater than 0.
bool ans;
int[] number = new int[]{9,0,2,-5,7};
for (int j = 0; j < number.Length; j++)
{
if (number[j]<number[j+1])
ans = IsPerfectSquares(number[j]+number[j+1]);
if(ans)
count++;
}
}
public static bool IsPerfectSquares(int input)
{ long SquareRoot = (long)Math.Sqrt(input);
return ((SquareRoot * SquareRoot) == input);
} `
C# Linq:
int[] array = {9, 0, 2, -5, 7};
int len = array.Length;
var pairs =
from i in Enumerable.Range(0, len-1)
where array[i] > 0
from j in Enumerable.Range(i+1, len-i-1)
where array[j] > 0
let sqrt = (int)Math.Sqrt(array[i] + array[j])
where array[i] + array[j] == sqrt * sqrt
select new {
A = Math.Min(array[i], array[j]),
B = Math.Max(array[i], array[j])
};
//or: select new int[] { ... };
Results:
{ A = 7, B = 9 }
{ A = 2, B = 7 }
Java: (also works in C# with slightly different syntax)
int[] array = { 9, 0, 2, -5, 7 };
List<int[]> pairs = new ArrayList<int[]>();
for (int i = 0; i < array.length - 1; ++i) {
if (array[i] <= 0) continue;
for (int j = i + 1; j < array.length; ++j) {
if (array[j] <= 0) continue;
int sqrt = (int)Math.sqrt(array[i] + array[j]);
if (array[i] + array[j] == sqrt * sqrt)
pairs.add(new int[] { array[i], array[j] });
}
}
I will let you write the code.
The algorithm is roughly this:
Iterate over the array. Remove all elements whose value is less than or equal to zero.
Create all possible pairs by using nested loop (two loops). For each pair, take the sum. Let say the sum is S. Take the square root of S. Let say the square root of R. Note that S is an integer (so, it may not exactly the square root of S). Check whether S is a perfect square by checking whether R*R = S.
This question already has answers here:
How do I reverse an int array in Java?
(47 answers)
Closed 8 years ago.
I have an array of n elements and these methods:
last() return the last int of the array
first() return the first int of the array
size() return the length of the array
replaceFirst(num) that add the int at the beginning and returns its position
remove(pos) that delete the int at the pos
I have to create a new method that gives me the array at the reverse order.
I need to use those method. Now, I can't understand why my method doesn't work.
so
for (int i = 1; i
The remove will remove the element at the position i, and return the number that it is in that position, and then with replaceFirst will move the number (returned by remove) of the array.
I made a try with a simple array with {2,4,6,8,10,12}
My output is: 12 12 12 8 6 10
so if I have an array with 1,2,3,4,5
for i = 1; I'm gonna have : 2,1,3,4,5
for i=2 >3,2,1,4,5
etc
But it doesn't seem to work.
Well, I'll give you hints. There are multiple ways to reverse an array.
The simplest and the most obvious way would be to loop through the array in the reverse order and assign the values to another array in the right order.
The previous method would require you to use an extra array, and if you do not want to do that, you could have two indices in a for loop, one from the first and next from the last and start swapping the values at those indices.
Your method also works, but since you insert the values into the front of the array, its going to be a bit more complex.
There is also a Collections.reverse method in the Collections class to reverse arrays of objects. You can read about it in this post
Here is an code that was put up on Stackoverflow by #unholysampler. You might want to start there: Java array order reversing
public static void reverse(int[] a)
{
int l = a.length;
for (int j = 0; j < l / 2; j++)
{
int temp = a[j]
a[j] = a[l - j - 1];
a[l - j - 1] = temp;
}
}
int[] reverse(int[] a) {
int len = a.length;
int[] result = new int[len];
for (int i = len; i > 0 ; i--)
result[len-i] = a[i-1];
return result;
}
for(int i = array.length; i >= 0; i--){
System.out.printf("%d\n",array[i]);
}
Try this.
If it is a Java array and not a complex type, the easiest and safest way is to use a library, e.g. Apache commons: ArrayUtils.reverse(array);
In Java for a random Array:
public static void reverse(){
int[] a = new int[4];
a[0] = 3;
a[1] = 2;
a[2] = 5;
a[3] = 1;
LinkedList<Integer> b = new LinkedList<Integer>();
for(int i = a.length-1; i >= 0; i--){
b.add(a[i]);
}
for(int i=0; i<b.size(); i++){
a[i] = b.get(i);
System.out.print(a[i] + ",");
}
}
Hope this helps.
Reversing an array is a relatively simple process. Let's start with thinking how you print an array normally.
int[] numbers = {1,2,3,4,5,6};
for(int x = 0; x < numbers.length; x++)
{
System.out.println(numbers[x]);
}
What does this do? Well it increments x while it is less than numbers.length, so what is actually happening is..
First run : X = 0
System.out.println(numbers[x]);
// Which is equivalent to..
System.out.println(numbers[0]);
// Which resolves to..
System.out.println(1);
Second Run : X = 1
System.out.println(numbers[x]);
// Which is equivalent to..
System.out.println(numbers[1]);
// Which resolves to..
System.out.println(2);
What you need to do is start with numbers.length - 1, and go back down to 0. To do this, you need to restructure your for loop, to match the following pseudocode..
for(x := numbers.length to 0) {
print numbers[x]
}
Now you've worked out how to print, it's time to move onto reversing the array. Using your for loop, you can cycle through each value in the array from start to finish. You'll also be needing a new array.
int[] revNumbers = new int[numbers.length];
for(int x = numbers.length - 1 to 0) {
revNumbers[(numbers.length - 1) - x] = numbers[x];
}
int[] noArray = {1,2,3,4,5,6};
int lenght = noArray.length - 1;
for(int x = lenght ; x >= 0; x--)
{
System.out.println(noArray[x]);
}
}
int[] numbers = {1,2,3,4,5};
int[] ReverseNumbers = new int[numbers.Length];
for(int a=0; a<numbers.Length; a++)
{
ReverseNumbers[a] = numbers.Length - a;
}
for(int a=0; a<ReverseNumbers.Length; a++)
Console.Write(" " + ReverseNumbers[a]);
int[] numbers = { 1, 2, 3, 4, 5, 6 };
reverse(numbers, 1); >2,1,3,4,5
reverse(numbers, 2); >3,2,1,4,5
public int[] reverse(int[] numbers, int value) {
int index = 0;
for (int i = 0; i < numbers.length; i++) {
int j = numbers[i];
if (j == value) {
index = i;
break;
}
}
int i = 0;
int[] result = new int[numbers.length];
int forIndex = index + 1;
for (int x = index + 2; x > 0; x--) {
result[i] = numbers[forIndex--];
++i;
}
for (int x = index + 2; x < numbers.length; x++) {
result[i] = numbers[x];
++i;
}
return result;
}