Generate all sequences of bits within Hamming distance t - c++

Given a vector of bits v, compute the collection of bits that have Hamming distance 1 with v, then with distance 2, up to an input parameter t.
So for
011 I should get
~~~
111
001
010
~~~ -> 3 choose 1 in number
101
000
110
~~~ -> 3 choose 2
100
~~~ -> 3 choose 3
How to efficiently compute this? The vector won't be always of dimension 3, e.g. it could be 6. This will run numerous time in my real code, so some efficiency would be welcome as well (even by paying more memory).
My attempt:
#include <iostream>
#include <vector>
void print(const std::vector<char>& v, const int idx, const char new_bit)
{
for(size_t i = 0; i < v.size(); ++i)
if(i != idx)
std::cout << (int)v[i] << " ";
else
std::cout << (int)new_bit << " ";
std::cout << std::endl;
}
void find_near_hamming_dist(const std::vector<char>& v, const int t)
{
// if t == 1
for(size_t i = 0; i < v.size(); ++i)
{
print(v, i, v[i] ^ 1);
}
// I would like to produce t == 2
// only after ALL the t == 1 results are reported
/* how to? */
}
int main()
{
std::vector<char> v = {0, 1, 1};
find_near_hamming_dist(v, 1);
return 0;
}
Output:
MacBook-Pro:hammingDist gsamaras$ g++ -Wall -std=c++0x hammingDist.cpp -o ham
MacBook-Pro:hammingDist gsamaras$ ./ham
1 1 1
0 0 1
0 1 0

First: There is a bijection between hamming dist k bit-vectors and subsets (of n aka v.size()) of kardinality k (the set of indices with changed bits). Hence, I'd enumerate the subsets of changed indices instead. A quick glance at the SO history shows this reference. You'd have to keep track of the correct cardinalitites of course.
Considering efficiency is probably pointless, since the solution to your problem is exponential anyways.

If Hamming distance h(u, v) = k, then u^v has exactly k bits set. In other words, computing u ^ m over all masks m with k bits set gives all words with the desired Hamming distance. Notice that such set of mask does not depend on u.
That is, for n and t reasonably small, precompute sets of masks with k bits set, for all k in 1,t, and iterate over these sets as required.
If you don't have enough memory, you may generate the k-bit patterns on the fly. See this discussion for details.

#include <stdio.h>
#include <stdint.h>
#include <string.h>
void magic(char* str, int i, int changesLeft) {
if (changesLeft == 0) {
printf("%s\n", str);
return;
}
if (i < 0) return;
// flip current bit
str[i] = str[i] == '0' ? '1' : '0';
magic(str, i-1, changesLeft-1);
// or don't flip it (flip it again to undo)
str[i] = str[i] == '0' ? '1' : '0';
magic(str, i-1, changesLeft);
}
int main(void) {
char str[] = "011";
printf("%s\n", str);
size_t len = strlen(str);
size_t maxDistance = len;
for (size_t i = 1 ; i <= maxDistance ; ++i) {
printf("Computing for distance %d\n", i);
magic(str, len-1, i);
printf("----------------\n");
}
return 0;
}
Output:
MacBook-Pro:hammingDist gsamaras$ nano kastrinis.cpp
MacBook-Pro:hammingDist gsamaras$ g++ -Wall kastrinis.cpp
MacBook-Pro:hammingDist gsamaras$ ./a.out
011
Computing for distance 1
010
001
111
----------------
Computing for distance 2
000
110
101
----------------
Computing for distance 3
100
----------------

In response to Kastrinis' answer, I would like to verify that this can be extended to my basis example, like this:
#include <iostream>
#include <vector>
void print(std::vector<char>&v)
{
for (auto i = v.begin(); i != v.end(); ++i)
std::cout << (int)*i;
std::cout << "\n";
}
void magic(std::vector<char>& str, const int i, const int changesLeft) {
if (changesLeft == 0) {
print(str);
return;
}
if (i < 0) return;
// flip current bit
str[i] ^= 1;
magic(str, i-1, changesLeft-1);
// or don't flip it (flip it again to undo)
str[i] ^= 1;
magic(str, i-1, changesLeft);
}
int main(void) {
std::vector<char> str = {0, 1, 1};
print(str);
size_t len = str.size();
size_t maxDistance = str.size();
for (size_t i = 1 ; i <= maxDistance ; ++i) {
printf("Computing for distance %lu\n", i);
magic(str, len-1, i);
printf("----------------\n");
}
return 0;
}
where the output is identical.
PS - I am also toggling the bit with a different way.

Related

Combination of unique elements without repetition

Elements : a b c
all combinations in such a way:abcabacbcabc
Formula to get total number of combinations of unique elements without repetition = 2^n - 1 (where n is the number of unique elements)
In our case top: 2^3 - 1 = 7
Another formula to get the combinations with specific length = n!/(r! * (n - r)!) (where n= nb of unique items and r=length)
Example for our the above case with r=2 : 3!/(2! * 1!) = 3 which is ab ac bc
Is there any algorithm or function that gets all of the 7 combinations?
I searched a lot but all i can find is one that gets the combinations with specific length only.
UPDATE:
This is what I have so far but it only gets combination with specific length:
void recur(string arr[], string out, int i, int n, int k, bool &flag)
{
flag = 1;
// invalid input
if (k > n)
return;
// base case: combination size is k
if (k == 0) {
flag = 0;
cout << out << endl;
return;
}
// start from next index till last index
for (int j = i; j < n; j++)
{
recur(arr, out + " " + arr[j], j + 1, n, k - 1,flag);
}
}
The best algorithm I've ever find to resolve this problem is to use bitwise operator. You simply need to start counting in binary. 1's in binary number means that you have to show number.
e.g.
in case of string "abc"
number , binary , string
1 , 001 , c
2 , 010 , b
3 , 011 , bc
4 , 100 , a
5 , 101 , ac
6 , 110 , ab
7 , 111 , abc
This is the best solution I've ever find. you can do it simply with loop. there will not be any memory issue.
here is the code
#include <iostream>
#include <string>
#include <math.h>
#include<stdio.h>
#include <cmath>
using namespace std;
int main()
{
string s("abcd");
int condition = pow(2, s.size());
for( int i = 1 ; i < condition ; i++){
int temp = i;
for(int j = 0 ; j < s.size() ; j++){
if (temp & 1){ // this condition will always give you the most right bit of temp.
cout << s[j];
}
temp = temp >> 1; //this statement shifts temp to the right by 1 bit.
}
cout<<endl;
}
return 0;
}
Do a simple exhaustive search.
#include <iostream>
#include <string>
using namespace std;
void exhaustiveSearch(const string& s, int i, string t = "")
{
if (i == s.size())
cout << t << endl;
else
{
exhaustiveSearch(s, i + 1, t);
exhaustiveSearch(s, i + 1, t + s[i]);
}
}
int main()
{
string s("abc");
exhaustiveSearch(s, 0);
}
Complexity: O(2^n)
Here's an answer using recursion, which will take any number of elements as strings:
#include <vector>
#include <string>
#include <iostream>
void make_combos(const std::string& start,
const std::vector<std::string>& input,
std::vector<std::string>& output)
{
for(size_t i = 0; i < input.size(); ++i)
{
auto new_string = start + input[i];
output.push_back(new_string);
if (i + 1 == input.size()) break;
std::vector<std::string> new_input(input.begin() + 1 + i, input.end());
make_combos(new_string, new_input, output);
}
}
Now you can do:
int main()
{
std::string s {};
std::vector<std::string> output {};
std::vector<std::string> input {"a", "b", "c"};
make_combos(s, input, output);
for(auto i : output) std::cout << i << std::endl;
std::cout << "There are " << output.size()
<< " unique combinations for this input." << std::endl;
return 0;
}
This outputs:
a
ab
abc
ac
b
bc
c
There are 7 unique combinations for this input.

Permutations &/ Combinations using c++

I need a different version of permutations for my code. I could able to achieve what I want but it is not generic enough. my algorithm keeps going bigger along with my requirements. But that should not be.
This is not a home work for any one, I need it for one my critical projects, wondering if any pre-defined algorithms available from boost or any other.
Below is the standard version of next_permutation using c++.
// next_permutation example
#include <iostream> // std::cout
#include <algorithm> // std::next_permutation
int main ()
{
int myints[] = {1,2,3};
do
{
std::cout << myints[0] << ' ' << myints[1] << ' ' << myints[2] << '\n';
} while ( std::next_permutation(myints,myints+3) );
return 0;
}
That gives below output :
1 2 3
1 3 2
2 1 3
2 3 1
3 1 2
3 2 1
But my requirement is :- Let's say I have 1 to 9 numbers :
1,2,3,4,5,6,7,8,9
And I need a variable length of permutations and in only ASCENDING order and with out DUPLICATES.
Let's say i need 3 digit length of permutations then i need output as below.
123
124
125
.
.
.
128
129
134 // After 129 next one should be exactly 134
135 // ascending order mandatory
136
.
.
.
148
149
156 // exactly 156 after 149, ascending order mandatory
.
.
.
489 // exactly 567 after 489, because after 3rd digit 9, 2nd digit
567 // will be increased to 49? , so there is no possibility for
. // 3rd digit, so first digit gets incremented to 5 then 6 then
. // 7, in ascending order.
.
.
.
789 // and this should be the last set I need.
My list may contain upto couple of hundred's of numbers and variable length can be 1 to up to Size of the list.
My own algorithm is working for specific variable length, and a specific size, when they both changes, i need to write huge code. so, looking for a generic one.
I am not even sure if this is called as Permutations or there is a different name available for this kind of math/logic.
Thanks in advance.
musk's
Formally, you want to generate all m-combinations of the set [0;n-1].
#include <iostream>
#include <vector>
bool first_combination (std::vector<int> &v, int m, int n)
{
if ((m < 0) || (m > n)) {
return false;
}
v.clear ();
v.resize (m);
for (int i = 0; i < m; i++) {
v[i] = i;
}
return true;
}
bool next_combination (std::vector<int> &v, int m, int n)
{
for (int i = m - 1; i >= 0; i--) {
if (v[i] + m - i < n) {
v[i]++;
for (int j = i + 1; j < m; j++) {
v[j] = v[j - 1] + 1;
}
return true;
}
}
return false;
}
void print_combination (const std::vector<int> &v)
{
for (size_t i = 0; i < v.size(); i++) {
std::cout << v[i] << ' ';
}
std::cout << '\n';
}
int main ()
{
const int m = 3;
const int n = 5;
std::vector<int> v;
if (first_combination (v, m, n)) {
do {
print_combination (v);
} while (next_combination (v, m, n));
}
}
You can use this code and the linked article as inspiration.
This task can be done with a simple iterative algorithm. Just increment the first element that can be incremented and rescale the elements before it until there is no element to be incremented.
int a[] = {0,1,2,3,4,5,6,7,8,9}; // elements: must be ascending in this case
int n = sizeof(a)/sizeof(int);
int digits = 7; // number of elements you want to choose
vector<int> indexes; // creating the first combination
for ( int i=digits-1;i>=0;--i ){
indexes.push_back(i);
}
while (1){
/// printing the current combination
for ( int i=indexes.size()-1;i>=0;--i ){
cout << a[indexes[i]] ;
} cout << endl;
///
int i = 0;
while ( i < indexes.size() && indexes[i] == n-1-i ) // finding the first element
++i; // that can be incremented
if ( i==indexes.size() ) // if no element can be incremented, we are done
break;
indexes[i]++; // increment the first element
for ( int j=0;j<i;++j ){ // rescale elements before it to first combination
indexes[j] = indexes[i]+(i-j);
}
}
Output:
0123456
0123457
0123458
0123459
0123467
0123468
0123469
0123478
0123479
0123489
0123567
0123568
0123569
0123578
0123579
0123589
0123678
0123679
0123689
0123789
0124567
0124568
0124569
0124578
0124579
0124589
0124678
0124679
0124689
0124789
0125678
0125679
0125689
0125789
0126789
0134567
0134568
0134569
0134578
0134579
0134589
0134678
0134679
0134689
0134789
0135678
0135679
0135689
0135789
0136789
0145678
0145679
0145689
0145789
0146789
0156789
0234567
0234568
0234569
0234578
0234579
0234589
0234678
0234679
0234689
0234789
0235678
0235679
0235689
0235789
0236789
0245678
0245679
0245689
0245789
0246789
0256789
0345678
0345679
0345689
0345789
0346789
0356789
0456789
1234567
1234568
1234569
1234578
1234579
1234589
1234678
1234679
1234689
1234789
1235678
1235679
1235689
1235789
1236789
1245678
1245679
1245689
1245789
1246789
1256789
1345678
1345679
1345689
1345789
1346789
1356789
1456789
2345678
2345679
2345689
2345789
2346789
2356789
2456789
3456789

Computing Combinations on basis of number of bits set

I need to compute all possible combinations of n things selected r at a time where 0<=r<=n, One method to do so is generating the numbers up to 0 to 2^n-1. But I need to generate these numbers such that the numbers should be sorted on the basis of the number of bits set in that number. for n=3:
0 // numbers with 0 bits set
1 2 4 // numbers with 1 bits set
3 5 6 // numbers with 2 bits set
7 // numbers with 3 bits set
I need to know how to generate the numbers such that they are sorted in increasing/decreasing order of bits set?
Implement regular algorithm to generate the combinations, but also hold an additional array where you store the numbers sorted accoding to the 1-bits set. Then for each combination generated replace the numbers with the numbers sitting in the corresponding position minus one in the array sorted as I described.
Iterating over all combinations of some some number of items is covered nicely by quant_dev here.
Here is a simple way function that counts the number of bits set in a number's representation:
// Counts how many bits are set in the representation of the input number n
int numOfBitsSet(int n)
{
int cnt = 0;
while (n != 0)
{
cnt += (n & 1);
n = n >> 1;
}
return cnt;
}
And here is how you could use it in a (C++11) program that does what you want:
#include <algorithm>
#include <vector>
#include <iostream>
#include <iterator>
using namespace std;
int main()
{
// For instance...
int n = 3;
// Fill up a vector of 2^n entries (0 .. 2^(n - 1))
vector<int> v(1 << n);
iota(begin(v), end(v), 0);
// For each number of bits...
for (size_t i = 0; i <= n; i++)
{
cout << "Numbers with " << i << " bits set: ";
// Find the first number with i bits set...
auto it = find_if(begin(v), end(v), [i] (int x) {
return (numOfBitsSet(x) == i);
});
while (it != end(v))
{
cout << *it << " ";
// Find the next number with i bits set...
it = find_if(next(it), end(v), [i] (int x) {
return (numOfBitsSet(x) == i);
});
}
cout << endl;
}
}
If C++11 is not an option for you, you will have to use functors instead of lambdas, and replace std::iota with a manual loop:
#include <algorithm>
#include <vector>
#include <iostream>
#include <iterator>
using namespace std;
struct bit_count_filter
{
bit_count_filter(int i) : _i(i) { }
bool operator () (int x) const { return numOfBitsSet(x) == _i; }
int _i;
};
int main()
{
// For instance...
int n = 3;
// Fill up a vector of 2^n entries (0 .. 2^(n - 1))
vector<int> v(1 << n);
for (size_t i = 0; i < v.size(); i++)
{
v[i] = i;
}
// For each number of bits...
for (size_t i = 0; i <= n; i++)
{
cout << "Numbers with " << i << " bits set: ";
// Find the first number with i bits set...
auto it = find_if(begin(v), end(v), bit_count_filter(i));
while (it != end(v))
{
cout << *it << " ";
// Find the next number with i bits set...
it = find_if(next(it), end(v), bit_count_filter(i));
}
cout << endl;
}
}
You could do it recursively:
void setnbits(unsigned int cur, int n, int toset, int max)
{
if(toset == 0)
{
printf("%d ", cur >> (n + 32 - max) , n);
return;
}
toset--;
for(int i = 1 ; i <= n-toset ; i++)
{
setnbits((cur >> i) | 0x80000000, n-i, toset , max);
}
}
Could be called like:
for(int z = 0 ; z < 4 ; z++)
{
printf("%d bits: ", z);
setnbits(0, 3, z, 3);
printf("\n");
}
prints:
0 bits: 0
1 bits: 1 2 4
2 bits: 3 5 6
3 bits: 7
The numbers are not guaranteed to be in numerical order.
That's pretty easy.
There are two cases:
1) Last 1-bit has 0-bit before:
000111001001 -> 000111001010.
You should just move it to the left
2) There is a chain of 1-bits:
000110111100 -> 000111000111
Then you should move last 1-bit to the nearest 0-bit on the left(before the chain), and move all another bits of that chain to the right.
You'll get this way all needed numbers in increasing order.

Is this an inefficent way to convert from a binary string to decimal value?

while(i < length)
{
pow = 1;
for(int j = 0; j < 8; j++, pow *=2)
{
ch += (str[j] - 48) * pow;
}
str = str.substr(8);
i+=8;
cout << ch;
ch = 0;
}
This seems to be slowing my program down a lot. Is it because of the string functions I'm using in there, or is this approach wrong in general. I know there's the way where you implement long division, but I wanted to see if that was actually more efficient than this method. I can't think of another way that doesn't use the same general algorithm, so maybe it's just my implementation that is the problem.
Perhaps you want might to look into using the standard library functions. They're probably at least as optimised as anything you run through the compiler:
#include <iostream>
#include <iomanip>
#include <cstdlib>
int main (void) {
const char *str = "10100101";
// Use str.c_str() if it's a real C++ string.
long int li = std::strtol (str, 0, 2);
std::cout
<< "binary string = " << str
<< ", decimal = " << li
<< ", hex = " << std::setbase (16) << li
<< '\n';
return 0;
}
The output is:
binary string = 10100101, decimal = 165, hex = a5
You are doing some things unnecessarily, like creating a new substring for each each loop. You could just use str[i + j] instead.
It is also not necessary to multiply 0 or 1 with the power. Just use an if-statement.
while(i < length)
{
pow = 1;
for(int j = 0; j < 8; j++, pow *=2)
{
if (str[i + j] == '1')
ch += pow;
}
i+=8;
cout << ch;
ch = 0;
}
This will at least run a bit faster.
short answer could be:
long int x = strtol(your_binary_c++_string.c_str(),(char **)NULL,2)
Probably you can use int or long int like below:
Just traverse the binary number step by step, starting from 0 to n-1, where n is the most significant bit(MSB) ,
multiply them with 2 with raising powers and add the sum together. E.g to convert 1000(which is binary equivalent of 8), just do the following
1 0 0 0 ==> going from right to left
0 x 2^0 = 0
0 x 2^1 = 0;
0 x 2^2 = 0;
1 x 2^3 = 8;
now add them together i.e 0+0+0+8 = 8; this the decimal equivalent of 1000. Please read the program below to have a better understanding how the concept
work. Note : The program works only for 16-bit binary numbers(non-floating) or less. Leave a comment if anything is not clear. You are bound to receive a reply.
// Program to convert binary to its decimal equivalent
#include <iostream>
#include <math.h>
int main()
{
int x;
int i=0,sum = 0;
// prompts the user to input a 16-bit binary number
std::cout<<" Enter the binary number (16-bit) : ";
std::cin>>x;
while ( i != 16 ) // runs 16 times
{
sum += (x%10) * pow(2,i);
x = x/10;
i++;
}
std::cout<<"\n The decimal equivalent is : "<<sum;
return 0;
}
How about something like:
int binstring_to_int(const std::string &str)
{
// 16 bits are 16 characters, but -1 since bits are numbered 0 to 15
std::string::size_type bitnum = str.length() - 1;
int value = 0;
for (auto ch : str)
{
value |= (ch == '1') << bitnum--;
}
return value;
}
It's the simplest I can think of. Note that this uses the new C++11 for-each loop construct, if your compiler can't handle it you can use
for (std::string::const_iterator i = str.begin(); i != str.end(); i++)
{
char ch = *i;
// ...
}
Minimize the number of operations and don't compute things more than once. Just multiply and move up:
unsigned int result = 0;
for (char * p = str; *p != 0; ++p)
{
result *= 2;
result += (*p - '0'); // this is either 0 or 1
}
The scheme is readily generalized to any base < 10.

a non recursive approach to the problem of generating combinations at fault

I wanted a non recursive approach to the problem of generating combination of certain set of characters or numbers.
So, given a subset k of numbers n, generate all the possible combination n!/k!(n-k)!
The recursive method would give a combination, given the previous one combination.
A non recursive method would generate a combination of a given value of loop index i.
I approached the problem with this code:
Tested with n = 4 and k = 3, and it works, but if I change k to a number > 3 it does not work.
Is it due to the fact that (n-k)! in case of n = 4 and k = 3 is 1. and if k > 3 it will be more than 1?
Thanks.
int facto(int x);
int len,fact,rem=0,pos=0;
int str[7];
int avail[7];
str[0] = 1;
str[1] = 2;
str[2] = 3;
str[3] = 4;
str[4] = 5;
str[5] = 6;
str[6] = 7;
int tot=facto(n) / facto(n-k) / facto(k);
for (int i=0;i<tot;i++)
{
avail[0]=1;
avail[1]=2;
avail[2]=3;
avail[3]=4;
avail[4]=5;
avail[5]=6;
avail[6]=7;
rem = facto(i+1)-1;
cout<<rem+1<<". ";
for(int j=len;j>0;j--)
{
int div = facto(j);
pos = rem / div;
rem = rem % div;
cout<<avail[pos]<<" ";
avail[pos]=avail[j];
}
cout<<endl;
}
int facto(int x)
{
int fact=1;
while(x>0) fact*=x--;
return fact;
}
Err.. why not use std::next_permutation? It does exactly what you're looking for and doesn't require you to write (and debug and maintain) your own.
This is about as fast as it can be calculated - the actual combination function is done using two lines of code.
However, this isn't the most intuitively easy to understand!
The work is done by implementing a Gray code sequence.
#include <iostream>
#include <iomanip>
#include <cstdlib>
#include <stdint.h>
using namespace std;
//'Combinations' over a set of n objects with k bins, eg n=3,k=2 = 3
//The combination function.
//It takes a combination and returns the next combination.
//It uses GCC's '__builtin_ctzll' which returns the number of
//trailing 0-bits in v, starting at the least significant bit position.
uint64_t combination(uint64_t v) {
uint64_t t = v | (v - 1ULL); // t gets v's least significant 0 bits set to 1
return (t + 1ULL) | (((~t & -~t) - 1ULL) >> (__builtin_ctzll(v) + 1ULL));
}
//arg 1 is number of bins (n) arg 2 is number of samples (k/r)
int main (int argc, char *argv[]) {
uint64_t n = min(64ULL,argc > 1ULL ? atoi(argv[1]) : 3ULL); //max bins = 63
uint64_t k = min( n,argc > 2 ? atoi(argv[2]) : 2ULL); //max samples = bins.
uint64_t v = (1ULL << k) - 1; //start value;
uint64_t m = n == 64 ? UINT64_MAX: (1ULL << n) - 1ULL; //size of n is used as a mask.
string index = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz+*";
cout << index.substr(0,n) << endl;
do {
cout << bitset<64>(v & m).to_string().substr(64ULL-n) << endl;
v=combination(v);
} while (v < m);
return 0;
}
Consider that your iterator is a number of k digits in base n. In C/C++ you can represent it as an array of ints of size k where every element is in the range from 0 to n-1).
Then, to iterate from one position to the next you only need to increment the number.
That will give you all the permutations. In order to get combinations you have to impose an additional condition that is that digits must be in ascending order.
For instance with k = 3, n = 3: 000 001 002 011 012 022 111 112 122 222
Implementing that constraint in C is also pretty simple, on the increment operation used to iterate, instead of setting the rightmost digits to zero when there is a carry, you have to set them to the same value as the leftmost digit changed.
update: some code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAXK 100
int
main(int argc, char *argv[]) {
int digits[MAXK];
int k = atol(argv[1]);
int n = atol(argv[2]);
int i, left;
memset(digits, 0, sizeof(digits));
while(1) {
for (i = k; i--; ) {
printf("%d", digits[i]);
printf((i ? "-" : "\n"));
}
for (i = k; i--; ) {
left = ++digits[i];
if (left < n) {
while (++i < k) digits[i] = left;
break;
}
}
if (i < 0) break;
}
}