1

I have to write a programm that shows some numbers coding in Gray Code. I already found an algorithm written in C++ in this page ( https://www.geeksforgeeks.org/given-a-number-n-generate-bit-patterns-from-0-to-2n-1-so-that-successive-patterns-differ-by-one-bit/ ).

But I want to create a new method to delete the numbers that have two "1" consecutively and have "1" in their extremity (left and right).

Example : for n = 3 we get this numbers :

000
001
011
010
110
111
101
100

Now I want to delete this numbers : 011 , 110 , 111 , 101 and show the other numbers remiding in the list.

My idea is to create a vector of vectors. Something like that for example when n = 3 : {{000},{001},{011},{010},{110},{111},{101},{100}}.

For the size it will be like this :

int m = pow(2,n);
int vector[m][n];

For example : vector[0][1] = {0} and vector[1][2] = {1} if I'm correct with the sizes.

Now to delete the numbers that have two "1" consecutively and have "1" in their extremity I can use this code :

while (i < m){
for (j=0; j<n-1; j++){
if (vector[i][j]==vector[i][j+1]==1 && vector[i][0]==vector[i][n-1]==1 ) 
    i=i+1; //Don't show this number
else { cout <<vector[i][j] << endl; i=i+1; }
}
}

Now the problem is that I don't know how to store the result in the Gray Code written in C++ in my vectors, or maybe there is a way to compare between two numbers from this code without using vectors.

Red One
  • 133
  • 7

2 Answers2

0

This is going to be extra work when you get to larger strings, and the code is not trivial to read. How about creating a simple mask? Shift a pair of contiguous 1 bits the length of the number (num).

mask = 0b11000      // fill in the correct quantity of 0s
end_mask = 0b10001

while mask > 1
    if (num && mask) == mask
        remove num from array
    mask = mask >> 1

if num && end_mask == end_mask
    remove num from array
Prune
  • 76,765
  • 14
  • 60
  • 81
  • Thank you for the answer and yes I have thought about the fact that it's going to be hard and long when I use a higher dimension n. I have never worked with mask before I'm a beginner in C++, so can you help me more please ? Is it possible to show me the whole programm ? – Red One Dec 28 '17 at 01:33
  • You can work with a string mask, but why bother? The information you're encoding is at the bit level -- just work in binary. – Prune Dec 29 '17 at 02:02
0

Without using bit manipulation, which admittedly would be faster, since you have a vector of vectors, one way to perform the removal is to use std::adjacent_find using a predicate to find the adjacent 1's, and to use std::remove_if to remove those vectors matching the criteria of having adjacent 1's.

Here is an example:

#include <algorithm>
#include <vector>
#include <iostream>
#include <iterator>

bool findOnes(const std::vector<int>& v)
{
    // less than 2 digits, so can't do anything
    if ( v.size() < 2 )
       return false;

    // test extremes
    if ( v.front() == 1 && v.back() == 1 )   
       return true;

    // check if there are adjacent 1's
    return std::adjacent_find(v.begin(), v.end(), [&](int n1, int n2)
                             { return n1 == 1 && n2 == 1; }) != v.end();
}

int main()
{
    //test 
    std::vector<std::vector<int>> vect = {{0,0,0},{0,0,1},{0,1,1},{0,1,0},{1,1,0},{1,1,1},{1,0,1},{1,0,0}};

    // erase the vectors that match the criteria
    vect.erase(std::remove_if(vect.begin(), vect.end(), findOnes), vect.end());

    // show the final results
    for ( auto& i : vect )
    {
       std::copy(i.begin(), i.end(), std::ostream_iterator<int>(std::cout, " "));
       std::cout << "\n";
    }
}

Live Example

Basically, if the adjacent_find does not find adjacent 1's, the iterator returned will be end(). Thus in the findOne predicate function, after doing the easy tests for size and the extreme values, adjacent_find takes over and does the rest.

PaulMcKenzie
  • 34,698
  • 4
  • 24
  • 45
  • Thanks for the answer it helps me ! But I want the auto-creation of the vector of vectors for the Gray Code, because I'ill work from n=3 to n=20, so you can imagine how difficule it would be to create a vector of 2^20 values manually. And I'll have to do some manipulations with the numbers that respect the criteria (Multiplication, Addition,...) – Red One Dec 28 '17 at 02:03
  • The answer assumes you already have the vectors set up. The manual entries in the example is done only to show that the entries can be removed. If you want to also generate the vectors, that really should have been a separate question, since that has nothing to do with removal. – PaulMcKenzie Dec 28 '17 at 02:06
  • I can use the other programm Gray Code to auto create the vector, thank you for your help I can start frm this. – Red One Dec 28 '17 at 16:42
  • Hello again, I have a question, I wat to use this method for a vector of 1 Dimension only, I found a solution to generate a vector of Gray Code in one dimension, what changes should I do to your code so I can work with a 1Dimension vector ? – Red One Jan 18 '18 at 18:11