如何知道数组的值是否由零组成?

时间:2010-02-09 01:28:43

标签: c++ memory-management bytearray

嘿,如果你能得到更具描述性的话,请编辑它。

我正在编写一个涉及检查矩阵中的值的算法。 让我们说:

char matrix[100][100];
char *ptr = &matrix[0][0];

想象一下我用矩阵的几个值(5或6)填充矩阵,如:

matrix[20][35]=1;
matrix[67][34]=1;

我怎么知道矩阵间隔的二进制值是否为零,例如(伪代码)

if((the value from ptr+100 to ptr+200)==0){ ... // do something

我正在尝试再次使用c / c ++。应该有一种方法可以选择那一百个字节(它们彼此相邻)并检查它们的值是否全为零而不必一个检查。(考虑char是一个字节)

6 个答案:

答案 0 :(得分:3)

您可以使用std :: find_if。

bool not_0(char c)
{
    return c != 0;
}

char *next = std::find_if(ptr + 100, ptr + 200, not_0);
if (next == ptr + 200)
    // all 0's

你也可以使用粘合剂来删除自由函数(虽然我认为粘合剂很难阅读):

char *next = std::find_if(ptr + 100, ptr + 200,
                           std::bind2nd(std::not_equal_to<char>(), 0));

Dang,我只是注意到请求不要逐个字节地执行此操作。 find_if仍然会逐字节地执行,尽管它是隐藏的。你必须逐一做到这一点,尽管使用更大的类型会有所帮助。这是我的最终版本。

template <class T>
bool all_0(const char *begin, const char *end, ssize_t cutoff = 10)
{
    if (end - begin < cutoff)
    {
        const char *next = std::find_if(begin, end,
           std::bind2nd(std::not_equal_to<char>(), 0));
        return (next == end);
    }
    else
    {
        while ((begin < end) && ((reinterpret_cast<uintptr_t>(begin) % sizeof(T)) != 0))
        {
            if (*begin != '\0')
                return false;

            ++begin;
        }

        while ((end > begin) && ((reinterpret_cast<uintptr_t>(end) % sizeof(T)) != 0))
        {
            --end;

           if (*end != '\0')
               return false;
        }

        const T *nbegin = reinterpret_cast<const T *>(begin);
        const T *nend = reinterpret_cast<const T *>(end);

        const T *next = std::find_if(nbegin, nend,
           std::bind2nd(std::not_equal_to<T>(), 0));
        return (next == nend);
    }
}

这样做首先检查数据是否足够长,以使其更复杂的算法。我不是100%确定这是必要的,但你可以调整最低限度。

假设数据足够长,它首先对齐开始和结束指针以匹配用于进行比较的类型的对齐。然后它使用新类型来检查大量数据。

我建议使用:

all_0<int>(); // 32 bit platforms
all_0<long>(); // 64 bit LP64 platforms (most (all?) Unix platforms)
all_0<long long>() // 64 bit LLP64 platforms (Windows)

答案 1 :(得分:2)

没有内置的语言功能,也没有标准的库函数。 memcmp()可以工作,但你需要第二个全零的数组来比较;该数组必须很大,并且在进行比较时也会占用不必要的内存带宽。

自己写这个功能,并不难。如果这真的是你的应用程序的瓶颈(你应该只得到 profiling 的结论),那么在程序集中重写该函数。

答案 2 :(得分:1)

你标记了这个C ++,所以你可以使用指针作为迭代器,并使用stl算法。的std ::最大。然后查看max是否为0。

答案 3 :(得分:0)

您可以将指针转换为int *,然后一次检查四个字节而不是一个。

答案 4 :(得分:0)

除了通过逐个检查所有元素之外,无法判断数组是否具有除零之外的任何值。但是如果你从一个你知道全部为零的数组开始,那么你可以保持一个标志来说明数组的零状态。

std::vector<int> vec(SIZE);
bool allzeroes = true;

// ...

vec[SIZE/2] = 1;
allzeroes = false;

// ...

if( allzeroes ) {
    // ...
}

答案 5 :(得分:0)

保留数组的元素0,将其设置为全零。

使用memcmp比较两个元素中的相应范围。