(Java) Check array for increasing elements - java

I'm attempting to create a method that checks an array for increasing elements. True should be returned if all the elements are in increasing order. I get an out-of-bounds exception when I compare arr[i+1]. Any ideas on how I can make it work.
int[] one = {1,2,3,4,5};
public static boolean isIncreasing(int[]arr)
{
boolean z = false;
for(int i=0; i<arr.length;i++)
{
if(arr[i]<arr[i+1])
{
z = true;
}
}
return z;
}

Because in a list with n items there are only n-1 gaps between them.
Change to
for (int i=0; i<arr.length-1; i++)
(Also you might want to check whether starting with false and setting to true is the right way around).

You have two problems:
Your loop is one iteration too long: Because you are checking element i+1, i needs to finished incrementing one iteration earlier than a usual loop.
Your logic is flawed. Your loop will terminate the first time the check is true, so this array will pass: {1, 2, 0} when tested the first iteration tests 1 < 2 which is true, so return true - this is not what we want)
Fixing these two problems:
int[] one = {1,2,3,4,5};
public static boolean isIncreasing(int[] arr) {
for(int i=0 ; i < arr.length - 1; i++) { // finish at length - 1
if (arr[i] > arr[i+1]) {
return false; // found elements that are out of order - return false
}
}
return true; // nothing out of order found - return true
}
This kind of logic - with an early exit with false on problem and a final return of true - is very common and a good pattern to learn.

I suggest you write your method like this
public static boolean isIncreasing(int[]arr)
{
for(int i=1; i<arr.length;i++)
{
if(arr[i-1]>arr[i])
return false;
}
return true;
}
it will help
return the proper result (yours returns true when it should not)
consider out of bounds
avoid unnecessary looping

You get that exception as when (i+1)'s value becomes array.length. For example if you have an array of length 10, the elements indexes will be from 0,1,2...till 9. so either you have to check till i < arr.length - 1 or you can modify your logic accordingly.

You can use Java 8's IntStream.
import java.util.stream.IntStream;
public class Test {
public static boolean isIncreasing(int[] a) {
return IntStream.range(1, a.length).reduce(0, (acc, e) -> acc + (a[e - 1] <= a[e] ? 0 : 1)) == 0;
}
}

Related

Why no out of bounds error on for loop (Java)

I'm doing a problem on codingbat.com and am confused with why this solution to the problem does not give an index out of bounds error. Wouldn't the first for loop search for an index that is beyond the length of the passed array?
Here's the problem:
We'll say that a value is "everywhere" in an array if for every pair of adjacent elements in the array, at least one of the pair is that value. Return true if the given value is everywhere in the array.
Here's my working solution:
public boolean isEverywhere(int[] nums, int val) {
boolean flag1 = true;
boolean flag2 = true;
for (int i = 0; i < nums.length; i += 2) {
if (nums[i] != val) flag1 = false;
}
for (int i = 0; i < nums.length - 1; i += 2) {
if (nums[i + 1] != val) flag2 = false;
}
return flag1 || flag2;
}
Thanks!
No. The test happens after i is incremented. So, once i is not less than the length of the nums array the loop stops. The second loop uses i + 1 at if (nums[i + 1] != val) which is why it needs to test that i is less than the length minus one.
Also you can make the method static (since it uses no instance state).
It wouldn't because while i += 2 is written after i < nums.length, the loop still checks that i is less than the given length(nums.length) before going onto the body of the loop even after 2 has been added on.

Why I am returning the wrong output?

I am not sure why I am returning false for the first test run as shown in the test table attachment. This was one of my assignments last semester and I never figured out how to solve it:/ My assignment was to:
Write the definition of a method , oddsMatchEvens, whose two parameters are arrays of integers of equal size. The size of each array is an even number. The method returns true if and only if the even-indexed elements of the first array equal the odd-indexed elements of the second, in sequence. That is if w is the first array and q the second array , w[0] equals q[1], and w[2] equals q[3], and so on.
Test table
My code was:
public boolean oddsMatchEvens(int[] w, int[] q) {
int count = 0;
for (int i = 0; i < w.length; i++) {
if (w[i] == q[i + 1])
count++;
if (count == (w.length - 1))
return true;
}
return false;
}
if (count == (w.length - 1))
return true;
This is wrong, since you have only w.length/2 indices which you have to compare.
You should just return false, if w[i] != q[i+1].
And you should increase i by 2, not by 1.
There are two problems with the code:
Firstly, it is clearly mentioned the two input arrays are of equal length and you have to compare them even index to odd index. So the corner case occurs when you are checking last item of first array with last+1 item of second array(which doesn't exist as arrays are of equal length.
Secondly, you have to check first array even with second array odd so increment should be i+=2 and not i++.
Correct code with optimization(if one check fails you can come out of loop):
public boolean oddsMatchEvens(int[] w, int[] q) {
for (int i = 0; i < w.length-1; i+=2) {
if (w[i] != q[i + 1])
return false;
else
continue;
}
return true;
}
public boolean oddsMatchEvens (int []w, int []q) {
for (int j = 0; j < w.length-1; j+=2) {
if (w [j] != q [j+1])
return false;
continue;
}
return true;
}

How would you check if all integers in a 2d array are unique?

I am looking to verify if all of the integers in a 2d array are unique, return true if they are unique otherwise false.
The below code is what I have for a simple array. But I am not sure how to go about modifying it.
public boolean verifyUniqueIntegers(int array []){
boolean result = true;
for (int i = 0; i < array.length; i++) {
if(array[i] <= 0 || array[i] > n*n){
result = false;
}
for (int j = 0; j < i; j++)
if (array[i] == array[j]) {
result = false;
}
}
return result;
}
The best way to approach this problem is to use a mathematical construct called a set. The key property of a set for your purposes is that they can not contain duplicates by definition. Java provides a data structure allowing us to create sets found in java.util.Set. This is the generic interface that specifies how sets should behave. However, interfaces provide only specification, not implementation, so you'll have to use Set in conjunction with another class java.util.HashSet, which implements Set. You seem like a novice programmer, so I wrote a test program to show you how this works.
import java.util.*;
public class SetTest {
public static void main(String[] args) {
int[] set = {1,2,3,4,5,6,7};
int[] nonSet = {1,2,3,4,5,4};
System.out.println(verifyUniqueIntegers(set));
System.out.println(verifyUniqueIntegers(nonSet));
}
public static boolean verifyUniqueIntegers(int[] array) {
Set<Integer> set = new HashSet<Integer>();
for(int i : array) // This is a construction called a for-each loop
if(!set.add(i)) // This is an example of what's called autoboxing
return false;
return true;
}
}
Here I've used a static method for convenience, but you can of course change this into an instance method for your purposes once you give it a try.
First, I create a for-each loop to iterate over all the elements in the array that's passed into verifyUniqueIntegers(). For each loops use what are called iterators to create a reference to each element, one at a time, and make it available in the body of the loop. When the end of the body is reached, the for-each loop automatically resets i to the next element in the array, as long as there are elements left in the arry. You can ready more about for-each loops in the Oracle Java Tutorials.
Then, the method calls set.add(i). This attempts to add i to the set that we previously defined. This is an example of what's called autoboxing. Since the Set interface is generic, it can contain elements of any object type. Since int is a primitive, we must use the wrapper class Integer to specify the elements in our set. When we call set.add(i) you don't have to convert the int into an Integerbecause the java compiler does it for you.
This method returns true if i is not a duplicate, then adds it to the Set. It returns false if i is a duplicate and does nothing. Thus, we can take advantage of the method check the uniqueness of each element in your array. The method returns false as soon as a duplicate is found, and otherwise returns true. Hope this helps, good luck!
Your algorithm is slow. To make it faster, you should use something like HashMap.
Create empty HashMap<Integer>.
Iterate on all 2d-array elements (for-for loop).
For every element check if your HashMap contains it.
If yes then return false, it means that not all elements in your array are unique.
If no, add element to HashMap.
After for-for loop return true.
As a beginning programmer, choose basic solutions without the sophistication of more complex parts of the library that do in truth offer more power. The main thing for you here is to learn how to use 2D arrays.
You can do it very simply because of the hidden specification that you did not mention but is in the code. None of the numbers can be greater than N * N.
Start with pseudo-code. The basic algorithm is to have a checking array of length N * N. Put a marker in each element as you find the number in the source array, using the number as the index into the checking array. If there is already an element there, then the number is not unique. The code becomes something like this:
final int N = 10; // Your choice of N, or perhaps input it.
int [][] needsChecking = new int [N] [N]; // fill it up.
public boolean arrayIsGood (int [][] src) {
final int N2 = N * N;
boolean [] checker = new boolean [N2];
for (int i = 0; i < N2; i++) { // Initialize Checker
checker [i] = false;
}
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
int value = src [i][j];
if ((value <= 0) || (value > N2))
return false;
if (checker [value - 1]) // already found
return false;
checker [value - 1] = true;
} // for j
} // for i
return true; // if we get here every element has passed.
} // arrayIsGood (int [][])
Some of the other answers are more elegant or more extensible or handle space usage better or may find the result faster, etc. But master the basics first.
public boolean verifyUniqueIntegers(int array []){
Set<Integer> set = new HashSet<>(array.length);
for (int i : array)
{
if (set.contains(i))
return false;
set.add(i);
}
return true;
}
or maybe:
public boolean verifyUniqueIntegers(Integer array []){
return new HashSet<>(Arrays.asList(array)).size() == array.length;
}

Boolean with loops to check an array

Write Java code for a loop that sets boolean variable isOrdered to true if the elements of a given array of ints called are in non-decreasing order, otherwise it sets isOrdered to false.
int i[] = { 1, 2, 3, 4, 5 };
int b = 0;
boolean isOrdered = false;
while (b < i.length) {
if (i[0] <= i[b]) {
isOrdered = true;
}
b++;
}
out.println(isOrdered);
Am I doing this correctly?
Let's see what is wrong.
if (i[0] <= i[b])
This is the main area which troubles me with your code. How are you checking if the next value you is lower/higher then i[b] you are only comparing values at index zero to index b!
Essentially your code would look like this in a loop.
/w int i[] = { 1, 2, 3, 4, 5 };
i[0] i[b]
1 1
1 2
1 3
...
you get the picture right? What you really need is to check the next value after b.
so the code would look like i[b] > i[b+1]
Honestly, you could probably make it work on how you initialized the order of isOrdered to true and false. I would first initialize it to true. Then the idea is to break out of whatever process you are doing if you find a fallacy in the question with a false. Please look at my examples for further references.
iterative
boolean isOrdered = true;
while(isOrdered && array.length - 1 > b){
if(array[b] > array[b+1]) isOrdered = false;
b++;
}
recursive
boolean isOrdered(int[] array, index){
if(index == array.length - 1) return true;
if(array[index] > array[index + 1]) return false;
return isOrdered(array, index + 1);
}
The recursive method for this is waaaaaaaaaay cooler.
No; you are only checking whether the first element of the array is smaller than or equal to at least one of the elements - including the first element itself, which will always be equal to itself, setting isOrdered to true no matter what the remaining elements are.
Hint #1: you should be comparing every element except the first one with the element immediately before it.
Hint #2: you should be optimistic and assume that the array is ordered, then search for a counter-example. As soon as you found a pair of elements that violate the ordering, set isOrdered to false and break out of the loop.
do a for loop on the size of the array to check if the next item is less then the current:
int arr[] = { 1, 2, 3, 4, 5 };
int b = 0;
boolean isOrdered = true;
for (int i = 0; i< arr.length - 1 ; i ++) {
if (arr[i] > arr[i+1])
{
isOrdered = false;
break;
}
b++;
}
out.println(isOrdered);

Variable not initialized in for loop

So I've been practicing my Java programming skills on the CodingBat website, when I came across this problem. In it, you have to make a simple method that takes in an array of integers of dynamic length, check to see if the elements in the array are in increasing order (1, 2, 3, 15678, etc), and return "true" if true, or "false" if there is an integer out of order.
Firstly, I initialize a boolean variable named "result". Then, I iterate through the array of integers passed by the method. If the current index value is less than the next index value, I set "result" to "true", and repeat the loop. Else, I'll set "result" to "false", break out of the loop and set "result" to "false". After the FOR loop, I return "result".
However, I've been receiving an error message that "result" has not been initialized properly. I can kinda understand the confusing with the JVM, however I thought that setting the value for "result" inside of the IF/ELSE statements would solve that.
Here is a copy of the code that I have done so far:
public boolean scoresIncreasing(int[] scores) {
boolean result;
for (int i = 0; i < scores.length; i++) {
if (i < (i + 1)) {
result = true;
}
else {
result = false;
break;
}
}
return result;
}
First of all, i < i+1 will always be true, unless i = Integer.maxValue, in which case you'll wrap around to Integer.minValue.
What you want is scores[i] < scores[i+1] , and you'll need to adjust your loop values to avoid an index out of bounds on the last iteration.
So, your code fixed:
public boolean scoresIncreasing(int[] scores) {
boolean result;
for (int i = 0; i < scores.length-1; i++) // fix loop end
{
if (scores[i] < scores[(i + 1)]) {
result = true;
}
else {
result = false;
break;
}
} // missing brace
return result;
}
Try this as an alternative. It works on the principle that once you get a false, you can get out immediately.
public boolean scoresIncreasing(int[] scores) {
boolean result = true; // assume true
for (int i = 0; i < scores.length-1; i++) // fix loop end
{
if (scores[i] > scores[(i + 1)]) return false;
} // missing brace
return result;
}
Of course, you may want to introduce bounds checking at the beginning to ensure that there are at least two values.
You are simply missing a closing brace (}) before return result.
As a suggestion to simplify the code (and deal with arrays of 0 elements!), you may want to initialize result to true. Then, as you loop over the array, change result to false if and only if you find an element out of order.
One other word of caution. You use element i + 1 in your for loop. Think about what will happen when you get the last element in the array (i == scores.length - 1).
if (i < (i + 1)) will always evaluate to true. You need to compare the contents of the array at those indexes, not the indexes themselves.
Something like:
public boolean scoresIncreasing(int[] scores) {
for(int i = 0; i < scores.length-1; i++) {
if(scores[i] > scores[i+1]) return false;
}
return true;
}
What if scores has 0 elements? ;]
in your code, you are returning result inside the for loop (after the if-else statement).
Add another bracket before the return statement (to close the for loop)

Categories

Resources