Reputation: 1045
I am trying to determine if the numbers in an array list are divisiable by all of numbers in antoher arraylist. My code below outputs all of the numbers from the listdiv
list that are disible by any divisors in the listdivisor
. I would like to output the values that are divisible by all divisiors in the list not any of them. For example If I have listdiv = [1,2,3,,5,8] and listdivisor= [2,4]. the expected output should be 8 , but this code outputs 2 and 8 .
Thank you !your effort will be greatly appreciated!
for (int i = 0; i < listdiv.size(); i++) {
for (int c = 0; c < listdivisor.size(); c++) {
if (listdiv.get(i) % listdivisor.get(c) == 0) {
System.out.println("final results are : " + listdiv.get(i));
}
}
}
Upvotes: 2
Views: 2609
Reputation: 175
We can use Set for getting the expected output, I have modified your code,
Set<Integer> firstIteration = new HashSet<>();
Set<Integer> nextIteration = new HashSet<>();
for (int c = 0; c < divisors.size(); c++) {
for (int i = 0; i < numbers.size(); i++) {
if (numbers.get(i) % divisors.get(c) == 0) {
if (c == 0) {
firstIteration.add(numbers.get(i));
} else {
nextIteration.add(numbers.get(i));
}
}
}
if (c != 0) {
// We will perform Set intersection here for each iteration
firstIteration.retainAll(nextIteration);
}
}
System.out.println(firstIteration);
Hope this will solve your issue
Upvotes: 0
Reputation: 73480
All the algorithms presented so far are O(N*M). It is possible to get O(N+M) by first finding the LCM of the first list and using that to filter the second list.
int thelcm = 1
for(int i : listdivisor) {
thelcm = lcm(thelcm, i);
}
ArrayList<Integer> result = new ArrayList<>();
for(int j : listdiv) {
if( j % thelcm == 0 ) {
result.put(j);
}
}
Upvotes: 2
Reputation: 3409
Other way with java 8:
List<Integer> collect = listdiv.stream().filter(p ->
listdivisor.stream().allMatch(d -> p % d == 0)
).collect(Collectors.toList());
Or better performance with parallelStream()
:
List<Integer> collect = listdiv.parallelStream().filter(p ->
listdivisor.parallelStream().allMatch(d -> p % d == 0)
).collect(Collectors.toList());
Upvotes: 5
Reputation: 521073
Your error appears to be caused by that you were counting a dividend as being divisible by all divisors upon hitting the first matching divisor. Instead, you need to add logic which keeps track of all divisors and ensures that each one works with a given dividend.
System.out.println("final results are: ");
for (int i=0; i < listdiv.size(); i++) {
boolean isDivisible = true;
for (int c=0; c < listdivisor.size(); c++) {
if (listdiv.get(i) % listdivisor.get(c) != 0) {
isDivisible = false;
break;
}
}
if (isDivisible) {
System.out.println(listdiv.get(i));
}
}
Upvotes: 2
Reputation: 6218
In the below solution I continue the outer for loop when an element from the first list is not divisible to any in the second list. If no such case happens the println will get called.
outer:
for (int i = 0; i < listdiv.size(); i++) {
for (int c = 0; c < listdivisor.size(); c++) {
if (listdiv.get(i) % listdivisor.get(c) != 0) {
continue outer;
}
}
System.out.println("Found : " + listdiv.get(i));
}
This solution doesn't need any extra variables (such as a boolean to keep status of divisibility) and uses the less known loop labels
Upvotes: 2
Reputation: 393781
Your condition checks for values divisible by at least a single divisor, which is not what you want.
You need to check all the divisors before generating output :
for (int i = 0; i < listdiv.size(); i++) {
boolean divisible = true;
for (int c = 0; c < listdivisor.size() && divisible; c++) {
if (listdiv.get(i) % listdivisor.get(c) != 0) {
divisible = false;
}
}
if (divisible) {
System.out.println("final results are : " + listdiv.get(i));
}
}
Upvotes: 2