Permuting All Possible (0, 1) value arrays - c++

I am having writing an algorithm to generate all possible permutations of an array of this kind:
n = length
k = number of 1's in array
So this means if we have k 1's we will have n-k 0's in the array.
For example:
n = 5;
k = 3;
So obviously there are 5 choose 3 possible permutations for this array because
n!/(k!(n-k)!
5!/(3!2!) = (5*4)/2 = 10
possible values for the array
Here are all the values:
11100
11010
11001
10110
10101
10011
01110
01101
01011
00111
I am guessing i should use a recursive algorithms but i am just not seeing it. I am writing this algorithm in C++.
Any help would be appreciated!

Just start with 00111 and then use std::next_permutation to generate the rest:
#include <algorithm>
#include <iostream>
#include <string>
int main()
{
std::string s = "00111";
do
{
std::cout << s << '\n';
}
while (std::next_permutation(s.begin(), s.end()));
}
output:
00111
01011
01101
01110
10011
10101
10110
11001
11010
11100

You can split up the combinations into those starting with 1 (n-1, k-1) and those starting with 0 (n-1, k).
This is essentially the recursive formula for the choose function.

What you want is actually a combination since the 1's and 0's are indistinguishable and therefore their order doesn't matter (e.g. 1 1 1 vs 1 1 1).
I recently had to rewrite a combination function myself because my initial version was written recursively in a very straightforward way (pick an element, get all the combinations of the remaining array, insert the element in various places) and did not perform very well.
I searched StackOverflow and just seeing the pictures in this answer lit up the iconic lightbulb over my head.

If you want to do this recursively, observe that the set of permutations you want is equal to all the ones that start with "1", together with all the ones that start with "0". So in calculating (n,k), you will recurse on (n-1,k-1) and (n-1,k), with special cases where k = 0 and k = n.
This recursion is the reason that the binomial coefficients appear as the values in Pascal's triangle.

Homework and recursive algorithm? OK, here you go:
Base case:
You have two elements, name them "a" and "b" and produce the concatenations ab, then ba.
Step: If your second Element is longer than 1, split it up in first field/letter and the other part, and pass that recursively as parameters to the function itself.
That will work for any strings and arrays.

Its about 0-1 permutations, so probably its much more eficient to iteratively increment an integer and in case it has desired bits count, print out its binary representation.
Here a sketch:
void printAllBinaryPermutations(int k, int n)
{
int max = pow(2, n) - 1;
for(int i=0; i<=max;i++)
{
if(hasBitCountOf(i, k)) // i has k 1's?
{
printAsBinary(i, n);
}
}
}
bool hasBitCountOf(int v, int expectedBitCount)
{
int count = 0;
while(v>0 && count<= expectedBitCount)
{
int half = v >> 1;
if(half<<1 != v)
{
// v is odd
count++;
}
v = half;
}
return count==expectedBitCount;
}
void printAsBinary(int number, int strLen)
{
for(int i=strLen-1; i>=0; i--)
{
bool is0 = (number & pow(2,i)) == 0;
if (is0)
{
cout<<'0';
}
else
{
cout<<'1';
}
}
cout<<endl;
}

I am not sure this helps, plus it is just some weird pseudocode, but this should give you the desired ouput.
permutation (prefix, ones, zeros, cur) {
if (ones + zeros == 0) output(cur);
else {
if (cur != -1) prefix = concat(prefix,cur);
if (ones > 0) permutation(prefix, ones - 1, zeros, 1);
if (zeros > 0) permutation(prefix, ones, zeros - 1, 0);
}
}
permutation(empty, 3, 2, -1);
greetz
back2dos

Related

Finding the number of sub arrays that have a sum of K

I am trying to find the number of sub arrays that have a sum equal to k:
int subarraySum(vector<int>& nums, int k)
{
int start, end, curr_sum = 0, count = 0;
start = 0, end = 0;
while (end < (int)nums.size())
{
curr_sum = curr_sum + nums[end];
end++;
while (start < end && curr_sum >= k)
{
if (curr_sum == k)
count++;
curr_sum = curr_sum - nums[start];
start++;
}
}
return count;
}
The above code I have written, works for most cases, but fails for the following:
array = {-1, -1, 1} with k = 0
I have tried to add another while loop to iterate from the start and go up the array until it reaches the end:
int subarraySum(vector<int>& nums, int k)
{
int start, end, curr_sum = 0, count = 0;
start = 0, end = 0;
while (end < (int)nums.size())
{
curr_sum = curr_sum + nums[end];
end++;
while (start < end && curr_sum >= k)
{
if (curr_sum == k)
count++;
curr_sum = curr_sum - nums[start];
start++;
}
}
while (start < end)
{
if (curr_sum == k)
count++;
curr_sum = curr_sum - nums[start];
start++;
}
return count;
}
Why is this not working? I am sliding the window until the last element is reached, which should have found a sum equal to k? How can I solve this issue?
Unfortunately, you did not program a sliding window in the correct way. And a sliding window is not really a solution for this problem. One of your main issues is, that you do not move the start of the window based on the proper conditions. You always sum up and wait until the sum is greater than the search value.
This will not really work. Especially for your example -1, -1, 1. The running sum of this is: -1, -2, -1 and you do not see the 0, although it is there. You may have the idea to write while (start < end && curr_sum != k), but this will also not work, because you handle the start pointer not correctly.
Your approach will lead to the brute force solution that typically takes something like N*N loop operations, where N is the size of the array. This, because we need a double nested loop.
That will of course always work, but maybe very time-consuming, and, in the end, too slow.
Anyway. Let us implement that. We will start from each value in the std::vector and try out all sub arrays starting from the beginning value. We must evaluate all following values in the std::vector, because for example the last value could be a big negative number and bring down the sum again to the search value.
We could implement this for example like the following:
#include <iostream>
#include <vector>
using namespace std;
int subarraySum(vector<int>& numbers, int searchSumValue) {
// Here we will store the result
int resultingCount{};
// Iterate over all values in the array. So, use all different start values
for (std::size_t i{}; i < numbers.size(); ++i) {
// Here we stor the running sum of the elements in the vector
int sum{ numbers[i] };
// Check for trivial case. A one-element sub-array does already match the search value
if (sum == searchSumValue) ++resultingCount;
// Now we build all subarrays beginning with the start value
for (std::size_t k{ i + 1 }; k < numbers.size(); ++k) {
sum += numbers[k];
if (sum == searchSumValue) ++resultingCount;
}
}
return resultingCount;
}
int main() {
vector v{ -1,-1,1 };
std::cout << subarraySum(v, 0);
}
.
But, as said, the above is often too slow for big vectors and there is indeed a better solution available, which is based on a DP (dynamic programming) algorithm.
It uses so-called prefix sums, running sums, based on the running sum before the current evaluated value.
We need to show an example. Let's use a std::vector with 5 values {1,2,3,4,5}. And we want to look subarrays with a sum of 9.
We can “guess” that there are 2 subarrays: {2,3,4} and {4,5} that have a sum of 9.
Let us investigate further
Index 0 1 2 3 4
Value 1 2 3 4 5
We can now add a running sum and see, how much delta we have between the current evaluated element and the left neighbor or over-next neighbor and so on. And if we have a delta that is equal to our search value, then we must have a subarray building this sum.
Running Sum 1 3 6 10 15
Deltas of 2 3 4 5 against next left
Running sum 5 7 9 against next next left
9 12 against next next next left
Example {2,3,4}. If we evaluate the 4 with a running sum of 10, and subtract the search value 9, then we get the previous running sum 1. “1+9=10” all values are there.
Example {4,5}. If we evaluate the 5 with a running sum of 15, and subtract the search value 9, then we get the previous running sum = 6. “6+9=15” all values are there.
We can find all solutions using the same approach.
So, the only thing we need to do, is to subtract the search value from the current running sum and see, if we have this running sum already calculated before.
Like: “Search-Value” + “previously Calculated Sum” = “Current Running Sum”.
Or: “Current Running Sum” – “Search-Value” = “previously Calculated Sum”
Again, we need to do the subtraction and check, if we already calculated such a sum previously.
So, we need to store all previously calculated running sums. And, because such a sum may appear more than one, we need to find occurrences of equal running sums and count them.
It is very hard to digest, and you need to think a while to understand.
With the above wisdom, you can draft the below potential solution.
#include <iostream>
#include <vector>
#include <unordered_map>
int subarraySum(std::vector<int>& numbers, int searchSumValue) {
// Here we will store the result
int resultingSubarrayCount{};
// Here we will stor all running sums and how ofthen their value appeared
std::unordered_map<int, int> countOfRunningSums;
// Continuosly calculating the running sum
int runningSum{};
// And initialize the first value
countOfRunningSums[runningSum] = 1;
// Now iterate over all values in the vector
for (const int n : numbers) {
// Calculate the running sum
runningSum += n;
// Check, if we have the searched value already available
// And add the number of occurences to our resulting number of subarrays
resultingSubarrayCount += countOfRunningSums[runningSum - searchSumValue];
// Store the new running sum. Respectively. Add 1 to the counter, if the running sum was alreadyy existing
countOfRunningSums[runningSum]++;
}
return resultingSubarrayCount;
}
int main() {
std::vector v{ 1,2,3,4,5 };
std::cout << subarraySum(v, 9);
}

Can someone please explain this approach to me?

I am working my way through the USACO training website. I found this question which requires us to find the minimum number of swaps in a three valued sequence. Although I have solved the problem with a O(n^2) solution, I was intrigued to find out this faster O(n) approach. However, I am finding it rather difficult to understand, being a beginner.
Here is the detailed problem statement and the best approach.
In this task the possible key values are the integers 1, 2 and 3. The
required sorting order is non-decreasing. However, sorting has to be
accomplished by a sequence of exchange operations. An exchange
operation, defined by two position numbers p and q, exchanges the
elements in positions p and q.
You are given a sequence of key values. Write a program that computes
the minimal number of exchange operations that are necessary to make
the sequence sorted.
#include <fstream>
using namespace std;
int min (int a, int b) { return a < b ? a : b; }
int max (int a, int b) { return a > b ? a : b; }
int main () {
int s[1024];
int n;
int sc[4] = {0};
ifstream fin("sort3.in");
ofstream fout("sort3.out");
fin>>n;
for (int i = 0; i < n; i++) {
fin>>s[i];
sc[s[i]]++;
}
int s12 = 0, s13 = 0, s21 = 0, s31 = 0, s23 = 0, s32 = 0;
for (int i = 0; i < sc[1]; i++){
if (s[i] == 2) s12++;
if (s[i] == 3) s13++;
}
for (int i = sc[1]; i < sc[1]+sc[2]; i++){
if (s[i] == 1) s21++;
if (s[i] == 3) s23++;
}
for (int i = sc[1]+sc[2]; i < sc[1]+sc[2]+sc[3]; i++){
if (s[i] == 1) s31++;
if (s[i] == 2) s32++;
}
fout<<min(s12, s21)+min(s13, s31)+min(s23, s32) +
2*(max(s12, s21) - min(s12, s21))<<endl;
return 0;
}
I got the part where we are taking the minimum of overlaps of 1s, 2s and 3s in their respective desired ranges [0->c1, c1->c1+c2, c1+c2->n]. However, I don't really understand the formula of 2*max(s12, s21) - min(s12, s21). Also why are we not considering s13, s31, s23, and s32 in the formula. I would like you to explain this to me as I don't intend to leave any unbridged gaps in my training. Thanks in Advance!
If we approach the problem from the other side and work out how to perform the swaps in an example we can see where the formula for the number of swaps comes from.
If we start with:
22121 23331 1231
s12 is 3
s13 is 0
s21 is 1
s23 is 3
s31 is 2
s32 is 1
Then swapping 1 and 2 with 1 swap (min(s12, s21)) gives:
12121 23332 1231
There are no swaps between 1 and 3 (min(s13, s31)).
Then swapping 2 and 3 with 1 swap (min(s23, s32)) gives:
12121 22332 1331
Now we're left with no more direct swaps, we need to swap twice to get the remaining elements into the correct locations. There are 2 1s in the wrong place, 2s in the wrong place and 2 3s in the wrong place, the number for each number must always be the same. The initial number of misplaced 1s was given by max(s12, s21), we've fixed min(s12, s21) of those leaving max(s12, s21) - min(s12, s21) still to fix. We'll need to perform 2 swaps to fix each incorrect element.
First swap the 2s where 1s should be with the 1s that are where the 3s should be, this takes 2 swaps giving:
11111 22332 2332
Now we can directly swap the 2s and 3s taking another 2 swaps giving the final result:
11111 22222 3333
Adding up the total number of swaps gives:
min(s12, s21) + min(s13, s31) + min(s23, s32) + 2*(max(s12, s21) - min(s12, s21))

Array-Sum Operation

I have written this code using vector. Some case has been passed but others show timeout termination error.
The problem statement is:-
You have an identity permutation of N integers as an array initially. An identity permutation of N integers is [1,2,3,...N-1,N]. In this task, you have to perform M operations on the array and report the sum of the elements of the array after each operation.
The ith operation consists of an integer opi.
If the array contains opi, swap the first and last elements in the array.
Else, remove the last element of the array and push opi to the end of the array.
Input Format
The first line contains two space-separated integers N and M.
Then, M lines follow denoting the operations opi.
Constraints :
2<=N,M <= 10^5
1 <= op <= 5*10^5
Output Format
Print M lines, each containing a single integer denoting the answer to each of the M operations.
Sample Input 0
3 2
4
2
Sample Output 0
7
7
Explanation 0
Initially, the array is [1,2,3].
After the 1st operation, the array becomes[1,2,4] as opi = 4, as 4 is not present in the current array, we remove 3 and push 4 to the end of the array and hence, sum=7 .
After 2nd operation the array becomes [4,2,1] as opi = 2, as 2 is present in the current array, we swap 1 and 4 and hence, sum=7.
Here is my code:
#include <bits/stdc++.h>
using namespace std;
int main()
{
long int N,M,op,i,t=0;
vector<long int > g1;
cin>>N>>M;
if(N>=2 && M>=2) {
g1.reserve(N);
for(i = 1;i<=N;i++) {
g1.push_back(i);
}
while(M--) {
cin>>op;
auto it = find(g1.begin(), g1.end(), op);
if(it != (g1.end())) {
t = g1.front();
g1.front() = g1.back();
g1.back() = t;
cout<<accumulate(g1.begin(), g1.end(), 0);
cout<<endl;
}
else {
g1.back() = op;
cout<<accumulate(g1.begin(), g1.end(), 0);
cout<<endl;
}
}
}
return 0;
}
Please Suggest changes.
Looking carefully in question you will find that the operation are made only on the first and last element. So there is no need to involve a whole vector in it much less calculating the sum. we can calculate the whole sum of the elements except first and last by (n+1)(n-2)/2 and then we can manipulate the first and last element in the question. We can also shorten the search by using (1<op<n or op==first element or op == last element).
p.s. I am not sure it will work completely but it certainly is faster
my guess, let take N = 3, op = [4, 2]
N= [1,2,3]
sum = ((N-2) * (N+1)) / 2, it leave first and last element, give the sum of numbers between them.
we need to play with the first and last elements. it's big o(n).
function performOperations(N, op) {
let out = [];
let first = 1, last = N;
let sum = Math.ceil( ((N-2) * (N+1)) / 2);
for(let i =0;i<op.length;i++){
let not_between = !(op[i] >= 2 && op[i] <= N-1);
if( first!= op[i] && last != op[i] && not_between) {
last = op[i];
}else {
let t = first;
first = last;
last = t;
}
out.push(sum + first +last)
}
return out;
}

Trying to develop a sort of permutation algorithm

I want to develop the following put can't get it right.
I have a vector of N length. Each element can become 0 to K. Here N and K are given by the user. Now I'm trying to create a function in which I can walk through all possible solutions.
So let's say N is 4 and K = 2, then I want to loop through all possible permutations (?).
I want to fill a vector with 0000, test it then fill the vector with 1000, test it then 0100 etc.
It's important to know that 0100 and 0010 are different. As are 1100 and 0011 etc.
For extra notice this is what the loop should print (it really doesn't matter is 0001 or 1000 comes after 0000 etc as long as all different possible sequences come up).
0000, 1000, 0100, 0010, 0001, 1100, 1010, 1001, 1110, 1101, 0111, 0101, ....., 2012, 2211 etc..
I've tried a combination of for loops but can't really get it.
The application is in C++
Please help, tnx
I don't think permutation is the word you're looking for. You're talking about counting, so what you want to do is essentially increment the vector, just like if you were doing addition long hand as you did in first grade
First value 0 0 0 0
Add 1 1
=======
Second Value 0 0 0 1
Add 1 1
=======
Third Value 0 0 1 0
So you'd do somethign like this:
// returns false when you've seen all of the possible values for this vector
bool increment(std::vector<int> & vector, int k) {
for (int i = 0; i < vector.size(); ++i) {
int j = vector[i] + 1;
if (j <= k) {
vector[i] = j;
return true;
}
else vector[i] = 0;
// and carry a 1 by looping back again
}
return false;
}
This will return values in the following order, for k=1, assuming you start with the vector 0000: 1000, 0100, 1100, 0010, 1010, 0110, 1110, 0001, 1001, 0101, 1101, 0011, 1011, 0111, 1111.
(Picture counting in binary -- I've merely reversed each of the numbers to fit our ordinary view of a vector as going from left to right.)
Something like this comes to my mind
bool increase(vector<int> &d, int index, int k){
if(index == d.size()){
return false;
}
if(d[index] == k){
d[index] = 0;
increase(d, index+1, k);
}else{
d[index]++;
}
return true;
}
void printvector(vector<int> v){
cout<<" ";
for(int i=0;i<v.size();i++){
cout<<v[i];
}
}
int main(){
//int N, K predefined, and initialised.
vector<int> D(N, 0);
do{
printvector(d);
}while(increase(d, 0, K);
}
You might want a recursive solution to do it neatly.
Place the all the possibilities to the first element, and recursively invoke with decreasing size.
Pseudo code:
permutations(int n, int k, solution):
if (n==0): //base clause
print solution //or append to some extra data structure
return
for (i = 0 ; i <= k ; i++):
solution.append(i)
permutations(n-1,k,solution) //recursive call
solution.removeLast() //clean up environment before moving to the next possibility
invoke with permutations(n,k,v) - where n,k are your parameters and v is an empty std::vector
EDIT: C++ code:
void permutations(int n, int k,vector<int> &solution) {
if (n==0) { //base clause
print(solution);
return;
}
for (int i = 0 ; i <= k ; i++) {
solution.push_back(i);
permutations(n-1,k,solution); //recursive call
solution.pop_back(); //clean up environment before moving to the next possibility
}
}
a demo including the print() function can be found here

Unique numbers in C++ [closed]

It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 11 years ago.
I'm trying to efficiently list numbers between 1 and 100. However I have to get rid of numbers with same digits.
Example:
12 according to this rule is the same of 21
13 is 31
14 is 41
so the for loop it won't go over the same numbers.
I'm thinking a few tricks such as getting all the numbers from 1 to 100 and then deleting the found permutations of current number.
The reason I'm asking this because in large limits like 100000 it will fail.
Another example: 124 is equal to 142,241,214,412,421
You can apply recursion. Prototype of this function is then like:
print_digits(int num_of_remaining_digits,int start_from_digit, int current_number);
EDIT: for completion I present here my solution (i think it has better readbility than from Ben Voigt and ascending output order
void print_digits(int num_of_remaining_digits,int start_from_digit, int current_number)
{
if(num_of_remaining_digits == 0)
{
std::cout << current_number << std::endl;
return;
}
for(int i=start_from_digit;i<=9;i++)
{
print_digits(num_of_remaining_digits-1,i,10*current_number+i);
}
}
and here is testing code
http://ideone.com/Xm8Mv
How this works?
It is one of classics in recursion. First there is stopping condition. And then there is main loop.
Main loop where goes from start_from_digit because all generated digits will be in non decreasing order. For instance if current_number is 15 it will call print_digits whith
print_digits(num_of_remaining_digits-1,5,155)
print_digits(num_of_remaining_digits-1,6,156)
print_digits(num_of_remaining_digits-1,7,157)
print_digits(num_of_remaining_digits-1,8,158)
print_digits(num_of_remaining_digits-1,9,159)
In each call it will check if we reached end whit num_of_remaining_digits and if not will continue from digit that is pushed as start_from_digit (2nd param) using current_number
You're look for combination of some characters (0..9) with a certain length (100=2, 1000=3).
Take a look here Algorithm to return all combinations of k elements from n
I would write a class suiting your comparision needs by overloading the correct operators (from the top of my head that should be only less) and go with a std::set.
I would use a hash table, something like this
1) Derive a key from the number derived in such a way that digits with the same number have the same key (e.g. sum the digits, so "124" and "142" have the key 7, or take the product of the digits(+1), so "124" and "142" have the key 30 - have to +1 for the digit 0)
2) Put the numbers in a hash table indexed by its key
Now the test as to whether you already have a number with the same digits is limited to entities in the hash table with the same key. This algorithm requires linear storage and its performance depends on how good a key you can come up with.
#include <stdio.h>
size_t enum_canonical(char* begin, char* end, char min, char max)
{
if (begin == end) {
puts(begin);
putchar('\n');
return 1;
}
size_t result_count = 0;
--end;
for( *end = min; *end <= max; ++*end )
result_count += enum_canonical(begin, end, min, *end);
return result_count;
}
int main(void)
{
char buff[7];
printf("%d results\n", enum_canonical(buff, &(buff[6] = '\0'), '0', '9'));
}
Demo: http://ideone.com/BWGdg
First, observe that your rule excludes multiples of 11. (Why?)
Start by generating all 2-digit numbers with the first digit = 1.
Now, generate all 2-digit numbers with the first digit = 2, but don't generate any numbers that match numbers in the first list.
Repeat for 3, but don't generate any numbers from the first two lists.
Observe that, for any 2-digit number ab, for it to qualify, it must be the case that a < b, or you would have already generated the corresponding number ba.
In PASCAL, just because I'm feeling ornery:
var i:integer; j:integer;
begin
for i := 1 to 8 do
for j := i+1 to 9 do
println(i*10+j);
end;
ADDED A LITTLE LATER
Observe that the numbers you want to generate will always have their digits strictly monotonically increasing. For a number 2abc to qualify, observe that 2 < a < b < c. (Example: 2539 is a match for 2359 and should be rejected.)
Lets take 1 to 1000. Since there are 4 digits in 1000, I print 1 as 0001, so 0001, 0010, 0100, 1000 are same number as per my algorithm. Also 0120, 0012, 0210, 0102, 0201, 0021 are same numbers.
Here is the program:
int main()
{
int i=0, j=0, k=0;
while(i<=9)
{
int unique=(i*100 + j*10 + k);
printf("unique number : %3d\n", unique);
if(j==9 && k==9)
{
i++;
k=i;
j=i;
}
else if(k==9)
{
j++;
k=j;
}
else
k++;
}
}
Seems like it can be as simple as this:
list = {}
for (j = 1 to 100)
if (j is not excluded from list)
list += j;
Really, only the if condition is interesting: needs to examine all relevant properties of the list items.
Create a function which takes a string, and returns an array of strings with all the possible permutations of the characters in that string. It wouldn't be hard, but it would probably be easiest to make recursive. Though, easier said than done.
Once you have that function, and it returns the array, you simply go through the array and remove the indecies which share a common number with one in the array.
I'd use a set for the permutations of the digits of the number:
std::vector<int> list_unwanted = digit_permutations(number);
std::unordered_set<int> set_unwanted(begin(list_unwanted), end(list_unwanted));
Then loop from 0 to the limit, not adding unwanted numbers by checking if they're in the set set_unwanted:
std::vector<int> numbers;
numbers.reserve(limit - set_unwanted.count());
for (int i = 0; i < limit; ++i)
if (!set_unwanted.count(i))
If you have a set of digits, a whatever permutation of this set is not a valid solution, so first of all make a function to estabilish if a set of digits is a permutation of another set.
To get single digits you can divide by 10 recursively, until you get a zero value.
If you put all the digits in an array like [1,2,4], to check if antoher array is a permutation (you check it only if they have the same length) of antoher set:
bool permutation(int *a, int *b, int n) // n leading dimension
{
bool result=true, vector[n]={false};
for(int i=0;i<n;i++)
{
for(int j=0;j<n ;j++)
{
if(a[i]==b[j])
vector[i]=false;
}
}
for(int i=0;i<n && result;i++)
result=(vector[i]==true); // if vector[i] is false, result is false, is
// not a permutation and the loop ends
return result;
}
I haven't tested it, but I think it works, otherwise tell me.
As for putting all digits in an array, I think it's pretty easy.
Once generating all numbers, you check that a certain number is not a permutation of an already taken number.
Here's my idea, for each value put the digits of it in a set. Use that set as a key to another set that keeps track of which numbers have been used. In my case I use a bit field as a set for the digits, i.e. digit 0 is represented by a 1, digit 1 is represented by a 2 (2 by a 4 and so on). Too tired to explain, here's tha codez:
unsigned int get_digits(int v)
{
unsigned int rv = 0;
do
{
rv |= 1 << (v % 10);
v /= 10;
} while(v);
return rv;
}
void unique_ints(int n)
{
std::set<unsigned int> used_combinations;
for(int i = 0; i < n; ++i)
{
const unsigned int d = get_digits(i);
if(used_combinations.find(d) == used_combinations.end())
{
used_combinations.insert(d);
// cout or some other way to store the value
std::cout << i << std::endl;
}
}
}