我有一组五个布尔值.如果其中不止一个是真的,我想要执行特定的功能.您能想到的最优雅的方法是什么,这样我才能在单个if()语句中检查这种情况?目标语言是C#,但我也对其他语言的解决方案感兴趣(只要我们不讨论特定的内置函数).
一个有趣的选择是将布尔值存储在一个字节中,进行右移并与原始字节进行比较.类似if(myByte && (myByte >> 1))
但是这需要将单独的布尔值转换为一个字节(通过bitArray?),这似乎有点(双关语)笨拙... [编辑]对不起,应该是 if(myByte & (myByte - 1))
[/ edit]
注意:这当然非常接近经典的"人口数量","横向增加"或"汉明重量"编程问题 - 但不完全相同.我不需要知道有多少位被设置,只要它不止一个.我希望有一种更简单的方法来实现这一目标.
Dan*_*ker 115
我打算写Linq版本,但是有五个人打败了我.但我真的很喜欢params方法,以避免手动新建数组.所以我认为最好的混合动力是,基于rp的回答与身体取代明显的Linqness:
public static int Truth(params bool[] booleans)
{
return booleans.Count(b => b);
}
Run Code Online (Sandbox Code Playgroud)
非常清楚阅读和使用:
if (Truth(m, n, o, p, q) > 2)
Run Code Online (Sandbox Code Playgroud)
Cha*_*ana 85
怎么样
if ((bool1? 1:0) + (bool2? 1:0) + (bool3? 1:0) +
(bool4? 1:0) + (bool5? 1:0) > 1)
// do something
Run Code Online (Sandbox Code Playgroud)
或者一般化的方法是......
public bool ExceedsThreshold(int threshold, IEnumerable<bool> bools)
{
int trueCnt = 0;
foreach(bool b in bools)
if (b && (++trueCnt > threshold))
return true;
return false;
}
Run Code Online (Sandbox Code Playgroud)
或者使用其他答案建议的LINQ:
public bool ExceedsThreshold(int threshold, IEnumerable<bool> bools)
{ return bools.Count(b => b) > threshold; }
Run Code Online (Sandbox Code Playgroud)
编辑(添加Joel Coehoorn的建议:(在.Net 2.x及更高版本中)
public void ExceedsThreshold<T>(int threshold,
Action<T> action, T parameter,
IEnumerable<bool> bools)
{ if (ExceedsThreshold(threshold, bools)) action(parameter); }
Run Code Online (Sandbox Code Playgroud)
或.Net 3.5及更高版本:
public void ExceedsThreshold(int threshold,
Action action, IEnumerable<bool> bools)
{ if (ExceedsThreshold(threshold, bools)) action(); }
Run Code Online (Sandbox Code Playgroud)
或作为...的延伸 IEnumerable<bool>
public static class IEnumerableExtensions
{
public static bool ExceedsThreshold<T>
(this IEnumerable<bool> bools, int threshold)
{ return bools.Count(b => b) > threshold; }
}
Run Code Online (Sandbox Code Playgroud)
用法将是:
var bools = new [] {true, true, false, false, false, false, true};
if (bools.ExceedsThreshold(3))
// code to execute ...
Run Code Online (Sandbox Code Playgroud)
Gar*_*ler 18
现在是强制性LINQ答案的时候了,在这种情况下实际上非常简洁.
var bools = new[] { true, true, false, false, false };
return bools.Count(b => b == true) > 1;
Run Code Online (Sandbox Code Playgroud)
rec*_*ive 16
我会把它们投入到整数和总和中.
除非你处于一个超紧密的内循环中,否则它具有易于理解的优点.
我写了一个函数来接收任意数量的布尔值.它将返回那些值为true的值.检查结果是否需要积极的值来执行某些操作.
更加努力地说清楚,而不是聪明!
private int CountTrues( params bool[] booleans )
{
int result = 0;
foreach ( bool b in booleans )
{
if ( b ) result++;
}
return result;
}
Run Code Online (Sandbox Code Playgroud)
如果您的意思是大于或等于一个布尔值等于true,则可以这样做
if (bool1 || bool2 || bool3 || bool4 || bool5)
Run Code Online (Sandbox Code Playgroud)
如果您需要多个(等于2个或更多)等于true的布尔值,则可以尝试
int counter = 0;
if (bool1) counter++;
if (bool2) counter++;
if (bool3) counter++;
if (bool4) counter++;
if (bool5) counter++;
if (counter >= 2) //More than 1 boolean is true
Run Code Online (Sandbox Code Playgroud)
如果有数百万而不是只有5,你可以避免Count()而是这样做......
public static bool MoreThanOne (IEnumerable<bool> booleans)
{
return booleans.SkipWhile(b => !b).Skip(1).Any(b => b);
}
Run Code Online (Sandbox Code Playgroud)
如果你的旗帜被打包成一个单词,那么Michael Burr的解决方案就可以了.但是,循环不是必需的:
int moreThanOneBitSet( unsigned int v)
{
return (v & (v - 1)) != 0;
}
Run Code Online (Sandbox Code Playgroud)
例
v (binary) | v - 1 | v&(v-1) | result
------------+-------+---------+--------
0000 | 1111 | 0000 | false
0001 | 0000 | 0000 | false
0010 | 0001 | 0000 | false
0011 | 0010 | 0010 | true
.... | .... | .... | ....
1000 | 0111 | 0000 | false
1001 | 1000 | 1000 | true
1010 | 1001 | 1000 | true
1011 | 1010 | 1010 | true
1100 | 1011 | 1000 | true
1101 | 1100 | 1100 | true
1110 | 1101 | 1100 | true
1111 | 1110 | 1110 | true
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
32747 次 |
最近记录: |