I'm trying to implement a containsAll method, but I don't understand why it's returning incorrect results. Please, help me.
public boolean contains(Object o) {
for (int ob = 0; ob < size; ob++) {
if (o == obj[ob])
return true;
}
return false;
}
public boolean containsAll(MyList c) {
for (int ob = 0; ob < size; ob++) {
c.toArray();
if (c.contains(obj[ob]))
{
return true;
}
}
return false;
}
It returns an incorrect result, because you return true after the first matching element is found. The logic should be along the lines of:
for (int ob = 0; ob < size; ob++) {
/* ... */
if (!c.contains(obj[ob])) {
return false;
}
}
return true;
I.e. return false after finding the first non-matching element, and only return true after checking all elements.
Also note that using ==, you're performing a strict identity comparison. If that's not what you're after, consider using equals() instead.
Related
I am trying to solve a coding problem. The problem is following:
Given a sequence of integers as an array, determine whether it is possible to obtain a strictly increasing sequence by removing no more than one element from the array.
For example:
[1,3,2,1] is false
[1,3,2] is true
I implemented it in Java. The code is as follows:
boolean almostIncreasingSequence(int[] sequence) {
int count =0;
for(int i =0; i < sequence.length; i++){
if (sequence[i] <= sequence[i-1]){
count++;
}
if(count>1){
return false;
}
if(sequence[i] <= sequence[i-2] && sequence[i+1] <= sequence[i-1]){
return false;
}
}
return true;
}
This is the following error:
Execution error on test 1: Your program had a runtime error.
Any help will be appreciated. It seems a small problem but I can't resolve it.
One implementation can be based on remove just 1 element when strictly ascending condition is not achieved.
public class TestAlmostIncreasingSequence {
public static boolean almostIncreasingSequence(int[] sequence)
{
if(sequence==null) return false;
//mandatory to remove just 1 element, if no one(or more) removed then false
boolean flag_removed=false;
for(int i=1, prev=sequence[0];i<sequence.length;i++)
{
if(prev>=sequence[i] && flag_removed==false)
{
//mark removed
flag_removed=true;
}
//if element was removed then false
else if(prev>=sequence[i] && flag_removed==true)
{
return false;
}
else
{
//change only if element removed is not the current
//comparisons will not be done with removed element
prev=sequence[i];
}
//System.out.println(prev);
}
//could have a strictly increased arr by default which will return false [1,2,3]
return flag_removed;
}
public static void main(String[] args)
{
//only for printing purpose
String arr="";
int s1[] = {1,2,3,1};
arr=Arrays.stream(s1).mapToObj(t->String.valueOf(t)).
collect(Collectors.joining(",","[","]"));
System.out.println(arr+"\n"+almostIncreasingSequence(s1)+"\n");
int s2[] = {1,2,3};
arr=Arrays.stream(s2).mapToObj(t->String.valueOf(t)).
collect(Collectors.joining(",","[","]"));
System.out.println(arr+"\n"+almostIncreasingSequence(s2)+"\n");
int s3[] = {1,2,3,1,2};
arr=Arrays.stream(s3).mapToObj(t->String.valueOf(t)).
collect(Collectors.joining(",","[","]"));
System.out.println(arr+"\n"+almostIncreasingSequence(s3)+"\n");
int s4[] = {1};
arr=Arrays.stream(s4).mapToObj(t->String.valueOf(t)).
collect(Collectors.joining(",","[","]"));
System.out.println(arr+"\n"+almostIncreasingSequence(s4)+"\n");
int s5[] = {1,1};
arr=Arrays.stream(s5).mapToObj(t->String.valueOf(t)).
collect(Collectors.joining(",","[","]"));
System.out.println(arr+"\n"+almostIncreasingSequence(s5)+"\n");
int s6[] = null;
arr="null";
System.out.println(arr+"\n"+almostIncreasingSequence(s6)+"\n");
}
}
Output
[1,2,3,1]
true
[1,2,3]
false
[1,2,3,1,2]
false
[1]
false
[1,1]
true
null
false
Note: The implementation have a case when the result is wrong [1,5,2,3], just update with one more branch with removed element=the previous one(not the current) and check both branched (one true means true)
This should fix the case
//method name is misguided, removePrev is better
public static boolean removeCurrent(int[] sequence)
{
if(sequence==null) return false;
//mandatory to remove just 1 element, if no one remove then false
boolean flag_removed=false;
for(int i=1, prev=sequence[0];i<sequence.length;i++)
{
if(prev>=sequence[i] && flag_removed==false)
{
//mark removed
flag_removed=true;
}
//if element was removed then false
else if(prev>=sequence[i] && flag_removed==true)
{
return false;
}
//compared element will be the current one
prev=sequence[i];
//System.out.println(prev);
}
//could have a strictly increased arr by default which will return false [1,2,3]
return flag_removed;
}
and use
int s1[] = {1,5,2,3};
arr=Arrays.stream(s1).mapToObj(t->String.valueOf(t)).
collect(Collectors.joining(",","[","]"));
boolean result= (almostIncreasingSequence(s1)==false) ? removeCurrent(s1) : true;
System.out.println(arr+"\n"+result +"\n");
Output
[1,5,2,3]
true (from removeCurrent_branch)
Seems one more case is wrong [5,6,3,4], means need to see if element[i-2](only after remove element) is not greater then current and 'prev' on last branch.
6>3 remove 6 (prev=3, 3<4 but [5>4 or 5>3] so false)
public static boolean removeCurrent(int[] sequence)
{
if(sequence==null) return false;
//mandatory to remove just 1 element, if no one remove then false
boolean flag_removed=false;
for(int i=1, prev=sequence[0], twoprev=Integer.MIN_VALUE;i<sequence.length;i++)
{
if(prev>=sequence[i] && flag_removed==false)
{
//mark removed
flag_removed=true;
if(i>=2) twoprev=sequence[i-2];
}
//if element was removed then false
else if(prev>=sequence[i] && flag_removed==true)
{
return false;
}
else if(twoprev>=sequence[i] || twoprev>=prev)
{
return false;
}
//compared element will be the current one
prev=sequence[i];
//System.out.println(prev);
}
//could have a strictly increased arr by default which will return false [1,2,3]
return flag_removed;
}
Output
[5,6,3,4]
false
Now, as far as I see all cases seems covered.
Brute force can also generate a solution but will be less optimal.(use a loop to remove an element, sort the result and compare with base)
public class TestInc {
public static void main(String[] args)
{
int s1[] = {1,1,2,3};
System.out.println(checkInc(s1));
}
public static boolean checkInc(int[] arr)
{
if(arr==null || arr.length==1) return false;
List<Integer> lst = Arrays.stream(arr).boxed().collect(Collectors.toList());
//remove this check if requirement is other(or return true)
if(checkIfAlreadySortedAsc(lst))
{
return false;
}
for(int i=0;i<lst.size();i++)
{
List<Integer> auxLst = new ArrayList<Integer>(lst);
auxLst.remove(i);
List<Integer> sorted = new ArrayList<Integer>(auxLst);
sorted = sorted.stream().distinct().sorted().collect(Collectors.toList());
if(auxLst.equals(sorted))
{
// System.out.println("=");
return true;
}
else
{
// System.out.println("!=");
}
}
return false;
}
//any ascending sorted list will be the same type if remove one element
//but as requirement on this case will return false
//(or don't use method in want other)
public static boolean checkIfAlreadySortedAsc(List<Integer> lst)
{
List<Integer> auxLst = new ArrayList<Integer>(lst);
auxLst = auxLst.stream().distinct().sorted().collect(Collectors.toList());
if(auxLst.equals(lst))
{
return true;
}
return false;
}
}
Output
[1,1,2,3]
true
This line would produce an ArrayIndexOutOfBoundsException when i == 0 because it will attempt to access sequence[-1]
if (sequence[i] <= sequence[i-1]){
This is the error I get:
This method must return a result of type boolean
And this is the code:
public boolean seleccionar(Aeronave otra) {
for (int i = 0; i < this.as.length; i++) {
if (otra != null && !otra.equals(this.as[i]) && otra.amenazadaPor(this.as[i])) {
return true;
} else {
return false;
}
}
}
Add a return false before the last brace. Your function doesn't return anything if this.as.length == 0, and Java is giving a compile error because of that.
The issue is that it is possible that the for-loop will loop through all elements and eventually reach the end and no result is returned. In this case we return false to ensure this.
public boolean seleccionar (Aeronave otra) {
for (int i=0; i < this.as.length; i++) {
if (otra !=null && !otra.equals(this.as[i]) && otra.amenazadaPor(this.as[i])) {
return true;
}
}
return false;
}
Your code will exit on first loop element. But when array this.as is empty, so loop will not execute, then your function is missing a return value -therefore compiler does not allow this.
To solve this issue, simply move return false after the loop ends.
public boolean seleccionar (Aeronave otra) {
for (int i=0; i < this.as.length; i++) {
if (otra !=null && !otra.equals(this.as[i]) && otra.amenazadaPor(this.as[i])) {
return true;
}
}
return false; // if no elements are matching loop condition, return false
}}
So I have a database called appleList. Within it I have apple objects which within them has a list of items. I'm attempting to create a method where it returns true if item j is within the list of customer r and false if its not. This is what I have come up with so far...
public boolean (String m)
{
if(n[i] = p)
found = true;
return found;
}
Use equals() to compare Strings. Also, if n is an array you need to pass it in like below
public boolean hasProduct(String[] n, String p)
{
boolean found = false;
for(int i=0; i < n.size(); i++)
if(n[i].equals(p))
found = true;
return found;
}
There's an existing method in List that you can use
customerList.contains(object)
This method return true if the list contains the object
If you are using a custom object you can override the method equals, so the method above will use it to compare all objects in your list
public class MyCustomClass{
private Integer id;
//Other variables, getters and setters
#Override
public boolean equals(Object o2){
if(o2 instanceof MyCustomClass){
MyCustomClass o2custom = (MyCustomClass) o2;
if(o2custom.getId()!=null && this.id != null){
return o2custom.getId() == this.id;
}
}
return false;
}
}
Hugs
String n is not an array n[0] is wrong try this :
public boolean hasProduct(String p)
{
boolean found = false;
for(int i=0; i < customerList.size(); i++)
if(customerList.get(i) == p)
found = true;
return found;
}
To iterate an ArrayList you need to use .get(). Also, I added a break in your loop once the item is found.
public boolean hasProduct(String n, String p)
{
boolean found = false;
for(int i=0; i < this.customerList.size(); i++)
if(this.customerList.get(i) == p)
found = true;
break;
return found;
}
Since you're looking for a String in an ArrayList, you can simply do something like this:
public boolean hasProduct(ArrayList customerList, String p)
{
return customerList.contains(p);
}
As #DigaoParceiro mentions, if you're looking for a custom object within your collection, be sure to override equals() and hashCode(). String already provides this for you.
For my equals method that checks to see if two arrays are equal, does the first method "equals" actually check if the two arrays are equal or only tests the memory addresses? Or should I include both?
public boolean equals(Object otherObject)
{
if (otherObject == null)
{
return false;
}
else if (getClass() != otherObject.getClass())
{
return false;
}
else
{
RegressionModel otherRegressionModel = (RegressionModel)otherObject;
return (xValues == (otherRegressionModel.xValues) && yValues == (otherRegressionModel.yValues));
}
}
OR
public static boolean equalArrays(double[] x, double[] y)
{
if(x.length != y.length)
{
return false;
}
else
{
for(int index = 0; index < x.length; index++)
{
if (x[index] != y[index])
{
return false;
}
}
return true;
}
}
the =/!= operator compares arrays based upon their reference, and not their content. Clearly two arrays may have the same elements, except they are still two distinct objects that are created in the memory. The arrays are two references. Therefore your second method should be applied, because it compares the actual elements inside the two arrays. Also you don't need your else statement.
public static boolean equalArrays(double[] x, double[] y)
{
if(x.length != y.length)
{
return false;
}
for (int index = 0; index < x.length; index++)
{
if (x[index] != y[index])
{
return false;
}
}
return true;
}
One more check can also be applied on first equals method where it can see both array has an same reference or not. Then other comparison can be done. In second method it always check the element of an array, even if both an reference of same array. so in terms of performance it will take time.
public boolean equals(Object otherObject)
{
if (otherObject == null)
{
return false;
}
else if (getClass() != otherObject.getClass())
{
return false;
} else if (this != otherObject)
return false;
}
else
{
RegressionModel otherRegressionModel = (RegressionModel)otherObject;
return (xValues == (otherRegressionModel.xValues) && yValues == (otherRegressionModel.yValues));
}
}
Adding to #Henry's answer, before comparing lengths of the two given arrays you should make sure that neither of them are null so that you don't get a NullPointerException.
You might also want to compare the references of the arrays before looping through their elements.
Something like this:
public static boolean equalArrays(double[] x, double[] y)
{
if (x == null || y == null || x.length != y.length)
{
//NOTE: That if both x and y are null we return false despite the fact that you could argue that they are equal
return false;
}
if (x == y)
{
return true;
}
for (int index = 0; index < x.length; index++)
{
if (x[index] != y[index])
{
return false;
}
}
return true;
}
EDIT: With your help I managed to fix my problem. I have edited my code to now show how I had to have it set up to get it working.
Currently I am having trouble coding a part which compares the content of two iterators. As part of the requirements for my assignment, I need to use a linkedlist to store the individual characters of the entered String. I have gotten to the point where I have two iterators which would contain the input one way and the reverse way.
String palindrom = input.getText();
String [] chara = palindrom.split (""); //this is successfully splitting them, tested.
int length = palindrom.length( ); // length == 8
System.out.println (length); //can use this for how many checks to do?
LinkedList ll = new LinkedList(Arrays.asList(chara));
Iterator iterator = ll.iterator();
Iterator desIterator = ll.descendingIterator();
/*while(iterator.hasNext() ){
System.out.println(iterator.next() );
}
while(desIterator.hasNext() ){
System.out.println(desIterator.next() );
}*/
boolean same = true;
while(iterator.hasNext()){
if(!iterator.next().equals(desIterator.next())){
same = false;
break;
}
}
And using the System.out I can see that they are being stored correctly, but I don't know how to check if the iterators store the same contents. What would be one of the simplest methods to compare the two iterators or convert them into something I can compare? To clarify I want to verify they contain the same elements in the same order.
boolean same = true;
while(iterator.hasNext()){
if(!desIterator.hasNext() || !iterator.next().equals(desIterator.next())){
same = false;
break;
}
}
System.out.println(same);
You need to iterate over both iterators simultaneously, i.e. with one loop. Here is a general comparison function (0 when equal, < 0 when A < B, > 0 when A > B):
static <T extends Comparable<S>, S> int compare(Iterator<T> a, Iterator<S> b) {
while (a.hasNext() && b.hasNext()) {
int comparison = a.next().compareTo(b.next());
if (comparison != 0) {
return comparison;
}
}
if (a.hasNext())
return 1;
if (b.hasNext())
return -1;
return 0;
}
To just check if they are equal, this can be simplified:
static <T, S> boolean equals(Iterator<T> a, Iterator<S> b) {
while (a.hasNext() && b.hasNext()) {
if (!a.next().equals(b.next())) {
return false;
}
}
if (a.hasNext() || b.hasNext()) {
// one of the iterators has more elements than the other
return false;
}
return true;
}
Guava implements this as Iterators.elementsEqual.
In both answers throw NullPointerException, if iterator.next() == null. This method is more optimal.
public static boolean equals(Iterator i1, Iterator i2) {
if (i1 == i2) {
return true;
}
while (i1.hasNext()) {
if (!i2.hasNext()) {
return false;
}
if (!Objects.equals(i1.next(), i2.next())) {
return false;
}
}
if (i2.hasNext()) {
return false;
}
return true;
}