是否可以将数组元素与没有循环的硬编码初始化列表进行比较? [关闭]
Posted
技术标签:
【中文标题】是否可以将数组元素与没有循环的硬编码初始化列表进行比较? [关闭]【英文标题】:Is it possible to compare an array elements with a hard-coded initializer list without loop? [closed] 【发布时间】:2020-02-12 09:18:07 【问题描述】:[更新]此问题适用于 C 和 C++
我正在尝试找到一种优化的方法来比较一个数组和一些文字值(幻数),而不用遍历整个数组并逐个元素地比较。例如:
int arr[3] = 1, 2, 3; // or std::array<int, 3> arr1, 2, 3 in C++;
if (1, 2, 3 == arr) // of course not a valid expression, but what expression can be valid instead?
/* true condition */
有可能吗?还是只能在 C++ 中通过声明另一个 std::array 并将它们进行比较如下:
std::array<int, 3> arr11, 2, 3;
const std::array<int, 3> arr21, 2, 3;
if (arr1 == arr2)
/* true condition */
【问题讨论】:
std::array
不是 C 而是 C++,选择 一种 语言。
std::arr1<int,3>1, 2, 3;
语法无效。
“不循环” 就算不写循环,内部也会有。
@L.F.已更正,谢谢告知!
@Jarod42,我把它写成 C 和 C++ 是因为我需要知道在 C 风格编码中是否可行,或者我必须使用 std::array。
【参考方案1】:
在 C 语言中,我想不出比memcmp
更简单的方法。这是一个例子:
int arr[3] = 1, 2, 3;
const int cmp[3] = 1, 2, 3;
if (memcmp(arr, cmp, sizeof(arr))
/* true condition */
请注意,没有防止读取数组外值的保护措施。 memcmp
将比较 sizeof(arr)
字节,因此您必须确保 cmp
具有相同的大小。
无需遍历整个数组并逐个元素进行比较。
那是不可能的。你可以隐藏循环,这样你就看不到它,但如果你想比较两个数组,内部总是会有一个循环。如果你不比较它们,你将如何找出两个元素是否相等?无论你做什么,检查两个数组是否相等都是 O(n)。
有一些方法可以加快速度,例如同时比较 a[0] == b[0]
和 a[1] == b[1]
,但这是特定于架构的,时间复杂度仍然是 O(n)。
【讨论】:
当所有 n 比较同时完成时,它仍然是 O(n) 吗? ;-) @RobertAndrzejuk 是的,因为没有计算机可以同时进行有限数量的比较。 我认为他只想使用运算符 - 而不是函数调用。在 C 中这是不可能的 如果我们是完全严格的,即使是任意数组也是 O(1),因为我们的元素集是有限的(最多std::numeric_limits<size_t>::max()
数组元素 - 只是在开玩笑......)。跨度>
@Aconcagua 实际上,数组的最大大小总是远高于同时操作的最大值。【参考方案2】:
std::array
仅在 C++11 后可用
这应该是可能的:
if (arr == std::array<int,3>1,2,3)
从 C++17 开始,我们有推导指南,所以应该可以:
if (arr == std::array1,2,3)
【讨论】:
这只是隐藏了循环。如果现在仍然是一个可以接受的答案取决于问题作者只是不想明确地编写循环(那么很好),或者她/他是否也想避免任何隐藏的循环(然后失败)...... @Aconcagua 依赖于实现、编译器、优化……。可能是 SIMD 处理器指令? 不仅是实现/编译器,还有 system(需要支持 SIMD 操作)。 和的数组元素个数。从一定数量开始,即使是 SIMD 机器也必须循环。不确定我们是否可以始终假定只有 3 个元素是理所当然的。所以我们必须区分,在特定情况下,我们确实可以在没有循环的情况下相处,一般情况下不会。 数组中只有三个元素,我希望编译器执行循环展开,即使我们有非 SIMD 机器。展开的循环仍然算作循环吗??? @Aconcagua 它会改变可观察到的行为吗?不,所以这是一个循环:-p以上是关于是否可以将数组元素与没有循环的硬编码初始化列表进行比较? [关闭]的主要内容,如果未能解决你的问题,请参考以下文章