Incorrect logic in my loop - java

public static void main(String[] args) {
Integer[] courses1 = {1,2,3};
Integer[] courses2 = {0,1};
Integer[] longestArr;
Integer[] shortestArr;
ArrayList commonCourses = new ArrayList();
if ( courses1.length > courses2.length)
{
longestArr = courses1; shortestArr = courses2;
}
else
{
longestArr = courses2; shortestArr = courses1;
}
for ( int i : longestArr)
{
for ( int j : shortestArr)
{
if (i == j);
commonCourses.add(i);
}
}
Collections.sort(commonCourses);
System.out.println(commonCourses.size());
}
No matter what the values of course1 and courses2, the arrayList commonCourses always has a size of one more the the total number of elements in both arrays when it is supposed to only contain the elements that are in both arrays. I have 2 questions why is ever element from the 2 arrays being added to the arrayList and why is the size of the arrayList always one more than the total number of elements? If you are wondering why I have courses1 and courses2 declared at the start, this is a problem from talentBuddy.co that I'm testing on eclipse. I have tested with different starting conditions and the same thing always happens.
My new slimmed down solution
public static void main(String[] args) {
Integer[] courses1 = {1};
Integer[] courses2 = {0};
ArrayList <Integer>commonCourses = new ArrayList<Integer>();
for ( int i : courses1)
{
for ( int j : courses2)
{
if (i == j)
commonCourses.add(i);
}
}
Collections.sort(commonCourses);
System.out.println(commonCourses.size());
}

Your problem is the semicolon in this line:
if (i == j);
The if clause ends here and the following line is always executed.

The semi-colon at the end of the if-condition is your problem. For a detailed explanation on why this happens, see this StackOverflow post. In short, the semi-colon causes the compiler to ignore the conditional at runtime.
for ( int j : shortestArr)
{
if (i == j);
// ^ Remove this semi-colon
commonCourses.add(i);
}
Using curly-braces to format your if-statements helps prevent this from happening:
if(condition){
doSomething();
}

for ( int j : shortestArr)
{
if (i == j);
// ^ REMOVE THIS SEMICOLON
commonCourses.add(i);
}
The problem is that extra semicolon. Your chunk of code is functionally identical to this right now:
for ( int j : shortestArr)
{
if (i == j)
{
}
commonCourses.add(i);
}

You have a misused semicolon after the if condition.
if (i == j);

I have never worked in a firm where they did not require parenthesis after if:
if (...) {
...
}
And the reason quite evident.
Let me show the most abstracted solution:
Courses are sets of unique course numbers
Common courses is an intersection set
In java one uses abstract interfaces like Set for the variable, but can implement that set with different implementing classes
One wants a sorted set, TreeSet is such an implementation
Set<Integer> courses1 = new HashSet<>();
Collections.addAll(courses1, 1, 2, 3);
SortedSet<Integer> courses2 = new HashSet<>();
Collections.addAll(courses2, 0, 1);
SortedSet<Integer> commonCourses = new TreeSet<>(courses1);
commonCourses.retainAll(courses2);

Related

Getting wrong answer while trying to solve Best sum problem using Dynamic programming

Trying to solve the best sum problem but I'm not getting the right answer using DP but if I remove the memoization part of this code then I'm getting the right answer.
I'm attaching the output screenshots:
PS: Please do not judge my code I'm trying to learn DP and I know that this code is not the best.
public class BestSum {
public static void main(String[] args) {
int[] arr = { 2, 3, 4, 5 };
int num = 10;
Map<Integer, List<Integer>> map = new HashMap<>();
List<Integer> list = rec(arr, num, map);
System.out.println(list);
}
static List<Integer> rec(int[] arr, int n, Map<Integer, List<Integer>> map) {
if (n == 0) {
return new ArrayList<>();
}
if (n < 0) {
return null;
}
if (map.containsKey(n)) {
return map.get(n);
}
List<Integer> sCombo = null;
for (int i : arr) {
int rem = n - i;
List<Integer> t = rec(arr, rem, map);
if (t != null) {
List<Integer> list = new ArrayList<>();
t.add(i);
list.addAll(t);
if (sCombo == null || list.size() < sCombo.size()) {
sCombo = list;
}
}
}
map.put(n, sCombo);
return map.get(n);
}
}
list.add(i); // write this instead of t.add(i).
a little mistake in the code nothing else.
just small mistake i.e....
you directly inserting sCombo into the Map. the values in sCombo array was changing while recursion every time at the same time the same sCombo array values in the map also changing because there have only one block of memory for each sCombo array that means when ever we edit that sCombo array it will effects the previous result....
example:- you assigned the list to sCombo
sCombo=list;
when ever the list gets changes then the sCombo also changed
just clone() the object you get correct result like this......

How to add an integer to a set while iterating?

I have a set of sets of integers: Set<Set<Integer>>.
I need to add integers to the set of sets as if it were a double array. So add(2,3) would have to add integer 3 to the 2nd set.
I know a set is not very suitable for this operation but it's not my call.
The commented line below clearly does not work but it shows the intention.
My question is how to add an integer to a set while iterating?
If it's necessary to identify each set, how would one do this?
#Override
public void add(int a, int b) {
if (!isValidPair(a, b)) {
throw new IllegalStateException("!isValidPair does not hold for (a,b)");
}
Iterator<Set<Integer>> it = relation.iterator();
int i = 0;
while (it.hasNext() && i <= a) {
//it.next().add(b);
i++;
}
}
One fundamental things you should be aware of, for which makes all existing answer in this question not working:
Once an object is added in a Set (similarly, as key in Map), it is not supposed to change (at least not in aspects that will change its equals() and hashCode()). The "Uniqueness" checking is done only when you add the object into the Set.
For example
Set<Set<Integer>> bigSet = new HashSet<>();
Set<Integer> v1 = new HashSet<>(Arrays.asList(1,2));
bigSet.add(v1);
System.out.println("contains " + bigSet.contains(new HashSet<>(Arrays.asList(1,2)))); // True
v1.add(3);
System.out.println("contains " + bigSet.contains(new HashSet<>(Arrays.asList(1,2)))); // False!!
System.out.println("contains " + bigSet.contains(new HashSet<>(Arrays.asList(1,2,3)))); // False!!
You can see how the set is corrupted. It contains a [1,2,3] but contains() does not work, neither for [1,2] nor [1,2,3].
Another fundamental thing is, your so-called '2nd set' may not make sense. Set implementation like HashSet maintain the values in arbitrary order.
So, with these in mind, what you may do is:
First find the n-th value, and remove it
add the value into the removed value set
re-add the value set.
Something like this (pseudo code again):
int i = 0;
Set<Integer> setToAdd = null;
for (Iterator itr = bigSet.iterator; itr.hasNext(); ++i) {
Set<Integer> s = itr.next();
if (i == inputIndex) {
// remove the set first
itr.remove();
setToAdd = s;
break;
}
}
// update the set and re-add it back
if (setToAdd != null) {
setToAdd.add(inputNumber);
bigSet.add(setToAdd);
}
Use a for-each loop and make your life easier.
public boolean add(int index, int value) {
// because a and b suck as variable names
if (index < 0 || index >= values.size()) {
return false;
}
int iter = 0;
for (Set<Integer> values : relation) {
if (iter++ == index) {
return values.add(value):
}
}
return false;
}
Now all you have to figure out is what to do if relation is unordered, as a Set or a relation are, because in that case a different Set<Integer> could match the same index each time the loop executes.
Use can use Iterators of Guava library like this :
#Override
public void add(int a, int b) {
if (!isValidPair(a, b)) {
throw new IllegalStateException("!isValidPair does not hold for (a,b)");
}
Iterators.get(relation.iterator(), a).add(b);
}
Edit : without Guava:
Iterator<Set<Integer>> iterator = relation.iterator();
for(int i = 0; i < a && iterator.hasNext(); ++i) {
iterator.next();
}
if(iterator.hasNext()) {
iterator.next().add(b);
}

how to compare int[] array with int in android?

I need to compare int[] array with integer values. This code am having
int c1[], c2[], c3[];
int count1=0, count2=1, count3=0;
c1 = new int[] { count1 };
c2 = new int[] { count2 };
c3 = new int[] { count3 };
Now i need to compare this int[] array with int, that is any array equals 0 then code don't need to execute if not equals then code execute. How to compare ?? help me thanks in advance ? this if condition i tried but it wont execute exactly.
if(c1.equals(0))
{
// skip
}
else
{
// execute code
}
this above code didn't work.
Try following:
for(int i=0;i<cl.length;i++){
if(c1[i]==0)
{
// skip
}
else
{
// execute code
}
}
Perhaps you are looking for :
if(c1[0] == 0)
{
// skip
}
else
{
// execute code
}
Though it's unclear why you need c1 to be an array if it only holds a single integer.
Use c1[0],c1[1] .... and (iterate through loop)
like-
if(c1[0]==0)

Comparing int to arraylist of integer

I have an int element and I would like to know if this int is higher than all the integers of an Arraylist ?
Example :
int a ; // Contain an int (i.e 51 or 54 or 989...etc)
ArrayList<Integer> list = new ArrayList<Integer>(); // contain a list of Integers
My purpose is to know if a is higher than any number in the arraylist.
Thanks in advance
Sorting is complete overkill. You just need to compare your value to the highest value in the list. Here's a way to do this with existing library functions:
if (a > Collections.max(list)) {
//a is higher than anything in list
}
Note:
This carries a caveat of always going through the whole list even if the very first element is larger than a. But it's a tradeoff you're usually willing to make because the code reads so nice. If you really want the early exit, you can roll your own approach like in Austin's answer, or in Java 8, it would look something like this:
if ( list.stream().allMatch(element -> a > element) ) {
//...a is higher than anything in list
}
you can just iterate the array to see if any other value is higher..
int a = _whateverInt ; // Contain an int (i.e 51 or 54 or 989...etc)
ArrayList<Integer> list = new ArrayList<Integer>();
boolean isHigher = true;
for(int i = 0; i < list.size() && isHigher; i ++)
{
isHigher = a > list.get(i);
}
Solution 1:
public class Test {
public static void main(String[] args) {
int a = 150;
ArrayList<Integer> arrayList = new ArrayList<Integer>();
arrayList.add(50);
arrayList.add(100);
arrayList.add(30);
System.out.println(a > Collections.max(arrayList));
}
}
Solution 2:
public class Test {
public static void main(String[] args) {
int a = 150;
ArrayList<Integer> arrayList = new ArrayList<Integer>();
arrayList.add(50);
arrayList.add(100);
arrayList.add(30);
Collections.sort(arrayList);
System.out.println(a > arrayList.get(arrayList.size() - 1));
}
}
int a;
ArrayList<Integer> list = new ArrayList<Integer>();
int max = Collections.max(list);
if(a>max)
{
//this is what you want
}
Hope you find this useful...
edit: oops someone already answered the same trick :(
private boolean isLargest(int a, ArrayList<Integer> list)
{
ArrayList<Integer> sortedList = Collections.sort(list);
if(a > sortedList.get(0))
return true;
return false;
}
It is not efficient, but this approach leaves the ordering in the original list in-tact.

java.lang.ArrayIndexOutOfBoundsException: 4 Error

I'm new to coding and I've been writing this code and trying to make it work but every time I run it it crashes. I've looked things up and will writing this code I've followed java's website on how to properly write down code as well as this site.
Anyways, it would be greatly appreciated if someone can explain to me why this is not working because it seems to me like the logic is there but I don't get why it crashes.
My code:
import java.util.Scanner;
import java.lang.String;
import java.util.*;
public class Question1
{
public static void main(String[] args)
{
Scanner keyboard= new Scanner(System.in);
System.out.println("Enter either letters or numbers and I'll magically tell you if they are consecutive :D");
String inputedString= keyboard.nextLine();
boolean consecutiveOrNot=isConsecutive(inputedString);
System.out.println("Drum rolls...... Is it consecutive: "+ consecutiveOrNot); //Problem with this line?
}
public static boolean isConsecutive(String inputedString)
{
//Storing string's units into an array and converting to UpperCase if necessary
//and storing string's numerical value into the variable 'arrayCharToInt'
char[] charIntoArray= new char[inputedString.length()];
int[] arrayCharToInt= new int[inputedString.length()];
for (int i=0;i<inputedString.length();i++ )
{
charIntoArray[i]=inputedString.charAt(i);
if (Character.isLetter(charIntoArray[i]) && Character.isLowerCase(charIntoArray[i]))
{
charIntoArray[i]= Character.toUpperCase(charIntoArray[i]);
}
arrayCharToInt[i]=(int) charIntoArray[i];
}
// The next if statements and the methods that they call are used to verify
//that the content of the initial string is either letters or numbers, but not both together
boolean[] continuous= new boolean[arrayCharToInt.length];
boolean[] testContNumbersDecreasing= new boolean[arrayCharToInt.length];
boolean[] testContNumbersIncreasing= new boolean[arrayCharToInt.length];
boolean[] testContLettersDecreasing= new boolean[arrayCharToInt.length];
boolean[] testContLettersIncreasing= new boolean[arrayCharToInt.length];
Arrays.fill(continuous, true);
if (lowestValue(arrayCharToInt)>=65 && highestValue(arrayCharToInt)<= 90)
{
for (int x=0;x<arrayCharToInt.length ;x++ )
{
testContLettersIncreasing[x]=((arrayCharToInt[x+1]-arrayCharToInt[x]== 1) || (arrayCharToInt[x+1]-arrayCharToInt[x]== -25));
testContLettersDecreasing[x]=((arrayCharToInt[x]-arrayCharToInt[x+1]== 1) || (arrayCharToInt[x]-arrayCharToInt[x+1]== -25));
}
return (Arrays.equals(continuous,testContLettersIncreasing) || Arrays.equals(continuous,testContLettersDecreasing));
}
else if ((lowestValue(arrayCharToInt) >= 48) && (highestValue(arrayCharToInt)<= 57))
{
for (int x=0;x<arrayCharToInt.length ;x++ )
{
testContNumbersIncreasing[x]=((arrayCharToInt[x+1]-arrayCharToInt[x]== 1) || (arrayCharToInt[x+1]-arrayCharToInt[x]== -9));
testContNumbersDecreasing[x]=((arrayCharToInt[x]-arrayCharToInt[x+1]== 1) || (arrayCharToInt[x]-arrayCharToInt[x+1]== -9));
}
return (Arrays.equals(continuous,testContNumbersIncreasing) || Arrays.equals(continuous,testContNumbersDecreasing));
}
else
{
return false;
}
}
public static int lowestValue(int[] array)
{
int lowest=array[0];
for (int counter=0; counter< array.length; counter++)
{
if( lowest>array[counter])
lowest= array[counter];
}
return lowest;
}
public static int highestValue(int[] array)
{
int highest=array[0];
for (int counter=0; counter< array.length; counter++)
{
if( highest<array[counter])
highest= array[counter];
}
return highest;
}
}
The main method seems to be fine because it put everything in the isConsecutive method as a comment except for 'return true;' and indeed the program ran and printed true. So I know the problem lies somewhere in the second method.
If there's anything that I did not do right please tell me and that would be greatly appreciated. After all I'm still learning.
Thanks
All of your calls to arrayCharToInt[x+1] are going to go out of bounds on the last iteration of the loop they're in (for example, if arrayCharToInt.length equals 5, the highest that x is going to go is 4. But then x+1 equals 5, which is out of bounds for an array with five cells). You'll need to put in some sort of if( x == arrayCharToInt.length - 1) check.
in the method isConsecutive inside the for loop: for (int x=0;x<arrayCharToInt.length ;x++ ) , you have used arrayCharToInt[x+1]
if the arrayCharToInt lenth is 4 , then you have arrayCharToInt [0] to arrayCharToInt [3].
now consider this statement:arrayCharToInt[x+1]
when x is 3 this statement will evalueate to arrayCharToInt[4] resulting in array index out of bounds exception
This error throw when something went wrong in the Array calling function.
You got the length and make it print.
for eg:
int a[] = {1,2,3,4}
Length of this array is,
int length = a.length
So length = 4 but highest index is 3, not 4. That means index of the array started with 0. So you have to print:
arr[length-1];
In your program,
x == arrayCharToInt.length - 1

Categories