[英]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.