-22

我有一个整数数组,我想计算有多少not 1数字:

int* t = new int[50];
int counter = 1;
for(int i = 0; i < 50; i++){
    t[i] = i % 10;
    if((memcmp((void*)t[i], (void*)1, 4) != 0)){
        counter++;
    }
}

但我明白了adress violation。如何让它工作......快速工作。你知道更快的解决方案,而不是标准的解决方案。请不要t[i]==1

编辑:因为我在程序中使用了大小数组,362856427我想让它变得简单。

4

4 回答 4

5

为什么不这样做:

int *t = new int[50];
int counter = 0; // <-- Shouldn't it be "0" at the beginning?
for (int i = 0; i < 50; i++) {
  if (t[i] != 1) {
    counter++;
  }
}
于 2013-05-05T14:56:53.303 回答
2

您正在将 1 类型转换为地址。这意味着您是在地址 1 上进行比较,而不是在地址 1 上进行比较。您的解决方案是创建int one = 1;,然后&one替换(void*)1.

于 2013-05-05T14:54:18.057 回答
1

TL;DR:以明显的方式进行,并确保您的编译器对其进行了优化。


如果没有完整的、可重现的程序示例,就很难推断性能。所以让我们从一个简单的实现开始:

#include <array>
#include <algorithm>

std::array<int, 362856427> a = {};

int main()
{
    a[500] = 1;
    a[5000] = 1;
    a[50000] = 1;
    a[500000] = 1;

    auto counter = 0u;
    for (auto i = 0u; i < a.size(); ++i) {
    if (a[i] != 1)
        ++counter;
    }

    return counter != 362856423;
}

计时,我得到了 1.79 秒的用户时间。然后我意识到我的错误,并添加-O3到我的编译命令中。这更好:

g++ -std=c++17 -g -Wall -Wextra -O3  16385733.cpp -o 16385733
time ./16385733 
0.07user 0.08system 0:00.16elapsed 98%CPU (0avgtext+0avgdata 2212maxresident)k

我们可以尝试简化循环,但这并没有明显的区别(优化器已经击败了我们):

for (auto i = 0u;  i < a.size();  ++i)
    counter += a[i] != 1;

另一种选择是通过使用标准算法使代码更清晰:

auto counter = a.size() - std::count(a.begin(), a.end(), 1);

这始终比明显的循环花费 50% 的时间。

如果您的输入数组要大得多,您可以通过像这样并行化计算来获得收益:

     auto counter = 0ul;
#pragma omp parallel for reduction(+:counter)
    for (auto i = 0ul;  i < a.size();  ++i)
        counter += a[i] != 1;

我的基准测试表明,当数组大小为 362856427 时,它与标准算法一样慢,而当它增加到 3628564270 时,速度不会更快。

有几种方法可以以等效形式重写:

    for (auto i: a)
        counter += i != 1;
    for (auto p = a.data();  p < end;  ++p)
        counter += *p != 1;

所有这些都表现出相似的性能,并且没有通过 OpenMP 得到改进。

所以简短的回答是

  • 以明显的方式做
  • 确保您的编译器正在优化,并且
  • 对您的替代方案进行基准测试。
于 2017-04-05T10:09:31.113 回答
0

在 C++1x 中,您可以使用std::count

const int N = 50;
int* t = new int[N];
int counter = N - std::count(t, t+N, 1);
于 2020-12-04T19:49:30.340 回答