I am writing a program for a class to first encrypt a string with a predetermined key. That part is done. Next part is where i have a problem or not a problem per se. its a question of redundancy. After this I am supposed to do a KPA on the string and the encrypted string to find the key.
Which is working but i am using like 15 nested for loops for the brute force. Is there another way to do this? without doing it recursively!
static String Key = null;
public static void main(String[] args) {
long startTime = System.nanoTime();
long startTime1 = System.currentTimeMillis();
int cntr = 0;
String key = "AAAAAAAAAAADDDAM";
String plaintext = "Secretfoemotherd";
StringBuilder cipher = new StringBuilder();
StringBuilder brutus = new StringBuilder();
byte[] ciphertext = encrypt(byteT(key), byteT(plaintext));
for (int i = 0; i < ciphertext.length; i++) {
cipher.append(ciphertext[i]);
}
while (true) {
char[] nkey = new char[16];
for (int i1 = 65; i1 < 122; i1++) {
nkey[0] = (char) i1;
for (int i2 = 65; i2 < 122; i2++) {
nkey[1] = (char) i2;
for (int i3 = 65; i3 < 122; i3++) {
nkey[2] = (char) i3;
for (int i4 = 65; i4 < 122; i4++) {
nkey[3] = (char) i4;
for (int i5 = 65; i5 < 122; i5++) {
nkey[4] = (char) i5;
for (int i6 = 65; i6 < 122; i6++) {
nkey[5] = (char) i6;
for (int i7 = 65; i7 < 122; i7++) {
nkey[6] = (char) i7;
for (int i8 = 65; i8 < 122; i8++) {
nkey[7] = (char) i8;
for (int i9 = 65; i9 < 122; i9++) {
nkey[8] = (char) i9;
for (int i10 = 65; i10 < 122; i10++) {
nkey[9] = (char) i10;
for (int i11 = 65; i11 < 122; i11++) {
nkey[10] = (char) i11;
for (int i12 = 65; i12 < 122; i12++) {
nkey[11] = (char) i12;
for (int i13 = 65; i13 < 122; i13++) {
nkey[12] = (char) i13;
for (int i14 = 65; i14 < 122; i14++) {
nkey[13] = (char) i14;
for (int i15 = 65; i15 < 122; i15++) {
nkey[14] = (char) i15;
for (int i16 = 65; i16 < 122; i16++) {
nkey[15] = (char) i16;
cntr++;
byte[] brutusCipher = Crack(
byteC(nkey),
byteT(plaintext));
for (int k = 0; k < brutusCipher.length; k++) {
brutus.append(brutusCipher[k]);
}
if (brutus
.toString()
.equals(cipher
.toString())) {
System.out
.println("found it");
System.out
.println("Key: "
+ Key);
System.out
.println("Brutus: "
+ brutus);
System.out
.println("i ran: "
+ cntr
+ "times");
long endTime = System
.nanoTime();
System.out
.println("time:"
+ (endTime - startTime)
+ " ns");
long endTime1 = System
.currentTimeMillis();
System.out
.println("Took "
+ (endTime1 - startTime1)
+ " ms");
return;
}
brutus.setLength(0);
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
public static byte[] byteT(String s) {
return s.getBytes();
}
public static byte[] byteC(char[] s) {
StringBuilder temp = new StringBuilder();
for (int i = 0; i < s.length; i++) {
temp.append(s[i]);
}
Key = temp.toString();
return temp.toString().getBytes();
}
public static byte[] encrypt(byte[] key, byte[] plaintext) {
byte[] d = new byte[key.length];
System.out.println(key.length);
for (int i = 0; i < key.length; i++) {
d[i] = (byte) (key[i] ^ plaintext[i]);
}
return d;
}
public static byte[] Crack(byte[] key, byte[] plaintext) {
byte[] n = new byte[key.length];
for (int i = 0; i < key.length; i++) {
n[i] = (byte) (key[i] ^ plaintext[i]);
}
return n;
}
}
Here is my suggestion on how you can improve your code:
char[] nkey = new char[16];
for (int i =0 ;i<16;++i) {
nkey[i] = 65;
}
while (true) {
//... do the stuff you do in the inner of the cycle
int index = 15;
nkey[index]++;
while (index >= 0 && nkey[index] >= 122) {
nkey[index] = 65;
index--;
if (index < 0) {
break;
}
nkey[index]++;
}
}
You can imagine what I do as representing what you iterate upon as a number in base 122-65 and adding one to it.
You could create a class like this (not tested):
class IncrementableCharArray {
private final char[] array;
IncrementableCharArray(int size) {
array = new char[size];
Arrays.fill(array, 'A');
}
boolean increment() {
//here logic to increment the array
int index = 0;
while(index < array.length && array[index] == 'z') index++;
if (index == array.length) return false;
array[index]++;
return true;
}
char[] get() { return array; }
}
The performance won't be better but it will be a little bit more readable. And you can use it like this:
IncrementableCharArray array = new IncrementableCharArray(16);
while(array.increment()) {
char[] nkey = array.get();
//your test here
}
Related
The following code is supposed to convert letters to numbers and give the sum, but ignore any letters that are uppercase.
Example:
The input abcde should return 15. The input abCde should return 12.
Any help is appreciated.
static int strScore(String str[], String s, int n) {
int score = 0, index=0;
for (int i = 0; i < n; i++) {
if (str[i] == s) {
for (int j = 0; j < s.length(); j++)
score += s.charAt(j) - 'a' + 1;
index = i + 1;
break;
}
}
score = score * index;
return score;
}
public static void main(String[] args) {
String str[] = { "abcde" };
String s = "abcde";
int n = str.length;
int score = strScore(str, s, n);
System.out.println( score);
}
Use Character.isLowerCase(...).
So this is what your strScore method should look like:
static int strScore(String str[], String s, int n) {
int score = 0, index = 0;
for (int i = 0; i < n; i++) {
if (str[i].equals(s)) {
for (int j = 0; j < s.length(); j++) {
char c = s.charAt(j);
if(Character.isLowerCase(c)) // <-- This is the important part
score += c - 'a' + 1;
}
index = i + 1;
break;
}
}
score = score * index;
return score;
}
As pointed out in the comments, there is no need for the str and therfore neither the n parameter. This is a better version:
static int strScore(String s) {
int score = 0;
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
if(Character.isLowerCase(c))
score += c - 'a' + 1;
}
return score;
}
There are two things to address:
You have used == to compare strings. You need to use .equals
You need to put a check like if(s.charAt(j)>= 'a' && s.charAt(j)<'z')
for (int i = 0; i < n; i++) {
if (str[i].equals(s)) {
for (int j = 0; j < s.length(); j++)
if(s.charAt(j)>= 'a' && s.charAt(j)<'z') {
score += s.charAt(j) - 'a' + 1;
You can avoid passing String str[] = { "abcde" }; which has one element which equals s
to The method. You can also avoid passing n which is an simply str.length():
static int strScore(String s) {
int score = 0, index = 0;
for (int i = 0; i < s.length(); i++) {
for (char c : s.toCharArray()) {
if(c >= 'a' && c <'z') { //alternatively if(Character.isLowerCase(c))
score += c - 'a' + 1;
}
}
index = i + 1;
break;
}
score = score * index;
return score;
}
I have to build Simplex Algorithm and its working but I want to allow user to input data, in method main I made few "for" loops where I put date into arrays, but that I put the same data in another arrays, (they have exactly the same data) I have no idea how to fix it.
When I try to make just one arrays for one type of date, it's crash.
[edit]
Yep, I update those Scanners (thanks guys)
And right now I have this error:
"Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 2
at simplex.Simplex$Modeler.(Simplex.java:224)
at simplex.Simplex.main(Simplex.java:196)"
package simplex;
import java.awt.List;
import java.util.ArrayList;
import java.util.Scanner;
public class Simplex {
private double[][] macierz; // macierz
private int LiczbaOgraniczen; // liczba ograniczen
private int LiczbaX; // liczba zmiennych "orginalnych"
private boolean MaxCzyMin;
private static final boolean MAX = true;
private static final boolean MIN = false;
private int[] baza; // baza[i] = basic variable corresponding to row i
public Simplex(double[][] macierz, int LiczbaOgraniczen, int numberOfOriginalVariable, boolean MaxCzyMin) {
this.MaxCzyMin = MaxCzyMin;
this.LiczbaOgraniczen = LiczbaOgraniczen;
this.LiczbaX = numberOfOriginalVariable;
this.macierz = macierz;
baza = new int[LiczbaOgraniczen];
for (int i = 0; i < LiczbaOgraniczen; i++)
baza[i] = LiczbaX + i;
Licz();
}
// Licz algorytm simples od startowych BFS
private void Licz() {
while (true) {
DrukujInteracje();
int q = 0;
// znajdz kolumne q wchodzącą do bazy
if (MaxCzyMin) {
q = ZnajdzIndexPoz(); //jesli szukamy max
} else {
q = ZnajdzIndexNeg(); //jesli szukamy min
}
if (q == -1){
break; // optimum
}
// znajdz rzad p wychodzący z bazy
int p = minRatioRule(q);
if (p == -1){
throw new ArithmeticException("BLAD");
}
//wiersz - kolumna
piwot(p, q);
// zaktualizuj baze
baza[p] = q;
}
}
// znajdowanie indexu niebazowej kolumny z najbardzoje pozytywnym kosztem
private int ZnajdzIndexPoz() {
int q = 0;
for (int j = 1; j < LiczbaOgraniczen + LiczbaX; j++)
if (macierz[LiczbaOgraniczen][j] > macierz[LiczbaOgraniczen][q])
q = j;
if (macierz[LiczbaOgraniczen][q] <= 0){
return -1; // optimum
} else {
return q;
}
}
// znajdowanie indexu niebazowej kolumny z najbardziej negatywnym kosztem
private int ZnajdzIndexNeg() {
int q = 0;
for (int j = 1; j < LiczbaOgraniczen + LiczbaX; j++)
if (macierz[LiczbaOgraniczen][j] < macierz[LiczbaOgraniczen][q])
q = j;
if (macierz[LiczbaOgraniczen][q] >= 0){
return -1; // optimum
} else {
return q;
}
}
// find row p using min ratio rule (-1 if no such row)
private int minRatioRule(int q) {
int p = -1;
for (int i = 0; i < LiczbaOgraniczen; i++) {
if (macierz[i][q] <= 0)
continue;
else if (p == -1)
p = i;
else if ((macierz[i][LiczbaOgraniczen
+ LiczbaX] / macierz[i][q]) < (macierz[p][LiczbaOgraniczen
+ LiczbaX] / macierz[p][q]))
p = i;
}
return p;
}
//zastosowanie metody Gauss-Jordan, aby doprowadzic macierz do postaci bazowej
private void piwot(int p, int q) {
for (int i = 0; i <= LiczbaOgraniczen; i++)
for (int j = 0; j <= LiczbaOgraniczen + LiczbaX; j++)
if (i != p && j != q)
macierz[i][j] -= macierz[p][j] * macierz[i][q] / macierz[p][q];
for (int i = 0; i <= LiczbaOgraniczen; i++)
if (i != p)
macierz[i][q] = 0.0;
for (int j = 0; j <= LiczbaOgraniczen + LiczbaX; j++)
if (j != q)
macierz[p][j] /= macierz[p][q];
macierz[p][q] = 1.0;
}
// Metoda zwraca wartosc funkcji celu
public double WartoscFunkcjiCelu() {
return -macierz[LiczbaOgraniczen][LiczbaOgraniczen + LiczbaX];
}
// metoda zwaraca wartosc x-ow
public double[] WyliczX() {
double[] x = new double[LiczbaX];
for (int i = 0; i < LiczbaOgraniczen; i++)
if (baza[i] < LiczbaX)
x[baza[i]] = macierz[i][LiczbaOgraniczen + LiczbaX];
return x;
}
// drukuj macierz => drukuj tabele
public void DrukujInteracje() {
System.out.println("Liczba Ograniczen = " + LiczbaOgraniczen);
System.out.println("Liczba zmiennych 'orginalnych' = " + LiczbaX);
for (int i = 0; i <= LiczbaOgraniczen; i++) {
for (int j = 0; j <= LiczbaOgraniczen
+ LiczbaX; j++) {
System.out.printf("%7.2f ", macierz[i][j]);
}
System.out.println();
}
System.out.println("Funkcja celu = " + WartoscFunkcjiCelu());
for (int i = 0; i < LiczbaOgraniczen; i++)
if (baza[i] < LiczbaX)
System.out.println("x_"
+ baza[i]
+ " = "
+ macierz[i][LiczbaOgraniczen + LiczbaX]);
System.out.println();
}
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
System.out.println("Podaj ilosc x");
int iloscX = scan.nextInt();
double[] WspolczynnikiFunkcjiCelu = new double[iloscX + 1];
for(int ggg = 0; ggg < iloscX; ggg++){
System.out.println("Podaj x" + ggg);
WspolczynnikiFunkcjiCelu[ggg] =scan.nextDouble();
}
System.out.println("Podaj ilosc ograniczen");
int iloscOgraniczen = scan.nextInt();
double[][] LewaStronaOgraniczen = new double[iloscOgraniczen][iloscX];
double[] PrawaStronaOgraniczen = new double[iloscOgraniczen + 1];
Znaki[] OperatorOgraniczen = new Znaki [iloscOgraniczen + 1];
for(int ggh = 0;ggh <iloscOgraniczen; ggh++){
System.out.println("Podaj znak ograniczenia (lessThan - equal - greatherThan ");
OperatorOgraniczen[ggh] = Znaki.valueOf(scan.next());
System.out.println("Podaj prawa strone ograniczenia");
PrawaStronaOgraniczen[ggh] = scan.nextDouble();
for(int haha = 0; haha < iloscX; haha++){
System.out.println("Lewa strona: Podaj wspolczynnik przy x" + haha);
LewaStronaOgraniczen[ggh][haha] =scan.nextDouble();
}
}
//double[] WspolczynnikiFunkcjiCelu = {Xsy[0], Xsy[1]};
// double[][] LewaStronaOgraniczen = {
// { TablicaTablic[0][0], TablicaTablic[0][1] }, { TablicaTablic[1][0], TablicaTablic[1][1] }, { TablicaTablic[2][0], TablicaTablic[2][1] }, { TablicaTablic[3][0], TablicaTablic[3][1] } };
//Znaki[] OperatorOgraniczen = { TablicaOgraniczen[0], TablicaOgraniczen[1], TablicaOgraniczen[2], TablicaOgraniczen[3] };
//double[] PrawaStronaOgraniczen = {TablicaPrawejStrony[0],TablicaPrawejStrony[1],TablicaPrawejStrony[2],TablicaPrawejStrony[3]};
Modeler model = new Modeler(LewaStronaOgraniczen, PrawaStronaOgraniczen, OperatorOgraniczen, WspolczynnikiFunkcjiCelu);
Simplex simplex = new Simplex(model.getmacierz(),
model.getLiczbaOgraniczen(),
model.getLiczbaX(), MAX);
double[] x = simplex.WyliczX();
for (int i = 0; i < x.length; i++)
System.out.println("x[" + i + "] = " + x[i]);
System.out.println("Rozwiazanie optymalne: " + simplex.WartoscFunkcjiCelu());
}
//zbior mozliwych znakow ograniczajacych
private enum Znaki {
lessThan, equal, greatherThan
}
public static class Modeler {
private double[][] a; // macierz
private int LiczbaOgraniczen; // Liczba Ograniczen
private int LiczbaX; // Liczba x w funkcji celu
public Modeler(double[][] LewaStronaOgraniczen,double[] PrawaStronaOgraniczen, Znaki[] OperatorOgraniczen, double[] WspolczynnikiFunkcjiCelu) {
LiczbaOgraniczen = PrawaStronaOgraniczen.length;
LiczbaX = WspolczynnikiFunkcjiCelu.length;
a = new double[LiczbaOgraniczen + 1][LiczbaX + LiczbaOgraniczen + 1];
for (int i = 0; i < LiczbaOgraniczen; i++) {
for (int j = 0; j < LiczbaX; j++) {
a[i][j] = LewaStronaOgraniczen[i][j];
}
}
for (int i = 0; i < LiczbaOgraniczen; i++)
a[i][LiczbaOgraniczen + LiczbaX] = PrawaStronaOgraniczen[i];
for (int i = 0; i < LiczbaOgraniczen; i++) {
int slack = 0;
switch (OperatorOgraniczen[i]) {
case greatherThan:
slack = -1;
break;
case lessThan:
slack = 1;
break;
default:
}
a[i][LiczbaX + i] = slack;
}
for (int j = 0; j < LiczbaX; j++)
a[LiczbaOgraniczen][j] = WspolczynnikiFunkcjiCelu[j];
}
public double[][] getmacierz() {
return a;
}
public int getLiczbaOgraniczen() {
return LiczbaOgraniczen;
}
public int getLiczbaX() {
return LiczbaX;
}
}
}
why have you so many scanners? Try use only one. Declare and initialize it at the beginning main method.
I want to print the statement System.out.println(sb.append(ss));
Only the last time I tried to take it out of the for loop but the result is wrong.
public static String constatmentvertBinaryStringToString(String string) {
StringBuilder sb = new StringBuilder();
char[] chars = string.toCharArray();
String ss = null;
//for each character
for (int j = 0; j < chars.length; j += 8) {
int idx = 0;
int sum = 0;
//for each bit in reverse
for (int i = 7; i >= 0; i--) {
if (chars[i + j] == '1') {
sum += 1 << idx;
}
idx++;
}
System.out.println(sum); //debug
int div = sum / 4;
System.out.println(div);
System.out.println((char) div);
int rem = sum % 4;
System.out.println(rem);
ss = (char) div + "" + rem;
System.out.println(sb.append(ss));
}
return sb.toString();
}
Put System.out.println(sb.append(ss)); out of the loop:
public static String constatment vertBinaryStringToString(String string){
StringBuilder sb = new StringBuilder();
char[] chars = string.toCharArray();
String ss=null;
//for each character
for (int j = 0; j < chars.length; j+=8) {
int idx = 0;
int sum =0;
//for each bit in reverse
for (int i = 7; i>= 0; i--) {
if (chars[i+j] == '1') {
sum += 1 << idx;
}
idx++;
}
System.out.println(sum); //debug
int div=sum/4;
System.out.println(div);
System.out.println((char)div);
int rem=sum%4;
System.out.println(rem);
ss=(char)div+""+rem;
}
System.out.println(sb.append(ss));
return sb.toString();
}
Because System.out.println(sb.append(ss)); contains a call to sb.append(ss)); taking the statement out of the for loop will have a different result than the one expected.
You should keep sb.append(ss); inside the loop and add System.out.println(sb) outside the loop.
public static String constatmentvertBinaryStringToString(String string) {
StringBuilder sb = new StringBuilder();
char[] chars = string.toCharArray();
String ss = null;
//for each character
for (int j = 0; j < chars.length; j += 8) {
int idx = 0;
int sum = 0;
//for each bit in reverse
for (int i = 7; i >= 0; i--) {
if (chars[i + j] == '1') {
sum += 1 << idx;
}
idx++;
}
System.out.println(sum); //debug
int div = sum / 4;
System.out.println(div);
System.out.println((char) div);
int rem = sum % 4;
System.out.println(rem);
ss = (char) div + "" + rem;
sb.append(ss);
}
System.out.println(sb);
return sb.toString();
}
In 'eightbitfulladder' function,I am trying to complement the sumno which is the result of addition of a positive number and a negative number.I found out the number it is sending in the 'convertobyte' function is different from the sumno computed. This is wierd. Can someone explain me what is happening.
import static java.lang.Math.pow;
public class CAModifiedBoothsMultiplier {
public byte byteArrayTobyte(byte[] b) {
byte value = 0;
for (byte i = 0; i < 8; i++) {
value += (b[i] * (pow(2, i)));
}
return value;
}
public byte[] twosComplement(byte x) {
byte y = (byte) (~x + 1);
byte mask = 1;
mask = (byte) (mask << 7);
byte num[] = new byte[10];
byte i = 0, num1 = 0;
for (i = 0; i < 8; i++) {
if ((y & mask) == 0)
num1 = 0;
else
num1 = 1;
y = (byte) (y << 1);
num[i] = num1;
}
return num;
}
public byte[] saveByte(byte number) {
byte mask = 1;
mask = (byte) (mask << 7);
byte num[] = new byte[10];
byte num1 = 0;
byte i = 0;
for (i = 0; i < 8; i++) {
if ((number & mask) == 0)
num1 = 0;
else
num1 = 1;
number = (byte) (number << 1);
num[i] = num1;
}
return num;
}
public byte[] eightbitFullAdder(byte a, byte b, byte cin) {
byte sum = 0, temp1 = 0, cout = 0;
byte sumno[] = new byte[10];
byte ain[] = saveByte(a);
byte bin[] = new byte[10];
if (cin == 1) {
bin = twosComplement(b);
cin = 0;
} else {
bin = saveByte(b);
}
System.out.print("The number entered is, a :");
for (int i = 0; i < 8; i++) {
System.out.print(ain[i]);
}
System.out.println("\n");
System.out.print("The number entered is, b :");
for (int i = 0; i < 8; i++) {
System.out.print(bin[i]);
}
System.out.println("\n");
for (int i = 7; i >= 0; i--) {
temp1 = (byte) (ain[i] ^ bin[i]);
sum = (byte) (temp1 ^ cin);
sumno[i] = sum;
cout = (byte) ((ain[i] & bin[i]) | (cin & temp1));
if (i != 0)
cin = cout;
}
for (int i = 0; i < 8; i++) {
System.out.print(sumno[i]);
}
System.out.println("\n");
if (sumno[0] == 1) {
byte[] sumnocomp = new byte[10];
byte temp2 = 0;
temp2 = byteArrayTobyte(sumno);
System.out.print(temp2);
sumnocomp = twosComplement(temp2);
return sumnocomp;
} else {
return sumno;
}
}
public static void main(String args[]) {
CAModifiedBoothsMultiplier mbm = new CAModifiedBoothsMultiplier();
byte x = 5;
byte complementedno[];
complementedno = mbm.twosComplement(x);
for (int i = 1; i <= 8; i++)
System.out.print(complementedno[i]);
System.out.println("\n");
byte a = 6, b = 8, cin = 1;
byte fulladder[] = mbm.eightbitFullAdder(a, b, cin);
System.out.print("The sum of numbers entered is :");
for (int i = 0; i < 8; i++) {
System.out.print(fulladder[i]);
}
System.out.println("\n");
}
}
With n=5 and k=3 the following loop will do it
List<String> l=new ArrayList<String>();
l.add("A");l.add("B");l.add("C");l.add("D");l.add("E");
int broadcastSize = (int) Math.pow(2, l.size());
for (int i = 1; i < broadcastSize; i++) {
StringBuffer buffer = new StringBuffer(50);
int mask = i;
int j = 0;
int size=0;
System.out.println();
while (mask > 0) {
if ((mask & 1) == 1) {
System.out.println(".. "+mask);
buffer.append(l.get(j));
if (++size>3){
buffer = new StringBuffer(50);
break;
}
}
System.out.println(" "+mask);
mask >>= 1;
j++;
}
if (buffer.length()>0)
System.out.println(buffer.toString());
}
but it's not efficient I would like to do it with Banker's sequence and thus explore first singletons, then pairs, then 3-tuple and stop.
I did not find a way do that, but at least this loop should be more efficient:
List<String> l=new ArrayList<String>();
l.add("A");l.add("B");l.add("C");l.add("D");l.add("E");
int broadcastSize = (int) Math.pow(2, l.size());
for (int i = 1; i < broadcastSize; i++) {
StringBuffer buffer = new StringBuffer(50);
int mask = i;
int j = 0;
if (StringUtils.countMatches(Integer.toBinaryString(i), "1") < 4){
while (mask > 0) {
if ((mask & 1) == 1) {
buffer.append(l.get(j));
}
mask >>= 1;
j++;
}
if (buffer.length()>0)
System.out.println(buffer.toString());
}
}
there is also: but k embedded loops looks ugly
//singleton
for (int i = 0; i < l.size(); i++) {
System.out.println(l.get(i));
}
//pairs
for (int i = 0; i < l.size(); i++) {
for (int j = i+1; j < l.size(); j++) {
System.out.println(l.get(i)+l.get(j));
}
}
//3-tuple
for (int i = 0; i < l.size(); i++) {
for (int j = i+1; j < l.size(); j++) {
for (int k = j+1; k < l.size(); k++) {
System.out.println(l.get(i)+l.get(j)+l.get(k));
}
}
}
//...
// k-tuple
This technique is called Gosper's hack. It only works for n <= 32 because it uses the bits of an int, but you can increase it to 64 if you use a long.
int nextCombo(int x) {
// moves to the next combination with the same number of 1 bits
int u = x & (-x);
int v = u + x;
return v + (((v ^ x) / u) >> 2);
}
...
for (int x = (1 << k) - 1; (x >>> n) == 0; x = nextCombo(x)) {
System.out.println(Integer.toBinaryString(x));
}
For n = 5 and k = 3, this prints
111
1011
1101
1110
10011
10101
10110
11001
11010
11100
exactly as you'd expect.
this should be the most efficient way, even if k embedded loops looks ugly
//singleton
for (int i = 0; i < l.size(); i++) {
System.out.println(l.get(i));
}
//pairs
for (int i = 0; i < l.size(); i++) {
for (int j = i+1; j < l.size(); j++) {
System.out.println(l.get(i)+l.get(j));
}
}
//3-tuple
for (int i = 0; i < l.size(); i++) {
for (int j = i+1; j < l.size(); j++) {
for (int k = j+1; k < l.size(); k++) {
System.out.println(l.get(i)+l.get(j)+l.get(k));
}
}
}
// ...
//k-tuple
Apache commons has iterators for subsets of size k, and for permutations.
Here is an iterator that iterates through 1-k tuples of an n-tuple, that combines the two:
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import org.apache.commons.collections4.iterators.PermutationIterator;
import org.apache.commons.math3.util.Combinations;
public class AllTuplesUpToKIterator implements Iterator<List<Integer>> {
private Iterator<int[]> combinationIterator;
private PermutationIterator<Integer> permutationIterator;
int i;
int k;
int n;
public AllTuplesUpToKIterator(int n, int k) {
this.i = 1;
this.k = k;
this.n = n;
combinationIterator = new Combinations(n, 1).iterator();
permutationIterator = new PermutationIterator<Integer>(intArrayToIntegerList(combinationIterator.next()));
}
#Override
public boolean hasNext() {
if (permutationIterator.hasNext()) {
return true;
} else if (combinationIterator.hasNext()) {
return true;
} else if (i<k) {
return true;
} else {
return false;
}
}
#Override
public List<Integer> next() {
if (!permutationIterator.hasNext()) {
if (!combinationIterator.hasNext()) {
i++;
combinationIterator = new Combinations(n, i).iterator();
}
permutationIterator = new PermutationIterator<Integer>(intArrayToIntegerList(combinationIterator.next()));
}
return permutationIterator.next();
}
#Override
public void remove() {
// TODO Auto-generated method stub
}
public static List<Integer> intArrayToIntegerList(int[] arr) {
List<Integer> result = new ArrayList<Integer>();
for (int i=0; i< arr.length; i++) {
result.add(arr[i]);
}
return result;
}
public static void main(String[] args) {
int n = 4;
int k = 2;
for (AllTuplesUpToKIterator iter= new AllTuplesUpToKIterator(n, k); iter.hasNext();) {
System.out.println(iter.next());
}
}
}