Here's my problem:
Write a method called allLess that accepts two arrays of integers and returns true if each element in the first array is less than the element at the same index in the second array. Your method should return false if the arrays are not the same length.
Here is my test data:
int[] arr1 = {1,2,4};
int[] arr2 = {3};
int[] arr3 = {5,4,6};
int[] arr4 = {2,2,7};
int[] arr5 = {2,3,6,8};
System.out.println(allLess(arr1,arr2)); //should print false
System.out.println(allLess(arr1,arr3)); //should print true
System.out.println(allLess(arr1,arr4)); //should print false
This is the code I have so far:
public static boolean allLess(int[] a, int[] b){
int len1=a.length;
int len2=b.length;
if(len1==len2){
for(int i=0; i<len1;i++)
if(a[i]<b[i])
return true;
}
else if(len1 !=len2)
return false;
return false;
}
However, when I try System.out.println(allLess(arr1,arr4)); it's printing true. How do I fix this?
The crux: you should scan until you find a mismatch. You're currently only looking for the first happy case.
The main part that you need to change is your conditional - flip its condition.
if(a[i] >= b[i]) {
return false;
}
Be sure to change your last return to true as you've exhausted all negative conditions, and you're pretty much good to go.
There's more cleanup that should be done here, since we're looking at it.
First, use braces everywhere. Do so and your code will be a fair bit easier to follow. You also won't run into bugs if you suddenly discover you need to add more to a conditional block without braces.
Next, you don't need to declare more variables for the length of the arrays - you only care about them in two spots. Just reference a.length and b.length directly as it's not a method call; it's a field, which costs nothing to access.
Third, your else if condition is redundant; it should be an else. Either the lengths of the arrays are equal or they're not.
Here's what it might look like overall:
public static boolean allLess(int[] a, int[] b) {
if (a.length == b.length) {
for (int i = 0; i < a.length; i++) {
if (a[i] >= b[i]) {
return false;
}
}
} else {
return false;
}
return true;
}
Simplifications to this basic form exist.
If you were interested in a Java 8-centric approach, then you could consider this methodology with streams. Essentially, we want to scan all of your elements, and reject the entire statement if the length of the arrays are not equal AND if the value in ai is not equal to bi.
public static boolean allLess(int[] a, int[] b) {
return a.length == b.length && IntStream.range(0, a.length)
.allMatch(i -> a[i] < b[i]);
}
The if statement is returning early, you need to invert the logic and return:
if(a[i]>=b[i])
return false;
This code only compares the first two elements of the arrays. You could instead try the following:
public static boolean allLess(int[] a, int[] b){
int len1=a.length;
int len2=b.length;
if(len1==len2){
for(int i=0; i<len1;i++)
if(!(a[i]<b[i]))
return false;
}
else if(len1 !=len2)
return false;
return true;
}
Related
We need to check if the first array is sorted, and if there are consecutive duplicate elements, check the second array at the index of duplicate elements. This is my code and output
The output I expect is false since a[2]=a[3] and thus we should move to the 2nd array and there b[2]>b[3].
for ex:
1.
array1[]={1,2,3,4,5};
array2[]={5,6,4,3,2};
this should return true because the first array is sorted
2.
array1[]={1,2,3,3,4};
array2[]={5,4,3,6,2};
this should also return true since array1[2]=array1[3] then we go to the array2 and there
array2[2]<array2[3] and hence it should return true.
3.
array1[]={1,2,3,3,4};
array2[]={5,4,4,4,2};
this should also return true since array1[2]=array1[3] then we go to the array2 and there
array2[2]=array2[3] and hence it should return true.
4.
array1[]={1,2,3,3,4};
array2[]={5,6,4,3,2};
this should also return false since array1[2]=array1[3] then we go to the array2 and there
array2[2]>array2[3] and hence it should return false.
In your case (4) it return true, because in your code you have if (a [i] < a[i+1]) return true inside the loop that check the duplicated values. So in array1 (1 < 2) is true, hence it return true.
How to solve this issue, you have to divide your code in two parts.
check if the first array is sorted a good explanation is in stackoverflow.com/a/19458302/3429103,
your code to complete the verification of same value successive and check in the second array.
something like
public class Main
{
public static boolean isSorted(int[] a)
{
for (int i = 0; i < a.length - 1; i++) {
if (a[i] > a[i + 1])
{
return false;
}
}
return true;
}
public static boolean checkDuplicate(int[] a, int b[])
{
for (int i = 0; i < a.length - 1; i++)
{
if (a[i] == a[i + 1] && b[i] > b[i + 1])
{
return false;
}
}
return true;
}
public static void main(String[] args)
{
int array1[]={1,2,3,3,4};
int array2[]={5,6,4,3,2};
if(isSorted(array1) && checkDuplicate(array1,array2))
System.out.println("True");
else
System.out.println("False");
}
}
This method is supposed to return true if four different numbers in the array are all equal. But whenever I try to run it with 4 equal numbers, I get an error that says:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 5
at Assignment4.containsFourOfaKind(Assignment4.java:93)
at Assignment4.main(Assignment4.java:16)
public static boolean containsFourOfaKind( int hand[] ){
for (int i = 0; i < 5; i++) {
if (hand[i ] == hand[i + 1] &&
hand[i + 1] == hand[i + 2] &&
hand[i + 2] == hand[i + 3]
) {
return true;
}
}
return false;
}
How can I fix this?
Most answers only address the ArrayIndexOutOfBoundsException, but they don't address that your original code wasn't detecting for of a kind. It was trying to detect four-in-a-row. Imagine a hand {3, 0, 3, 3, 3}: even if your code didn't cause the ArrayIndexOutOfBoundsException, it still would say that this wasn't four-of-a-kind, although it clearly is.
You need code that actually counts how many of-a-kind there are and then check if it is four or more out of the total hand. (In a typical playing card deck you couldn't have more than 4 of a kind so you can check with == to 4 as well)
The code below is even agnostic to the number of cards in a hand, although from your code above it looks like your hand size is 5 (which is very typical in poker)
public static boolean containsFourOfaKind(int hand[]) {
for (int i = 0; i < hand.length; i++) {
int countOfKind = 0;
for (int j = 0; j < hand.length; j++) {
if (hand[i] == hand[j]) {
countOfKind++;
}
}
if (countOfKind >= 4) {
return true;
}
}
return false;
}
(Note that this is a native approach. You can optimize this further; for example if you look at this closely you'll see that i doesn't have to go any further than 0 and 1.)
When you run your loop from (i=0; i<5;...) you are checking five values... In your if statement you are looking at hand[i] == hand[i+1] && hand[i+1] == hand[i+2] && hand[i+2] == hand[i+3]. This means that during the iteration when i=4 you are trying to access hand[4] through to hand[7].
I suspect your array, hand, doesn't have that many elements.
public static boolean containsFourOfaKind(int hand[]){
for(int x=0; x < hand.length; x++){
for(int y=0; y < hand.length; y++){
if(y!=x){
if(hand[x]!=hand[y]){
return false;
}
}
}
}
return true;
}
You were going outside the index using the +1 within the loop. The above code checks to see if all of the elements in the array are the same.
While others have addressed the ArrayIndexOutOfBoundsException quite clearly, I'd like to propose another method that uses no indexes:
private boolean isArrayEqual(int[] array) {
Arrays.sort(array); //Sort array to place four of a kind in sequence
int[] setOfFour = Arrays.copyOfRange(array, 0, 4); //Copy first four values
int[] compareArray = new int[4];
Arrays.fill(compareArray, setOfFour[0]); //Make an array containing only first value
if (Arrays.equals(compareArray, setOfFour)) { //Test if first four are equal
return true;
} else { //Test is last four are equal
setOfFour = Arrays.copyOfRange(array, 1, 5); //Copy of last four values
Arrays.fill(compareArray, setOfFour[0]);
return Arrays.equals(compareArray, setOfFour);
}
}
You create a second array which is filled with one of the values from the array in question (any value will do - I picked the first one). Then just see if the arrays are equal. Done.
//brain compiled code
public static boolean containsFourOfaKind(int hand[])
{
for(int i=0; i < hand.length - 1; i++)
{
if(hand[i] != hand[i + 1])
return false;
}
return true;
}
Going with your approach you could have had a simple check that was non-iterative that would just check to see if all the four cards were equal, however if you're going for an iterative approach then this is probably your best bet. Whenever you receive an arrayindexoutofbounds exception you always know that it has something to do with your arrays, and in your case there is only one spot that deals with arrays so it should be easy to visualize once you know what t he exception means.
A noniterative approach is as follows...
//brain compiled code
public static boolean containsFourOfaKind(int hand[])
{
if((hand[0] == hand[1]) && (hand[1] == hand[2]) && (hand[2] == hand[3]))
return true;
return false;
}
This can be used however it is not recommended.
An approach that doesn't specifically target a hand, could be to target a larger group; where the array could be much larger than 4. In this case, you could have a loop add onto a map that counts how many times a certain "object" (literal meaning) is in that list:
public static boolean fourOfaKind(Integer[] hand) {
HashMap<Integer,Integer> counts = new HashMap<Integer,Integer>();
for(Integer i : hand) {
if(counts.containsKey(i))
{
int count = counts.get(i);
counts.put(i, ++count);
if(count >= 4)
return true;
}
else
counts.put(i, 1);
}
return false;
}
simple code can be as follows, this will work for N number of element.
public static boolean containsFourOfaKind(int hand[]){
for(int i=1; i < hand.length; i++){
if(hand[i-1] != hand[i]){
return false;
}
}
return true;
}
In Java8 you can do it very easy:
private static boolean isEqualElements(int[] arr) {
return Arrays.stream(arr).allMatch(value -> arr[0] == value);;
}
This is a follow-up to my previous question that I asked yesterday. I wrote a Bubble Sort method that analyzes an array of strings and returns the NUMBER of comparisons that the method has made when ordering the array into alphabetical order (the assignment is to write several types of sorting methods and graph the number of comparisons each one makes, to see which is most efficient).
This is my code:
public static void main(String[] args)
{
String[] test_array = {"bill", "phil", "adam"};
/*
System.out.println(compare("orange", "boogie"));
*/
System.out.println(bubbleSort(test_array));
}
public static int compare(String a, String b)
{
int len = Math.min (a.length(),b.length());
// looping through every character. If cha is less than chb, the method returns -1, and so on.
for (int i = 0; i<len; i++) {
char cha = a.charAt(i);
char chb = b.charAt(i);
if (cha < chb) {
return -1;
} else if (cha > chb) {
return 1;
}
}
// Now we account for the length of the word, since it could be the same word.
if (a.length() < b.length())
return -1;
else if (a.length() > b.length())
return 1;
// Seems to be the same String, so return 0.
else
return 0;
}
public static int bubbleSort(String[] test_array) {
boolean swapped = true;
// Variable to track number of comparisons.
int compNumber = 0;
while (swapped == true) {
swapped = false;
for (int i = 1; i < test_array.length; i++) {
// Tracking the number of comparisons
compNumber++;
if (compare(test_array[i-1], test_array[i]) > 0) {
//Switching the variables by use of a temp variable
String temp = test_array[i-1];
test_array[i-1] = test_array[i];
test_array[i] = temp;
swapped = true;
}
else {
swapped = true;
}
}
}
return compNumber;
}
So the compare method compares two strings (given by the array) and determines if they are in alphabetical order (returns -1) or not (returns 1), or is the same word (returns 0). Then, the bubble sort method calls upon the compare method to go through the array, and it then makes the switches, while my compNumber variable counts the number of times the loop (therefore the number of comparisons) runs.
It compiles fine, but it unfortunately doesn't stop running and doesn't return anything. I've waited 5 minutes so I've determined that something is wrong, probably with my loops. I can't seem to find an issue, having manipulated the parameters of the loops several times. Could anyone help me out? Thanks in advance.
"swapped" will always be true, hence the while will never end looping.
I think you meant to put swapped = false in the else statement
you need to set one of these two swapped = false... or else you will never exit the while loop because swapped = true always ... probably changing the second one makes sense !
if (compare(test_array[i-1], test_array[i]) > 0) {
//Switching the variables by use of a temp variable
String temp = test_array[i-1];
test_array[i-1] = test_array[i];
test_array[i] = temp;
swapped = true;
}
else {
swapped = true;
}
I am a fresh student in computer science and currently we study Java recursion. Unfortunately, the academy only explains the following regarding this topic:
What recursion means.
There are 2 types of cases when using a recursive algorithm: base cases and recursive cases and their purpose.
An example of factorial and Fibonacci implementation using recursion.
Now I got the following exercise:
Two integer numbers will be called "strangers" if their greatest common divisor (aka GTC) is ONLY 1". For example, the numbers 8 and 9 are "strangers" because their GTC is 1. However, 8 and 9 are not "strangers" because their GTC is 2.
Please implement a recursive method which receives an array of integers, and returns "true" if every pair numbers in this array are strangers, and "false" otherwise.
Method signature must be as follows:
public boolean checkGCD(int[] values)
For example:
{3, 5, 7, 11} -> method will returns true.
{4, 7, 8, 9} -> method will returns false because 4 and 8 are not strangers.
For assistance, you can use the following method for finding GTC (Euclidean algorithm):
private static int gcd(int n, int m){
if (m==0)
return n;
return gcd(m,n % m);
}
In addition, the method checkGCD(int[] values) should be overloaded...
Loops cannot be used!
The above can be done very easily with a nested loop, but I must use recursion!
I understand that I need to use an overloaded method which gets the array, lo index and hi index.
So this is what I came up in mind:
######
Base case: if there is at least one pair of numbers in the array which are not strangers, method returns false (no need to continue the comparison...).
######
Comparison will be done in the following way: lo index points to the 1st cell -> hi index points to the 2nd cell -> comparing -> hi index is incremented by 1 until it reaches the last cell of the array.
Then, lo index is incremented by 1, and then repeating the above.
So bottom line, I should compare the first cell to all consecutive cells, compare the 2nd to all consecutive cells, the 3rd etc...
########
If all pairs of numbers are strangers, I need something else to stop recursion. Therefore, if all pairs are strangers, it means that lo index and hi index will eventually point to the last cell (cause both lo and hi index has incremented gradually, and they reach the last array cell after all comparisons turned out to be OK i.e strangers).
The following is the overloaded function:
private static boolean checkGCD(int[] values, int lo, int hi)
{
if ( (gcd(values[lo], values[hi]) )!= 1 )
return false;
else if (lo < values.length-1 && hi < values.length-1)
return checkGCD(values, lo, hi+1);
else if (lo < values.length-2 && hi == values.length-1)
return checkGCD (values, lo+1, lo+2);
if (lo == values.length-1 && hi == values.length-1)
return true;
} -> Compiler says "missing return statement"**
The following is the method the exercise requires to have, and it basically just calls the overloaded method which does everything recursively.
public static boolean checkGCD(int[] values)
{
return checkGCD(values, 0, 1);
}
When I try to compile, I get "missing return statement" which points to the close bracket in the overloaded function
But I do use "return" in the overloaded function.
Please clarify how to fix. I am sure after compilation error, the above overloaded function is still not OK.
You get the compiler error because, if every if fails, the method does not return anything. The solution is add the appropriate return statement when the final if fails.
Not to give the answer away, but here's a strong hint: the base case is an array with two elements. All larger arrays are recursive cases.
There's a general pattern for going through a list with a recursion (pseudocode):
Result f(List f) {
if(f is an empty list) {
return Result for an empty list;
} else {
return (Result for head of list) merged with f(tail of list)
}
}
Since you're using arrays, rather than a type with convenient head() and tail() methods, you could pass in an index to say how much of the array you want to process. When index == array.length you are processing an "empty list".
boolean allMembersPositive(int[] array, int index) {
if(index == array.length) {
return true;
} else {
return (array[index] >=0) && (allMembersPositive(index + 1));
}
}
It's a small step to adapt this to consume two array items per recursive call.
I can guarantee you that when you understand recursion clearly you are going to level up your programming skills.
I recommend reading these URLs:
http://howtoprogramwithjava.com/java-recursion/
http://danzig.jct.ac.il/java_class/recursion.html
Now, lets move back to your questions. I think that is one possible way to implement it:
public class Test {
public static void main(String[] arguments) {
int[] strangers = { 3, 5, 7, 11 };
int[] acquaintances = { 4, 7, 8, 9};
boolean verifyStrangers = checkGCD(strangers);
boolean verifyAcquaintances = checkGCD(acquaintances);
System.out.println(verifyStrangers);
System.out.println(verifyAcquaintances);
}
public static boolean checkGCD(int[] values) {
return checkGCD(values, 0, 1);
}
/*
* I'm really not sure why your professor wants this method signature: "checkGCD(int[] values, int i, int j)"
* I'm coding what I understood from the problem.
*/
private static boolean checkGCD(int[] values, int i, int j) {
boolean result = true;
if (gcd(values[i], values[j]) != 1){
result = false;
}
j++;
if (j < values.length ) {
result = result && checkGCD(values, i, j);
}
return result;
}
private static int gcd(int n, int m) {
if (m == 0)
return n;
return gcd(m, n % m);
}
}
I managed to solve the exercise.
public static int gcd(int n, int m)
{
if (m==0)
return n;
return gcd(m,n % m);
}
private static boolean checkGCD(int[] values, int lo, int hi)
{
// System.out.println("lo is " + lo + " hi is " + hi);
// System.out.println("");
// System.out.println("[lo] is " + values [lo] + " [hi] is " + values[hi]);
// System.out.println("");
if ( (gcd(values[lo], values[hi]) )!= 1 )
return false;
if (lo < values.length-1 && hi < values.length-1)
return checkGCD(values, lo, hi+1);
if (lo < values.length-2 && hi == values.length-1)
return checkGCD(values, lo+1, lo+2);
if (lo == values.length-2 && hi == values.length-1)
return true;
return true;
}
public static boolean checkGCD(int[] values)
{
return checkGCD(values, 0, 1);
}
:-)
I am trying to loop through 2 arrays, the outer array is longer then the other. It will loop through the first and if the 2nd array does not contain that int it will return a false. But I cannot figure out how to go about this. This is what I have so far:
public boolean linearIn(int[] outer, int[] inner) {
for (int i = 0; i < outer.length; i++) {
if (!inner.contains(outer[i])) {
return false;
}
}
return true;
}
I am getting this error when run:
Cannot invoke contains(int) on the array type int[]
I am wondering if it can be done without using a nested loop (like above). I know I'm doing something wrong and if anyone could help on the matter it would be great. Also I wasn't sure what class to look for in the java doc for the int[].
You could check that the larger of the arrays outer contains every element in the smaller one, i.e. inner:
public static boolean linearIn(Integer[] outer, Integer[] inner) {
return Arrays.asList(outer).containsAll(Arrays.asList(inner));
}
Note: Integer types are required for this approach to work. If primitives are used, then Arrays.asList will return a List containing a single element of type int[]. In that case, invoking containsAll will not check the actual content of the arrays but rather compare the primitive int array Object references.
You have two options using java.util.Arrays if you don't want to implement it yourself:
Arrays.toList(array).contains(x) which does exactly you are doing right now. It is the best thing to do if your array is not guaranteed to be sorted.
Arrays.binarySearch(x,array) provided if your array is sorted. It returns the index of the value you are search for, or a negative value. It will be much, much faster than regular looping.
If you would like to use contains then you need an ArrayList. See: http://docs.oracle.com/javase/7/docs/api/java/util/ArrayList.html#contains(java.lang.Object)
Otherwise, you need two loops.
There is a workaround like this:
public boolean linearIn(int[] outer, int[] inner) {
List<Integer> innerAsList = arrayToList(inner);
for (int i = 0; i < outer.length; i++) {
if (!innerAsList.contains(outer[i])) {
return false;
}
}
return true;
}
private List<Integer> arrayToList(int[] arr) {
List<Integer> result= new ArrayList<Integer>(arr.length);
for (int i : arr) {
result.add(i);
}
return result;
}
But don't think that looping is not happening, just because you don't see it. If you check the implementation of the ArrayList you would see that there is a for loop:
http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/util/ArrayList.java#ArrayList.indexOf(java.lang.Object)
So you are not gaining any performance. You know your model best, and you might be able to write more optimized code.
The question above is a practice in my class. There is my friend' solution:
public boolean contains(int[] arrA, int[] arrB) {
if (arrB.length > arrA.length) return false;
if (arrB.length == 0 && arrA.length == 0) return false;
for (int count = 0, i = 0; i < arrA.length; i++) {
if (arrA[i] == arrB[count]) {
count++;
} else {
count = 0;
}
if (count == arrB.length) return true;
}
return false;
}
int[] is a primitive array. Meaning it does not have any special methods attached to it. You would have to manually write your own contains method that you can pass the array and the value to.
Alternatively you could use an array wrapper class such as ArrayList which does have a .contains method.
ArrayList<Integer> inner = new ArrayList<Integer>();
boolean containsOne = inner.contains(1);
contain method is reserved for ArrayList
Try this:
public boolean linearIn(int[] outer, int[] inner) {
for (int i = 0; i < outer.length; i++) {
for (int j = 0; j < inner.length; j++) {
if (outer[i] == inner[j])
return false;
}
}
return true;
}