The below code prints all subsets, but I need of size greater than or equal to 2.
public static void printSubsets(char set[])
{
int n = set.length;
for (int i = 0; i < (1<<n); i++)
{
System.out.print("{ ");
for (int j = 0; j < n; j++)
if ((i & (1 << j)) >0 )
System.out.print(set[j] + " ");
System.out.println("}");
}
}
A subset of size 0 corresponds to i == 0. To eliminate the empty subset start at i = 1.
A subset of size 1 corresponds to i having exactly one bit set; or, equivalently, when it is a power of 2. A positive number i is a power of two if (i & (i - 1)) == 0.
for (int i = 1; i < (1<<n); i++) {
if ((i & (i - 1)) == 0) {
continue;
}
System.out.print("{ ");
for (int j = 0; j < n; j++) {
if ((i & (1 << j)) != 0) {
System.out.print(set[j] + " ");
}
}
System.out.println("}");
}
Alternatively, you could keep your original loop and simply insert this check:
if (Integer.bitCount(i) < 2) {
continue;
}
It's not as clever or efficient, but it is nice and readable.
I'm trying to reach following sequences of 1 and 0 for a three input system:
000
001
010
...
...
My current code didn't make it :-
for (int i = 0; i < possibleCombinations; i++) {
for (j = 0 ; j < 3; j++) {
if (j < 2 ){
k = j;
}
System.out.print(k + " ");
}
System.out.println();
}
How i can reach above result?
One line:
for (int i = 0; i < 8; i++) {
System.out.println(((i>>2)%2)+""+((i>>1)%2)+""+(i%2));
}
You can generalize this for n-channels of course.
int numChannels=3;
for (int i = 0; i < 2<<numChannels; i++) {
for(int j=numChannels-1; j>=0;j--){
System.out.print((i>>j)%2);
}
System.out.println();
}
Think it about using the periodicity of the occurence of zeroes and ones (first channel has pattern 00001111.., second 0011.., third 01..).
You can use bitmasks for this:
void generateCombinations(int n) {
for(int i = 0; i < (1 << n); i++) {
for(int j = n - 1; j >= 0; j--) {
if((i & (1 << j)) != 0) {
System.out.print(1);
} else {
System.out.print(0);
}
}
System.out.println();
}
}
So for n = 3 you will have 2 ^ n = 8 combinations. That's why the first for is 1 << n, this is the same as 2 ^ n.
For every number you check whether it's bits and print them.
(i & (1 << j)) != 0 - this checks if a bit is 1 or 0 on position j.
We have these situations:
n=2; -> 00,01,10,11
n=3;->000,001,010,011,100,101,110,111.
....
The algorithm is to just enumerate all numbers till 2^n - 1 in binary. For instance , n=2 :
0 in binary will be 00
1 in binary will be 01
2 in binary will be 10
3 in binary will be 11
For converting one integer number to binary string, you should use Integer.toBinaryString method.
Code:
static String print_binary(int n)
{
String binaryString=Integer.toBinaryString(n);
String additional=new String(new char[n-binaryString.length()]).replace("\0", "0");
if(binaryString.length() < n)
binaryString+=additional;
return binaryString;
}
static void Main(String args[]){
int possibleCombinations = 1<<LENGTH, i;
for(i = 0; i< possibleCombinations; i++)
System.out.println(print_binary(i));
}
Its easy enough to rotate numbers to the left. I would do the following:
int numberCount = 4;
int rotationCount = 2 * numberCount;
for(int i = 0; i < rotationCount; i++)
{
for(int j = 0; j < numberCount; j++)
{
System.out.print((i+j) % numberCount + " ");
}
System.out.println();
}
In this example the following would be printed:
0 1 2 3
1 2 3 0
2 3 0 1
3 0 1 2
0 1 2 3
1 2 3 0
2 3 0 1
3 0 1 2
How would you do the same thing, but rotating the numbers to the right?
The answer was obvious once I thought about it-- to move a number left, you add to it, so to move right, you subtract from it. I thought the formula would be significantly changed, so I was thinking of formulas that were much more complicated than the solution turned out to be.
// ensures mod is positive
int mod(int a, int b)
{ return (a%b+b)%b; }
int numberCount = 4;
int rotationCount = 2 * numberCount;
for(int i = 0; i < rotationCount; i++)
{
for(int j = 0; j < numberCount; j++)
{
System.out.print(mod((j-i), numberCount) + " ");
}
System.out.println();
}
int j = 0;
for (int i = 1; i < 4; i++)
{
if ((columnIndex + i) > 6 || this.isWinningCondition(columnIndex, i, j, colSlot, isRed))
{
break;
}
else
{
pieces++;
}
}
for (int i = -1; i > -4; i--)
{
if ((columnIndex + i) < 0 || this.isWinningCondition(columnIndex, i, j, colSlot, isRed))
{
break;
}
else
{
pieces++;
}
}
Basically, it is apart of a Connect4 program that searches for three in a row on the left and right side of a specific column (in this case, it is searching for horizontal wins), hence the incrementing (for the right side) and the decrementing (for the left side) for loops. Is there a way I can combine these for loops into one, so I don't have to repeat myself?
If your MaxValue ( 4 )is always the same for both for loop, you can always do :
for( int i = 1; i < 4; ++i)
{
//verify i version 1
int i2 = i * -1;
// verify i2 version 2
}
Try the mixed for loop.
for(int i = 0, j = 4; i <= 4 && j >=0; i ++, j --)
{
System.out.println(i + " " + j);
}
Output:
0 4
1 3
2 2
3 1
4 0
I'm trying to print out all possibilities of nCr, which are the combinations when order doesn't matter. So 5C1 there are 5 possibilities: 1 , 2, 3, 4, 5. 5C2 there are 10 possibilities: 1 2, 1 3, 1 4, 1 5, 2 3, 2 4, 2 5, 3 4, 3 5, 4 5.
I made functions that print what I want for r = 2, r = 3, and r = 4, and I sort of see the pattern, but I cant seem to make a working method for variable r:
public void printCombinationsChoose2(int n, int k) //for when k = 2
{
for (int a = 1; a < n; a++)
{
for (int b = a + 1; b <= n; b++)
{
System.out.println("" + a + " " + b);
}
}
}
public void printCombinationsChoose3(int n, int k) //for when k = 3
{
for (int a = 1; a < n - 1; a++)
{
for (int b = a + 1; b < n; b++)
{
for (int c = b + 1; c <= n; c++)
{
System.out.println("" + a + " " + b + " " + c);
}
}
}
}
public void printCombinationsChoose4(int n, int k) //for when k = 4
{
for (int a = 1; a < n - 2; a++)
{
for (int b = a + 1; b < n - 1; b++)
{
for (int c = b + 1; c < n; c++)
{
for (int d = c + 1; d <= n; d++)
{
System.out.println("" + a + " " + b + " " + c + " " + d);
}
}
}
}
}
public void printCombinations(int n, int k) //Doesn't work
{
int[] nums = new int[k];
for (int i = 1; i <= nums.length; i++)
nums[i - 1] = i;
int count = 1;
while (count <= k)
{
for (int a = nums[k - count]; a <= n; a++)
{
nums[k - count] = a;
for (int i = 0; i < nums.length; i++)
System.out.print("" + nums[i] + " ");
System.out.println();
}
count++;
}
}
So I think the layout of my last method is right, but I'm just not doing the right things, because when I call printCominbations(5, 2), it prints
1 2
1 3
1 4
1 5
1 5
2 5
3 5
4 5
5 5
when it should be what I said earlier for 5C2.
Edit
The last example was bad. This is a better one to illustrate what it's doing wrong: printCombinations(5, 3) gives this:
1 2 3
1 2 4
1 2 5
1 2 5
1 3 5
1 4 5
1 5 5
1 5 5
2 5 5
3 5 5
4 5 5
5 5 5
How do I get it to be:
1 2 3
1 2 4
1 2 5
1 3 4
1 3 5
1 4 5
2 3 4
2 3 5
2 4 5
3 4 5
How about this:
public class Test {
public static void main(final String[] args) {
print_nCr(7, 4);
}
public static final void print_nCr(final int n, final int r) {
int[] res = new int[r];
for (int i = 0; i < res.length; i++) {
res[i] = i + 1;
}
boolean done = false;
while (!done) {
System.out.println(Arrays.toString(res));
done = getNext(res, n, r);
}
}
/////////
public static final boolean getNext(final int[] num, final int n, final int r) {
int target = r - 1;
num[target]++;
if (num[target] > ((n - (r - target)) + 1)) {
// Carry the One
while (num[target] > ((n - (r - target)))) {
target--;
if (target < 0) {
break;
}
}
if (target < 0) {
return true;
}
num[target]++;
for (int i = target + 1; i < num.length; i++) {
num[i] = num[i - 1] + 1;
}
}
return false;
}
}
The key to this solution for me was to look at the problem as a numbering system and you want to increase a number by one and every time you reach an upper bound, you just carry the excess to the left one and ... You just need to implement the increasing algorithm correctly...
The first point where your code deviates from the expectation is here:
...
1 2 5
1 2 5 <-- first bad output
1 3 5
...
So ask yourself three things:
What should have happened in that line of code with the given state of the variables?
Why doesn't do my code exactly that?
What must be changed to achieve that?
The answer for the first part is like this:
It should have incremented the 2 to 3 and it should have set the following numbers to
4, 5, ... similar to the initialisation of nums.
The second and third part is your part again.
BTW: When you come back because you need more help, please explain in detail what you have deduced so far and clean up and shorten the question quite a bit.
OK... What is the solution when we know we need loops, but not the number of them?? RECURSION...
You need to use a recursive implementation. Have this in mind: ANYTIME, you need loops but the number of the nested loops can only be known at runtime, based on the specific parameters of the problem, you should use recursive methods... I'll give you some time to try it yourself, I'll be back to give you the final implementation...
I have done it in c++
#include <iostream>
using namespace std;
#define ARR_LIMIT 100
int arr[ARR_LIMIT];
void _ncr(int N,int R, int n,int r , int start )
{
if(r>0)
{
for(int i = start ; i <= start + (n-r); i++)
{
arr[R-r] = i;
_ncr(N,R,N-i, r-1, i+1 );
}
}
else
{
for(int i=0;i<R;i++)
{
cout << arr[i] << " ";
if(i==R-1)
cout<<"\n";
}
}
}
void ncr(int n,int r)
{
//Error checking of parameters
bool error = false;
if( n < 1)
{
error = true;
cout<< "ERROR : n should be greater 0 \n";
}
if( r < 1)
{
error = true;
cout<< "ERROR : r should be greater 0 \n";
}
if(r > n)
{
error = true;
cout<< "ERROR : n should be greater than or equal to r \n";
}
// end of Error checking of parameters
if(error)
return;
else
_ncr(n,r,n,r,1);
}
int main()
{
int n,r;
cout << "Enter n : ";
cin >> n;
cout << "Enter r : ";
cin >> r;
ncr(n,r);
return 0;
}
The layout of function printCombination() seems wrong. The while loop will iterate two times, for count = 1 and count = 2.
When count = 1, only values in nums[0][here] will change, since in this case k - count = 1.
Hence,
1,2
1,3
1,4 and
1,5.
And when count = 2, only values in nums[here][1] will change, since here k - count = 0.
Hence
1,5
2,5
3,5
4,5 and
5,5