数组

时间:2017-01-31 16:06:36

标签: c++ arrays operators bitwise-operators

我想以最有效的方式使用布尔运算符比较数组中的所有项。目前,我有这样的事情:

bool myFunction(int i) 
{

    bool *myArray = {true, true, false, false, true};
    //suppose we know that i = 5 and that i is the length of the array...
    return myArray[0] && myArray[1] && myArray[2] && myArray[3] && myArray[4];
}

由于数组的大小不固定,'i'的值可以改变,我的return语句将不再有效,所以我必须实现这样的东西

bool myFunction(int i) 
{
    bool *myArray = //some other array of bools
    //should work with any value of i
    bool result = myArray[0];
    for (int a = 1; a < i; ++a)
    {
        result &= myArray[i];
    }
    return result;
}

我想知道除了制作for循环并浏览每个元素并将列表中下一个项目的值与前两个项目的存储结果进行比较之外,是否还有更好的方法可以做到这一点。就像一些按位运算符可以使这个变得容易或者什么东西,任何东西都可以取消循环。

5 个答案:

答案 0 :(得分:0)

您可以使用boost::dynamic_bitset,它有一个成员函数any(),如果设置了此位集中的任何位,它将返回true。如果没有设置位,none()将返回true

any()的实施是:

template <typename Block, typename Allocator>
bool dynamic_bitset<Block, Allocator>::any() const
{
    for (size_type i = 0; i < num_blocks(); ++i)
        if (m_bits[i])
            return true;
    return false;
}

所以你有一个for循环!

但是如果您正在搜索并行计算之类的内容,则可能需要使用arrayfire: 例如,它有一个algorithm

template<typename T >
T af::allTrue(  const array &   in  )   
//C++ Interface for checking if all values in an array are true.

答案 1 :(得分:0)

您可能需要知道&=不是逻辑运算符;它是“按位和”运算符。只要你只在booleans上使用它,我想它会正常工作;但是C不会阻止1或0以外的值滑入数组,所以你可能不应该做出这样的假设。在语义上,如果你做的是合乎逻辑的,或者你想要&&而不是&

那就是说,你当然可以使用短路来改进你正在做的事情。一旦你找到一个0(假),从那时起什么都不会使你的聚合回到1(真),所以你也可以停止。

for (int a = 1; result && a < i; ++a)
{
    result &= myArray[i];
}

除此之外,你可以改进的并不多。不确定为什么你反对循环,但如果你想要组合未知数量的值,你将不得不迭代。您可能会找到(或写入)一些实用程序函数来执行此操作,但无论如何它都将在内部使用循环。 (除非它试图利用原生地执行你想要的矢量处理器,也许......但这将是毫无意义的,如果你真的没有数值限制,那么仍然涉及循环。)

答案 2 :(得分:0)

您可以在遇到false后立即退出循环:

for (int a = 0; a < i; a++)
{
    if (!myArray[i])
        return false;
}
return true;

如果您允许更改数组中的最后一个值,那么这是一个优化它的技巧:

  • 如果数组中的最后一个值为false,则返回false
  • false写入数组的最后一个条目
  • 迭代数组,直到遇到false
  • true写入数组的最后一个条目
  • 如果您在最后一个条目之前停止,则返回false
  • 返回true

代码:

int a;
if (!myArray[i-1])
    return false;
myArray[i-1] = false;
for (a = 0; a < i; a++)
{
    if (!myArray[i])
        break;
}
myArray[i-1] = true;
return a != i-1;

每次迭代产生一个分支,而不是每次迭代产生两个分支。

如果您被允许分配i+1个条目,那么您可以摆脱“最后一个条目交换”部分:

int a;
myArray[i] = false;
for (a = 0; myArray[i]; i++);
return a != i;

您还可以摆脱myArray[i]中嵌入的其他算术:

bool *arrayPtr;
myArray[i] = false;
for (arrayPtr = myArray; *arrayPtr; arrayPtr++);
return arrayPtr != myArray+i;

如果编译器尚未应用它,那么此函数肯定会这样做。另一方面,它可能会使优化器更难以展开循环,因此您必须在生成的汇编代码中验证...

答案 3 :(得分:0)

您可以使用all_of(如果要检查整个数组而不是第一个std::begin(myArray) + i元素,请将std::end(myArray)替换为i

#include <vector>
#include <algorithm>
bool myFunction(int i)
{
    std::vector<bool> myArray = { true, true, false, false, true };
    return std::all_of(std::begin(myArray), std::begin(myArray) + i, [](bool elem) { return elem; });
}

答案 4 :(得分:0)

我会更改你的for循环的条件,这样你就不会在遇到false值时继续使用迭代器而不是索引。

$RemoteComputer = 'computer1.hostname.goes.here'
$ClassPath = "\\$RemoteComputer\ROOT\DEFAULT:StdRegProv"
$HKU = 2147483651

$Keys = Invoke-WmiMethod -Path $ClassPath -Name EnumKey -ArgumentList 2147483651,'' |Select-Object -ExpandProperty sNames

或者如果你真的更喜欢索引:

bool myFunction(int i) {
    bool myArray[i] = //some other array of bools
    //should workwith any value of i

    bool result;
    bool * a;
    for (a = myArray, result = *a; a < myArray+i && result; result=*(++i)) {}
    //no need to use the AND operator since we stop if we meet one false

    return result;
}

也许我错了,但是我不会使用按位AND赋值(&amp; =)如果它不在位范围操作上,它就不是真正相关的但是bool类型。