Listing all the combinations of the elements of a set - java

Among elements of a set, I want to list all the 3-combinations of this set.
Is there a way to do it?
If it was a list;
for(int i=0; i<list.size()-2; i++)
for(int j=i+1; j<list.size()-1; j++)
for(int k=j+1; k<list.size(); k++)
System.out.println(list.get(i) + " " + list.get(j) + " " + list.get(k));
But how to do this with a set without converting it to a list?

Converting to a list and using the logic from your code would be my first choice. If you want to do it without converting to list, you can do it with iterators, like this:
Set<String> set = ...;
for (String a : set) {
boolean bGo = false;
for (String b : set) {
if (bGo) {
boolean cGo = false;
for (String c : set) {
if (cGo) {
System.out.println(a + " " + b + " " + c);
} else if (b.equals(c)) {
cGo = true;
}
}
} else if (a.equals(b)) {
bGo = true;
}
}
}
The logic above freely iterates the set in the outer loop. When it starts iterating the set in the first nested loop, it skips elements until the current element of the outer loop is found (i.e. until a.equals(b)). After that, it runs the third nested loop, which skips all data in the set until b, at which point it starts producing the combinations output.
Here is a demo on ideone.

Is your set a SortedSet ? If so, you can do this:
for (V x: mySet) {
for (V y: mySet.tailSet(x, false)) {
for (V z: mySet.tailSet(y, false)) {
System.out.println(x + " " + y + " " + z);
}
}
}

Related

Arraylist find the count of consecutive duplicate elements

I am trying to find the COUNT of repeated elements in an array list.
for example if array named "answerSheerPacketList" list contains values like {20,20,30,40,40,20,20,20},i need to show output like {20=2,30=1,40=2,20=3}.
Map<String, Integer> hm = new HashMap<String, Integer>();
for (String a : answerSheerPacketList) {
Integer j = hm.getinsAnswerSheetId(a);
hm.put(a, (j == null) ? 1 : j + 1);
}
// displaying the occurrence of elements in the arraylist
for(Map.Entry<String, Integer> val : hm.entrySet()){
System.out.println("Element " + val.getKey() + " "
"occurs" + ": " + val.getValue()+ " times");
}
when i executed above code i got output like {20=5,30=1,40=2} but i am trying to get a output like {20=2,30=1,40=2,20=3}.
A simple approach here would be to just iterate the arraylist once, and then keep tallies as we go along:
List<Integer> list = new ArrayList<>();
list.add(20);
list.add(20);
list.add(30);
list.add(40);
list.add(40);
list.add(20);
list.add(20);
list.add(20);
Integer curr = null;
int count = 0;
System.out.print("{");
for (int val : list) {
if (curr == null) {
curr = val;
count = 1;
}
else if (curr != val) {
System.out.print("(" + curr + ", " + count + ")");
curr = val;
count = 1;
}
else {
++count;
}
}
System.out.print("(" + curr + ", " + count + ")");
System.out.print("}");
{(20, 2)(30, 1)(40, 2)(20, 3)}
This is a classic problem of counting runs of consecutive elements in an array. I have renamed the array to arr in the code for brevity.
int run = 1;
for (int i = 0; i < n; ++i) { // n is the size of array
if (i + 1 < n && arr[i] == arr[i + 1]) {
run++; // increment run if consecutive elements are equal
} else {
System.out.println(arr[i] + "=" + run + ", ");
run = 1; // reset run if they are not equal
}
}
Performance-wise, this approach is aysmptotically optimal and runs in O(n), where n is the number of elements in the array.
Set<Integer> distinctSet = new HashSet<>(answerSheerPacketList);
HashSet<Integer,Integer> elementCountSet=new HashSet<>();
for (Integer element: distinctSet) {
elementCountSet.put(element,Collections.frequency(answerSheerPacketList, element));
}
What you need is basically frequency counting. The following code will do it with a single pass through your answerSheerPacketList array:
int[] answerSheerPacketList = // initialization
Map<Integer, Integer> frequencyCount = new LinkedHashMap<>();
for (int i : answerSheerPacketList) {
Integer key = Integer.valueOf(i);
if (frequencyCount.containsKey(key)) {
frequencyCount.put(key, Integer.valueOf(frequencyCount.get(key) + 1));
} else {
frequencyCount.put(key, Integer.valueOf(1));
}
}
for (Integer key : frequencyCount.keySet()) {
System.out.println("Element " + key + " occurs: " + frequencyCount.get(key)
+ " times");
}

creating tree in recursive function

I am trying to implement C4.5 algorithm in java. To get initial idea about C4.5 algorithm I took a python code as reference from this link. On this project there is file named mine.py which contains the following function.
def mine_c45(table, result):
""" An entry point for C45 algorithm.
_table_ - a dict representing data table in the following format:
{
'<column name>': [<column values>],
'<column name>': [<column values>],
...
}
_result_: a string representing a name of column indicating a result.
"""
col = max([(k, gain(table, k, result)) for k in table.keys() if k != result],
key=lambda x: x[1])[0]
tree = []
for subt in get_subtables(table, col):
v = subt[col][0]
if is_mono(subt[result]):
tree.append(['%s=%s' % (col, v),
'%s=%s' % (result, subt[result][0])])
else:
del subt[col]
tree.append(['%s=%s' % (col, v)] + mine_c45(subt, result))
return tree
By using the code in link I tried to convert this code in Java with some modification in it. I got succeeded getting the output which I want but the issue is I am not able to build a tree in recursive manner.
Here the code converted in java.
public void mineC45(Map<String, Attribute> table, String result) {
int maxGain = 0;
double[] gains = new double[table.size()];
int counter = 0;
SplitPoints point = null;
for (Entry<String, Attribute> entry : table.entrySet()) {
if (!entry.getKey().equals(result)) {
boolean nominal = entry.getValue().isNominal();
if (nominal)
gains[counter++] = Utils
.gain(table, entry.getKey(), result);
else {
point = Utils.numericGain(table, entry.getKey(), result);
gains[counter++] = point.getGain();
}
}
}
// calculate maximum gain column index
maxGain = Utils.getMax(gains);
List<String> keys = new ArrayList<String>(table.keySet());
String column = keys.get(maxGain);
if (table.get(column).isNominal()) {
for (Map<String, Attribute> subTable : Utils.createSubTables(table,
column)) {
String value = subTable.get(column).getValues().get(0);
if (Utils.isMono(subTable.get(result))) {
System.out.println("\t" + column + " = " + value + " "
+ result + " = "
+ subTable.get(result).getValues().get(0));
} else {
subTable.remove(column);
System.out.println(column + " = " + value + " ");
mineC45(subTable, result);
}
}
} else {
boolean first = true;
for (Map<String, Attribute> subTable : Utils.createNSubtables(
table, column, result, point.getSplitValue())) {
String sign = "";
sign = first ? "<=" : ">";
first = false;
if (Utils.isMono(subTable.get(result))) {
System.out.println("\t" + column + " "
+ point.getSplitValue().toString() + " " + result
+ " = " + subTable.get(result).getValues().get(0));
} else {
subTable.remove(column);
System.out.println(column + " "
+ point.getSplitValue().toString() + " ");
mineC45(subTable, result);
}
}
}
}
Here I created Map<String, Attribute> which represents a table. The string key represents column name and attribute stores the list of values. If any one can explain me how would I convert the output into tree so that I can form rules.

java-how to return multiple values in an array in switch case

I want to return all the array elements which satisfies the if statement in the code above.
Here the output is all the first element which satisfies the if condition.
switch(ch) {
case 1: {
g = prob1 * totoutcome;
flag = (int) g;
for(int i=0; i<9; i++) {
if(a1[0][0].equals(veh[i]) && flag > 0) {
flag--;
return(id[i] + " " + name[i] + " " + number[i] + " " + veh[i] + " " + color[i] + " " + type[i] + "\n");
}
}
break;
}
return means go back to the function that called you (and not go back and come back to return another) carrying the variable returned.
To achieve what you want.. you can create a list, add the elements to return to the list and return the list after ending your for loop.
ArrayList<String> aa = new ArrayList<String>();
ArrayList<String> ab = new ArrayList<String>();
ArrayList<String> ac = new ArrayList<String>();
ArrayList<String> ad = new ArrayList<String>();
ArrayList<String> ae = new ArrayList<String>();
for(.....)
{
if()
{
aa.add(name[i]);
ab.add(number[i]);
ac.add(veh[i]);
ad.add(color[i]);
ae.add(type[i]);
}
}
return(aa+ab+ac+ad+ae);

Check if a Vector contains a string always fails

in this code snippet:
s = ExtLibUtil.getCurrentSession();
Vector<String> groups = s.getUserGroupNameList();
if (debug) System.out.println("User groups are " + groups);
Boolean n = groups.contains("Notes_Admin");
if (debug) System.out.println("n = " + n);
if ( n ){
if (debug) System.out.println("Groups Contains Notes_Admin");
}else{
if (debug) System.out.println("Groups does not contain Notes_Admin");
}
the value for n always returns false even though I know that the Vector groups does in fact contain the value "Notes_Admin". I also tried groups.indexOF("Notes_Admin") with it always returning -1. I'm guessing that I have misdefined type somewhere in there but I've tried all the combinations that I can think of. The getUserGroupsNameList says that it returns a Vector.
The reason is that Session's getUserGroupNameList() doesn't return a list of Strings but a list of lotus.domino.local.Name.
Change your code to
import lotus.domino.local.Name;
...
Vector<Name> groups = s.getUserGroupNameList();
System.out.println("User groups are " + groups);
Boolean n = false;
for (Name group : groups) {
if (group.getCommon().equals("Notes_Admin")) {
n = true;
break;
}
}
System.out.println("n = " + n);

if / else "last resort" while in a loop

here is the scoop. I have a program that loops through an ArrayList and checks to see if the values are equal to an inputted keyword(inputArray[0])
I want to add a default action incase inputArray[0] is not equal to any of the values inside of the keyList
The else if is where I am having the problem. I want my loop to go through ALL of the values in keyList before it resorts the "last resort" - an else statement. Right now my problem is that in the first if statement it sees that inputArray[0] is not equal to keyList[x] and it goes to the else statement without going through another run of the loop.
As you can see, I tried using an else if statement, where if my loop's counter, x, is larger than the size of keyList then it will do the code inside, but that seemingly does not work. I also added continue;to the else statement to ensure that it is going through the loop, which according to the console, it is. (I know because of the System.out statement at the beginning of the loop.)
public static void wikiInit(ArrayList keyList, ArrayList nameList, ArrayList domainList, ArrayList softwareList, String[] inputArray, EntityPlayer player)
{
System.out.println("These are the current lists:");
System.out.println("Key List: " + keyList);
System.out.println("Name List: " + nameList);
System.out.println("Domain List: " + domainList);
System.out.println("Software List: " + softwareList);
// KEY PARSER
for(int x = 0; x < keyList.size(); x++)
{
System.out.println("Starting the loop");
if((keyList.get(x)).equals(inputArray[0]))
{
//getWikiName = wikiNameArray[x]
//getWikiDomain = wikiDomainArray[x]
//getWikiSoftware = wikiSoftwareArray[x]
StringBuilder hyperlinkBuilder = new StringBuilder();
for(int y = 1; y < inputArray.length; y++)
{
hyperlinkBuilder.append(inputArray[y] + " ");
}
if((softwareList.get(x)).equals("MEDIAWIKI"))
{
String hyperlink = "http://" + domainList.get(x) + "/index.php?search=" + hyperlinkBuilder.toString();
System.out.println("Searching for " + hyperlinkBuilder.toString() + " on the " + nameList.get(x));
player.addChatMessage("Searching for " + hyperlinkBuilder.toString() + " on the " + nameList.get(x));
BrowserHandler.browserInit(hyperlink.replace(" ", "+"), player);
System.out.println("Opening " + hyperlink.replace(" ", "+"));
break;
}
}
else if(x > keyList.size())
{//LAST RESORT
}
else
{
continue;
}
}
}
instead of loop use
if(keyList.contains(inputArray[0])){
int x = keyList.indexOf(inputArray[0]);
StringBuilder hyperlinkBuilder = new StringBuilder();
for(int y = 1; y < inputArray.length; y++)
...
}
else { // last resort code
}
If the default action should only happen after all elements have been checked, it should happen outside the loop. You can do this by using a variable to signal when this happens:
boolean found = false;
for(int x = 0; x < keyList.size(); x++)
{
System.out.println("Starting the loop");
if((keyList.get(x)).equals(inputArray[0]))
{
found = true;
...
}
}
if (!found) {
//The value was never found, do something special.
}
Having said that, in this case it would be much easier to use keyList.contains, as in bellabax's answer.
One way is to simply set a found variable to false before the loop and set it to true inside the loop if you find a key match.
Then after the loop:
if (!found)
complainBitterly();
Try using a boolean. Set it to false before the for loop, and if inputArray[0] is equal to keyList[x], set the boolean to true (in your if statement).
Then have an if statement after the for loop that will do your last case resort if the bool is still false.
The good news is you can make this a lot simpler by making 2 changes.
First, extract those 4 separate lists that you reference and combine them as a list of objects with fields for each list, 'ParameterTuplein the code. Second, you can track loop exit status with another variable,foundMediaWikiKey` in the code.
/**
* Not sure of a better name for this class, you'll need to look at in the larger sense.
* Also, in production you probably want to use getters for these, rather than final
* public and the constructor
*/
public class ParameterTuple {
public ParameterTuple(String key, String name, String domain, String software) {
this.key = key;
this.name = name;
this.domain = domain;
this.software = software;
}
public final String key;
public final String name;
public final String domain;
public final String software;
}
public static void wikiInit(ArrayList<ParameterTuple> paramList, String[] inputArray, EntityPlayer player) {
System.out.println("These are the current lists:");
System.out.println("List: " + paramList);
// Variable to keep track of how we exited the loop.
boolean foundMediaWikiKey = false;
// KEY PARSER
for(ParameterTuple param : paramList)
{
System.out.println("Starting the loop");
if(param.key.equals(inputArray[0])) {
StringBuilder hyperlinkBuilder = new StringBuilder();
for(int y = 1; y < inputArray.length; y++) {
hyperlinkBuilder.append(inputArray[y] + " ");
}
if(param.software.equals("MEDIAWIKI")) {
String hyperlink = "http://" + param.domain + "/index.php?search=" + hyperlinkBuilder.toString();
System.out.println("Searching for " + hyperlinkBuilder.toString() + " on the " + param.name;
player.addChatMessage("Searching for " + hyperlinkBuilder.toString() + " on the " + param.name;
BrowserHandler.browserInit(hyperlink.replace(" ", "+"), player);
System.out.println("Opening " + hyperlink.replace(" ", "+"));
// Keep track of how we exited the loop
foundMediaWikiKey = true;
break;
}
}
}
// When we exit, check to see how we did so.
if (!foundMediaWikiKey) {
// Last Resort
}
}
We usually do it like this where we search first and then put the code to handle the found one later.
I also lifted the one part out of the loop, since it didn't need to be in there. It could also go down in the "found" part of the code but I liked getting it out of the way to make the code more readable.
Also, the test for MEDIAWIKI is left in the loop (unlike my earlier version of this). Thanks to #paxdiablo for that. It is also a failing of some other answers here (as of right now).
StringBuilder hyperlinkBuilder = new StringBuilder(); // lift this out of the loop
for(int y = 1; y < inputArray.length; y++) {
hyperlinkBuilder.append(inputArray[y] + " ");
}
int found = -1;
for(int x = 0; x < keyList.size(); x++)
{
System.out.println("Starting the inside of the loop");
if((keyList.get(x)).equals(inputArray[0])) {
if((softwareList.get(x)).equals("MEDIAWIKI"))
found = x;
break;
}
}
}
if (found >= 0) {
int x = found;
//getWikiName = wikiNameArray[x]
//getWikiDomain = wikiDomainArray[x]
//getWikiSoftware = wikiSoftwareArray[x]
String hyperlink = "http://" + domainList.get(x) + "/index.php?search=" + hyperlinkBuilder.toString();
System.out.println("Searching for " + hyperlinkBuilder.toString() + " on the " + nameList.get(x));
player.addChatMessage("Searching for " + hyperlinkBuilder.toString() + " on the " + nameList.get(x));
BrowserHandler.browserInit(hyperlink.replace(" ", "+"), player);
System.out.println("Opening " + hyperlink.replace(" ", "+"));
} else {
//LAST RESORT ... fill in 'not found' code
}
I want my loop to go through ALL of the values in keyList before it
resorts the "last resort" - an else statement
else if(some condition)
{
if(x!=keylist.size()-1) // USE IT HERE
{ continue; }
//LAST RESORT
}

Categories