Returning different return value

58 views Asked by At

When i have a problem with the code im writing, i usually handle it like a story. Each command is a sentence in a story. The sentences needs to make sense in order for the story to be complete/right.

So im learning java from scratch now with the MOOC course at Helsinki University. I got somewhat stuck at exercise 68. The program is suppose to compare integer values of a list(array) together with user input. What i programmed is a method that return true if the user input number is already on the list, and false if its not.

What I said about story at the start: The commented out code is my initial code. This did not past the last test but in my head both the commented out code and the other code say basically the same

Error message (from last test): "Answer wrong when parameter was list [0, 7, 9, -1, 13, 8, -1] and value 8 expected: false but was: true"

public static boolean moreThanOnce(ArrayList<Integer> list, int searched) 
//        if (list.size()==1) {return false;}
//        
//        for (int i = 0; i < list.size();i++  ){
//          if (list.contains(searched)) 
//          
//          {
//          
//              return true; }
//          
//        }
//return false;
//   
        int counter = 0;
        for (int num : list) {
            if (searched == num) {
                counter++;
            }
        }
        if (counter >= 2){
            return true;
        } else {
            return false;
        }
    }

I understand that there is something wrong, just cant seem to figure it out. Do you see why the last code would be accepted, but not the first (commented out one) ?

If any use, the rest of the code (not my work) is this:

 public static void main(String[] args) {
        Scanner reader = new Scanner(System.in);
        ArrayList<Integer> list = new ArrayList<Integer>();
        list.add(3);
        list.add(2);
        list.add(7);
        list.add(2);

        System.out.println("Type a number: ");
        int number = Integer.parseInt(reader.nextLine());
        if (moreThanOnce(list, number)) {
            System.out.println(number + " appears more than once.");
        } else {
            System.out.println(number + " does not appear more than once. ");
        }
    }
}
2

There are 2 answers

0
SloCompTech On

Code that is commented out guaranties only that if true there is at least one of occurance in array, maybe there are more but not guaranted. If function returns false thes may be 1 or no occurance.

Reason: If arrary os bigger than 1 it does not mean that there are 2 or more occurances of value you search for.

Posible solution: Add counter like uncommented code.

0
Elliott Frisch On

Your first algorithm has a few flaws, first you test for a length of one explicitly. Not null, and not an empty List. Second, you should prefer the List interface to the ArrayList explicit type. And finally, you need to consider the sublist offset by one of the current position when you call contains (clearly the list contains at least the current value).

I think you wanted something like

public static boolean moreThanOnce(List<Integer> list, int searched) {
    if (list == null || list.size() < 2) {
        return false;
    }

    int len = list.size();
    for (int i = 0; i < len - 1; i++) {
        if (list.get(i).equals(searched) 
                    && list.subList(i + 1, list.size()).contains(searched)) {
            return true;
        }
    }
    return false;
}

And, we can express that as generic method. Like,

public static <T> boolean moreThanOnce(List<T> list, T searched) {
    if (list == null || list.size() < 2) {
        return false;
    }

    int len = list.size();
    for (int i = 0; i < len - 1; i++) {
        if (list.get(i).equals(searched) 
                    && list.subList(i + 1, list.size()).contains(searched)) {
            return true;
        }
    }
    return false;
}

or, if you're using Java 8+, use a Stream and filter and then count like

public static <T> boolean moreThanOnce(List<T> list, T searched) {
    if (list == null || list.size() < 2) {
        return false;
    }
    return list.stream().filter(v -> v.equals(searched)).count() > 1;
}