[英]Logical operation between all elements in array
我想以最有效的方式使用布爾運算符比較數組中的所有項目。 目前,我有這樣的事情:
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循環並遍歷每個元素,然后將列表中下一項的值與前兩項的存儲結果進行比較。 就像一些按位運算符可以使此操作變得容易一樣,任何東西都可以消除循環。
您可以使用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 :例如,它具有執行此操作的算法 。
template<typename T >
T af::allTrue( const array & in )
//C++ Interface for checking if all values in an array are true.
您可能需要知道&=
不是邏輯運算符; 它是“按位與”運算符。 只要您僅在布爾值上使用它,我想它就可以正常工作。 但是C不會阻止1或0以外的其他值滑入數組,因此您可能不應該做這個假設。 從語義上來說,如果您正在做邏輯運算,或者您想用&&
代替&
。
也就是說,您當然可以使用短路來完善您正在做的事情。 一旦找到單個0(假),此后的任何事情都不會使聚合返回1(真),因此您最好停止。
for (int a = 1; result && a < i; ++a)
{
result &= myArray[i];
}
除此之外,您沒有什么可以改善的地方。 不知道為什么不喜歡循環,但是如果您想組合未知數量的值,則必須進行迭代。 您可能會找到(或編寫)一些實用程序函數來執行此操作,但是無論如何它都會在內部使用循環。 (除非它試圖利用向量處理器本來可以執行您想要的操作,也許……但是那將是毫無意義的,並且,如果您確實沒有值的數量限制,那么仍然會涉及到循環。)
一旦遇到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;
如果編譯器尚未應用它,那么此函數將確定會應用。 另一方面,這可能會使優化程序更難展開循環,因此您必須在生成的匯編代碼中進行驗證...
您可以使用all_of
(如果要檢查整個數組而不是第一個i
元素,請用std::end(myArray)
替換std::begin(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; });
}
我會更改for循環的條件,因此,如果遇到錯誤的值並使用迭代器而不是索引,則不會繼續。
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;
}
或者,如果您真的更喜歡使用index:
bool myFunction(int i) {
bool myArray[i] = //some other array of bools
//should workwith any value of i
bool result;
unsigned int a;
for (a = 0, result = myArray[a]; a < i && result; result=myArray[++i]) {}
//no need to use the AND operator since we stop if we meet one false
return result;
}
也許我是錯的,但是如果不在位范圍操作上,我就不會使用按位AND賦值(&=),盡管它與布爾類型實際上並不相關。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.