【问题标题】:About hash functions关于哈希函数
【发布时间】:2012-11-01 18:33:06
【问题描述】:

让我们考虑一个双向数组,声明如下:

#include <stdbool.h>

bool array[N1][N2];

我必须知道这个数组的每一行是否在同一位置恰好有一个true 值。

例如下面的就可以了:

{ 
  { 1, 0, 1, 0 },
  { 1, 0, 0, 1 },
  { 0, 0, 1, 1 }
}

这是不正确的:

{ 
  { 1, 0, 1, 0 },
  { 1, 0, 1, 0 },
  { 0, 0, 1, 1 }
}

我试过了:

static uintmax_t hash(const bool *t, size_t n) 
{
    uintmax_t retv = 0U;
    for (size_t i = 0; i < n; ++i)
        if (t[i] == true)
            retv |= 1 << i;
    return retv;
}

static int is_valid(bool n) 
{ 
    return n != 0 && (n & (n - 1)) == 0;
}

bool check(bool t[N1][N2])
{
    uintmax_t thash[N1];

    for (size_t i = 0; i < N1; ++i)
        thash[i] = hash(t[i], N2);

    for (size_t i = 0; i < N1; ++i)
        for (size_t j = 0; j < N1; ++j)
            if (i != j && !is_valid(thash[i] & thash[j]))
                return 0;

    return 1;
}

但它只适用于N1 &lt;= sizeof(uintmax_t) * CHAR_BIT。你知道解决它的最佳方法吗?

【问题讨论】:

  • 哎呀,我想我没有很好地解释我的问题。我会编辑。

标签: c algorithm hash


【解决方案1】:

为什么不直接创建另一个大小为 N2(列数)的数组,将其设置为全部 true,然后将其设置为每行中的每一列 and。最后,检查你的新数组是否正好有一个设置位。

bool array[N1][N2];  // this is initialized somehow
bool result[N2];
int i, j;

// initialize result array
for (j = 0; j < N2; ++j)
{
    result[j] = 1;
}

// Now go through the array, computing the result
for (i = 0; i < N1; ++i)
{
    for (j = 0; j < N2; ++j)
    {
        result[j] &= array[i][j];
    }
}

// At this point, you can check the result array.
// If your array is valid, then result should have only one '1' in it.

【讨论】:

    【解决方案2】:

    不要将位打包成整数。相反,检查每两个相邻的行 ii+1 并求和 !(a[i][j] ^ a[i+1][j])(两行中位的 XOR 的非)。每行的总和必须正好为 1。

    请注意,我使用的是逻辑 not,而不是按位 not。我不想得到 -1s(按位不是 0)。

    【讨论】:

    • 这是不正确的,如果行相同(零个或多个true)总和将为零。
    猜你喜欢
    • 1970-01-01
    • 2016-04-17
    • 2016-03-25
    • 2011-02-27
    • 1970-01-01
    • 1970-01-01
    • 2011-08-04
    • 2011-07-10
    • 2022-01-03
    相关资源
    最近更新 更多