PHP 用字符串表示的二进制计数器

PHP binary counter with string representation

我们可以提高这段代码的复杂度吗?

如何简化此计数器而不降低可读性?

是否有更简单的逻辑解决方案来实现此目的?

我正在尝试自己进行二进制加法——这就是我使用字符串的原因。

$pattern = '00000000';                                                                                        
                                                                                                              
while ($pattern !== '11111111') {                                                                             
    $bit_arr = str_split($pattern);                                                                           
    $rev_arr = array_reverse($bit_arr);                                                                       
    $arr_ln = count($bit_arr) - 1;                                                                            
    $i = 0;                                                                                                   
                                                                                                              
    while ($i <= $arr_ln) {                                                                                   
        if ((int) $rev_arr[$i + 1] === 0 && (int) $rev_arr[$i] === 0) {                                       
            $rev_arr[$i] = 1;                                                                                 
            $i = $arr_ln + 1;                                                                                 
            break;                                                                                            
        }                                                                                                     
                                                                                                              
        if ((int) $rev_arr[$i + 1] === 0 && (int) $rev_arr[$i] === 1) {                                       
            $rev_arr[$i + 1] = 1;                                                                             
            $rev_arr[$i] = 0;                                                                                 
            $i = $arr_ln + 1;                                                                                 
            break;                                                                                            
        }                                                                                                     
                                                                                                              
        if ((int) $rev_arr[$i + 1] === 1 && (int) $rev_arr[$i] === 0) {                                       
            $rev_arr[$i] = 1;                                                                                 
            $i = $arr_ln + 1;                                                                                 
            break;                                                                                            
        }                                                                                                     
                                                                                                              
        if ((int) $rev_arr[$i + 1] === 1 && (int) $rev_arr[$i] === 1) {                                       
            $rev_arr[$i] = 0;                                                                                 
        }                                                                                                     
                                                                                                              
        $i++;                                                                                                 
    }                                                                                                         
                                                                                                              
    $next_pattern = implode('', array_reverse($rev_arr));                                                     
    $pattern = $next_pattern;                                                                                 
    $second = 1000 * 1000;                                                                                    
                                                                                                              
    usleep(0.5 * $second);                                                                                    
                                                                                                              
    echo $pattern . PHP_EOL;          
    echo 'Decimal number: ' .  bindec($pattern) . PHP_EOL;                                                     
}

二进制加法非常简单。

0 + 0 = 0
0 + 1 = 1
1 + 0 = 1
1 + 1 = 0 with 1 carry(for the next MSB bit)

牢记以上4个操作,我们从carry开始二进制加法作为1,意思是将1加到当前表示中。现在,如果当前位加进位可以是可能的结果之一:

  • 0 - 所以将当前位设置为 0
  • 1 - 所以将当前位设置为 1
  • 2 - 因此将当前位设置为 0,下一位进位为 1

在下面的代码中,ord 用于获取 01 的 ASCII 值。

片段:

<?php

$pattern = '00000000';
$length = strlen($pattern);
$expected = 1;
while($pattern != '11111111'){
    $carry = 1;
    for($i = $length - 1; $i >= 0; --$i){
        $curr_digit = ord($pattern[$i]) - 48 + $carry;
        $pattern[$i] = $curr_digit != 1 ? '0' : '1';
        $carry = $curr_digit == 2 ? 1 : 0;
    }
    
    echo bindec($pattern),PHP_EOL;
}

时间复杂度与模式中的位数成线性关系。