Choose some numbers coding in Gray Code

≡放荡痞女 提交于 2019-12-11 07:30:15

问题


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.


回答1:


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



回答2:


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.



来源:https://stackoverflow.com/questions/48000038/choose-some-numbers-coding-in-gray-code

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!