【问题标题】:Choose some numbers coding in Gray Code在格雷码中选择一些数字编码
【发布时间】:2018-06-08 13:30:02
【问题描述】:

我必须编写一个程序来显示一些格雷码编码的数字。我已经在这个页面 (https://www.geeksforgeeks.org/given-a-number-n-generate-bit-patterns-from-0-to-2n-1-so-that-successive-patterns-differ-by-one-bit/) 中找到了一个用 C++ 编写的算法。

但我想创建一个新方法来删除连续有两个“1”并且末端有“1”的数字(左和右)。

示例:对于 n = 3,我们得到这个数字:

000
001
011
010
110
111
101
100

现在我想删除这些数字:011、110、111、101,并在列表中显示其他数字。

我的想法是创建一个向量的向量。例如,当 n = 3 时:{{000},{001},{011},{010},{110},{111},{101},{100}}。

大小应该是这样的:

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

例如:vector[0][1] = {0} 和 vector[1][2] = {1} 如果我的尺寸是正确的。

现在要删除连续有两个“1”且末端有“1”的数字,我可以使用以下代码:

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; }
}
}

现在的问题是我不知道如何将结果存储在我的向量中用 C++ 编写的格雷码中,或者也许有一种方法可以在不使用向量的情况下比较此代码中的两个数字。

【问题讨论】:

  • 为什么这被标记为java和C++?哪种语言?在 C++ 中,std::adjacent_find 的使用使这变得微不足道。
  • 我将删除 Java 代码。以及如何在用 C++ 编写的代码中使用 std::adjacent_find ?
  • 那么您是否有一个向量向量,并且您想删除与您所说的标准匹配的向量?
  • 是的,这个向量就是我要删除的数字。

标签: c++ algorithm vector gray-code


【解决方案1】:

不使用位操作,这无疑会更快,因为您有一个向量向量,执行删除的一种方法是使用std::adjacent_find 使用谓词来查找相邻的 1,并使用std::remove_if 来删除那些符合具有相邻 1 标准的向量。

这是一个例子:

#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

基本上,如果adjacent_find 没有找到相邻的1,则返回的迭代器将是end()。因此,在findOne 谓词函数中,在对大小和极值进行简单测试后,adjacent_find 接管并完成其余工作。

【讨论】:

  • 感谢您的回答,它对我有帮助!但我想要为格雷码自动创建向量向量,因为我将从 n=3 到 n=20 工作,所以你可以想象手动创建一个 2^20 值的向量是多么困难.而且我必须对符合标准的数字进行一些操作(乘法,加法,...)
  • 答案假设您已经设置了向量。示例中的手动条目只是为了显示可以删除条目。如果您还想生成向量,那真的应该是一个单独的问题,因为这与删除无关。
  • 我可以使用其他程序格雷码自动创建矢量,谢谢你的帮助我可以从这个开始。
  • 你好,我有一个问题,我想用这个方法只用于一维向量,我找到了一个生成一维格雷码向量的解决方案,我应该怎么做到您的代码中,以便我可以使用 1Dimension 向量?
【解决方案2】:

当您处理较大的字符串时,这将是一项额外的工作,而且代码读起来并不简单。创建一个简单的面具怎么样?将一对连续的 1 位移动数字的长度 (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

【讨论】:

  • 感谢您的回答,是的,我考虑过这样一个事实,即当我使用更高维度的 n 时,它会变得困难而漫长。在我还是 C++ 的初学者之前,我从来没有使用过面具,所以你能帮我更多吗?是否可以向我展示整个程序?
  • 您可以使用字符串掩码,但何必呢?您正在编码的信息是位级别的 - 只是在二进制中工作。
猜你喜欢
  • 2018-09-16
  • 2018-09-25
  • 2010-12-14
  • 2019-07-29
  • 1970-01-01
  • 2019-08-03
  • 2017-01-12
  • 2015-10-19
  • 1970-01-01
相关资源
最近更新 更多