首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >灰度码生成.n位格雷码

灰度码生成.n位格雷码
EN

Stack Overflow用户
提问于 2018-04-06 03:14:33
回答 2查看 1.1K关注 0票数 2

这个问题是由hackerrank提出的,我得到了解决方案,但在最后的测试用例中存在一个问题。

问题如下。

代码语言:javascript
复制
1 <= $n <= 65

以下是1位序列(n = 1)

代码语言:javascript
复制
0 1

输出

代码语言:javascript
复制
1

以下是2位序列(n = 2)

代码语言:javascript
复制
00 01 11 10

输出

代码语言:javascript
复制
11 10

以下是3位序列(n = 3)

代码语言:javascript
复制
000 001 011 010 110 111 101 100

输出

代码语言:javascript
复制
111 101 100

以下是4位序列(n = 4)

代码语言:javascript
复制
 0000 0001 0011 0010 0110 0111 0101 0100 1100 1101 1111 
  1110 1010 1011 1001 1000

输出

代码语言:javascript
复制
1010 1011 1001 1000

解决方案示例

下面是从2位灰色代码列表生成3位灰色代码列表的步骤。

  • L1 = {00,01,11,10} (2位格雷码列表)
  • L2 = {10,11,01,00} (与L1相反)
  • 在L1的所有条目前缀为‘0’,L1变为{000,001,011,010}
  • 在L2的所有条目前缀为‘1’,L2将成为{110、111、101、100}
  • 级联L1和L2,得到{000,001,011,010,110,111,101,100}

下面给出了第一个解决方案(基于上面的解决方案示例)

但是下面给出的解决方案在22,23个数字之后就不能工作了。内存分配错误。

代码语言:javascript
复制
<?php

$input = 2;

$list_array = ["0","1"];
$reverse_array = array_reverse($list_array);

for($i = 1; $i < $input; $i++ )
{
    for($j = 0; $j < sizeof($list_array); $j++)
    {
        $list_array[$j] = "0".$list_array[$j];
    }

    for($k = 0; $k < sizeof($reverse_array); $k++)
    {
        $reverse_array[$k] = "1".$reverse_array[$k];
    }

    $list_array = array_merge($list_array,$reverse_array);
    $reverse_array = array_reverse($list_array);
}

for($l = sizeof($list_array) - $input; $l < sizeof($list_array); $l++)  
{
    print_r($list_array[$l]);
    echo "<br />";
}

?>

第二个解决方案在下面给出

这个解决方案将工作到63岁。在63之后,这将显示超时错误。

当64位php在64位操作系统上运行时,这将工作到63。如果它是在64位os上运行的32位php,那么它在31之后就不能工作了。

代码语言:javascript
复制
<?php

    $n = 59;

    $intial = pow(2, $n) - $n;

    $length = pow(2, $n) - 1;

    for($i= $intial; $i <= $length; $i++)
    {
        $decimal = ($i >> 1) ^ $i;
        print_r(decbin($decimal));
        echo "<br />";
    }
?>

请帮我找到这个解决方案。

问题:如何解决上述问题,包括$n = 64和$n = 65

参考资料:https://www.geeksforgeeks.org/given-a-number-n-generate-bit-patterns-from-0-to-2n-1-so-that-successive-patterns-differ-by-one-bit/

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-04-06 06:15:09

这应该适用于你:

代码语言:javascript
复制
<?php

print_r( getResult( 4 ) );

function getResult ( $n ) {
    $result = [];
    for ( $i = 0; $i < $n; $i++ ) {
        $result[] = arr_xor(
          str_split( str_pad( str_pad( strtr( decbin($n - $i - 1), '01', '10' ), (int)ceil(log($n - $i - 1, 2)), '0', STR_PAD_LEFT ), $n, '1', STR_PAD_LEFT ) ),
          str_split( '0' . str_pad( substr( str_pad( strtr( decbin($n - $i - 1), '01', '10' ), (int)ceil(log($n - $i - 1, 2)), '0', STR_PAD_LEFT ), -1-(int)ceil(log($n - $i - 1, 2)), -1), $n - 1, '1', STR_PAD_LEFT ) )
        );
    }
    return $result;
}

function arr_xor( $a, $b ) {
    $result = [];
    for ( $i = 0; $i < count( $a ); $i++ )
        $result[] = (int)$a[$i] ^ (int)$b[$i];
    return implode( '', $result );
}

它只使用第二个解决方案(($i >> 1) ^ $i)中的公式,但是由于不能对大于PHP_INT_MAX的整数使用该公式,所以它使用一个数组,每个元素代表一个位。这不是最有效的解决方案,但很容易超过65。$n = 1000似乎没什么问题。

票数 3
EN

Stack Overflow用户

发布于 2018-04-07 17:04:50

另一个答案和@paulpro类似,这也是我在第二个解决方案中应用的想法。($i >> 1) ^ $i

代码语言:javascript
复制
<?php

$n = 65;

for ( $i = 0; $i < $n; $i++ ) 
{
    $decimal = decbin($n - $i - 1);

    $replace = strtr( $decimal, '01', '10' );

    $cast = (int)ceil(log($n - $i - 1, 2));

    $padding = str_pad( $replace , $cast , '0', STR_PAD_LEFT );

    $a_string = str_pad( $padding, $n, '1', STR_PAD_LEFT );

    //shifting the bit to right
    $substring = substr( $a_string , 0 , -1);
    $b_string = str_pad( $substring , $n, '0', STR_PAD_LEFT );

    $a = str_split( $a_string );
    $b = str_split( $b_string );

    for ( $j = 0; $j < count( $a ); $j++ )
    {
        print_r((int)$a[$j] ^ (int)$b[$j]);
    }

    echo "\n";
}

?>
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/49684736

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档