簡體   English   中英

在不帶二進制的Perl / Java中打印n個變量的所有可能的布爾狀態

[英]Print all possible boolean states of n variables in Perl/Java w/o binary

我需要生成n個變量的所有可能的布爾狀態(2 ^ n)。 例如,對於n = 3,它應如下所示:

0 0 0  
1 0 0  
0 1 0  
0 0 1  
1 1 0  
1 0 1  
0 1 1  
1 1 1  

不幸的是,我不能使用二進制魔術,就像這里顯示的那樣,所以這個(大師)的簡單性對我來說是不可用的:(

final int n = 3;
for (int i = 0; i < Math.pow(2, n); i++) {
    String bin = Integer.toBinaryString(i);
        while (bin.length() < n)
        bin = "0" + bin;
    System.out.println(bin);
} 

我需要以簡單而有效的方式使用無格式循環來執行此操作,而沒有像上面答案中所示的二進制或列表函數之類的特殊事物。

任何幫助將非常感激!

那這樣的東西呢? 如果不清楚,請添加評論!

void allConfigurations(int n, int[] config, int index)
{
    if(index == n)// base case, the whole config has been filled
    {
        printConfiguration(config);
        return;
    }
    config[index] = 0; //create config with 0 at index
    allConfigurations(n, config, index + 1);
    config[index] = 1; //create config with 1 at index
    allConfigurations(n, config, index + 1);
}

這些州是

sub bits {
   my ($n, $i) = @_;
   return map { my $bit = $i & 1; $i >>= 1; $bit } 0..$n-1;
}

my $n = 3;
for my $i (0 .. (1<<$n)-1) {
   my @bits = bits($n, $i);
   print("@bits\n");
}

如果您沒有&<<>> (由於所有CPU都有這些,那將真的很奇怪),或者如果您想要兩個以上的狀態,則可以使用以下命令:

sub bits {
   my ($b, $n, $i) = @_;
   return map { my $bit = $i % $b; $i = ($i-$bit)/$b; $bit } 0..$n-1;
}

my $n = 3;
my $b = 2;
for my $i (0 .. ($b**$n)-1) {
   my @bits = bits($b, $n, $i);
   print("@bits\n");
}

優化:

sub get_next {
   my ($b, $bits) = @_;
   for (@$bits) {
      return 1 if ++$_ != $b;
      $_ = 0;
   }
   return 0;
}

my $n = 3;
my $b = 2;
my @bits = (0) x $n;
while (1) {
   print("@bits\n");
   last if !get_next($b, \@bits);
}

n = 3的基准結果,

                  Rate tommaso_pasini        ikegami ikegami_inline
tommaso_pasini 34462/s             --           -23%           -49%
ikegami        44612/s            29%             --           -34%
ikegami_inline 68061/s            97%            53%             --

n = 10的基准結果,

                Rate tommaso_pasini        ikegami ikegami_inline
tommaso_pasini 271/s             --           -33%           -58%
ikegami        403/s            48%             --           -38%
ikegami_inline 644/s           138%            60%             --

基准測試代碼:

use strict;
use warnings;
use Benchmark qw( cmpthese );

sub _tommaso_pasini {
    my ($n, $bits, $i) = @_;

    if ($i == $n) {
    # ...
        return;
    }

    $bits->[$i] = 0;
    _tommaso_pasini($n, $bits, $i+1);
    $bits->[$i] = 1;
    _tommaso_pasini($n, $bits, $i+1);
}

sub tommaso_pasini {
   my ($n) = @_;
   _tommaso_pasini($n, [], 0);
}

sub ikegami_next {
   my ($bits) = @_;
   for (@$bits) {
      return 1 if ++$_ != 2;
      $_ = 0;
   }
   return 0;
}

sub ikegami {
   my ($n) = @_;
   my $bits = [ (0) x $n ];
   while (1) {
      # ...
      last if !ikegami_next($bits);
   }
}

sub ikegami_inline {
   my ($n) = @_;
   my $bits = [ (0) x $n ];
   OUTER: while (1) {
      # ...

      for (@$bits) {
         next OUTER if ++$_ != 2;
         $_ = 0;
      }

      last;
   }
}

for my $n (3, 10) {
   cmpthese(-3, {
      ikegami        => sub { ikegami($n)        },
      ikegami_inline => sub { ikegami_inline($n) },
      tommaso_pasini => sub { tommaso_pasini($n) },
   });
}

如果有人需要,只需發布​​上面出色解決方案的Perl版本。 @TommasoPasini再次感謝!

sub allConfigurations{
    my ($n, $index, @config) = @_;

    if($index == $n) #base case, the whole config has been filled
    {
        &printConfiguration(@config);
        return;
    }
    $config[$index] = 0; #create config with 0 at index
    allConfigurations($n, $index + 1, @config);

    $config[$index] = 1; #create config with 1 at index
    allConfigurations($n, $index + 1, @config);
}

sub printConfiguration{
    my @config = @_;

    print "@config";
    print "\n";
}


&allConfigurations(3, my $index=0, my @conf);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM