Reputation: 49
I am making combinations of 3 different values that give a requested sum, in this case the requested sum is 0.
I can't find a way to iterate through a TreeSet with 2 for loops in order to receive a set of 3 numbers without repeating that solution. The third number I would like to obtain by using the contains method of the TreeSet.
This is my code so far, it gives good solutions but it repeats them.
import java.util.*;
public class Tree
{
public static void main(String[] args)
{
TreeSet<Integer> ts = new TreeSet<>();
int array[] = {-5, 1, -4, 6, 2, 3, 9, 5};
int sumSearching = 0;
int valueSearching;
for(int i = 0; i < array.length; i++)
ts.add(array[i]);
for(Integer i: ts)
{
for(Integer j : ts)
{
if(i != j)
{
valueSearching = sumSearching - (i + j);
if(valueSearching != i && valueSearching != j)
if(ts.contains(valueSearching))
System.out.println("Solution: "
+ i + ", " + j + ", " + valueSearching);
}
}
}
}
}
Thanks for any kind of help!
Upvotes: 1
Views: 64
Reputation: 109577
Go for j > i, removing one symmetry.
This does not exclude doubles on {i, j, valueSearching} as negative numbers are involved. So one needs to maintain all solutions.
Set<Set<Integer>> solutions = new HashSet<>();
for (int i: ts)
{
for (int j : ts.tailSet(i, false))
{
valueSearching = sumSearching - (i + j);
if (valueSearching != i && valueSearching != j)
if (ts.contains(valueSearching)) {
Set<Integer> solution = new TreeSet<>();
Collections.addAll(solution, i, j, valueSearching);
if (solutions.add(solution)) {
System.out.println("Solution: "
+ i + ", " + j + ", " + valueSearching);
}
}
}
}
Also note: i != j
for Integers should better be i.intValue() != j.intValue()
as only in the range -128 .. 127 the object for a number is unique.
Here simply the int
primitive type is used, which is more appropriate. Also Set.tailSet(value, exclusive)
gives the set after the value. Using an Iterator probably would be more efficient.
Upvotes: 1
Reputation: 1028
To exclude repeating solutions, it's enough to include only those triples which are in ascending order.
So, try changing this line:
if (valueSearching != i && valueSearching != j)
to:
if (i < j && j < valueSearching)
Upvotes: 0
Reputation: 44170
Implement a reversable pair class:
class ReversablePair<T>
{
private final T first;
private final T second;
ReversablePair(final T first, final T second)
{
this.first = first;
this.second = second;
}
// Some getters...
@Override
public boolean equals(final Object o)
{
if (o == null) return false;
if (!(o instanceof ReversablePair)) return false;
final ReversablePair that = (ReversablePair) o;
return (this.first.equals(that.first) && this.second.equals(that.second))
|| (this.first.equals(that.second) && this.second.equals(that.first));
}
@Override
public int hashCode()
{
return first.hashCode() + second.hashCode();
}
}
Then maintain a set of previous solutions:
Set<ReversablePair<Integer>> previousSolutions = new HashSet();
And check the set before printing:
if (! previousSolutions.contains(new ReversablePair<>(i, j))
{
// whatever
}
Upvotes: 0