当前位置: 首页 > 知识库问答 >
问题:

数学组合的完美最小散列

安高义
2023-03-14

首先,定义两个整数nk,其中n>=k,两者在编译时都已知。例如:n=8k=3

接下来,定义一组整数[0,N)(或者[1,N],如果这使答案更简单的话),并将其称为S。例如:{0,1,2,3,4,5,6,7}

具有K元素的S子集的数目由公式C(N,K)给出。例

我的问题是:为这些子集创建一个完美的最小哈希。示例哈希表的大小为C(8,3)56

我不关心排序,只关心哈希表中有56个条目,并且我可以从一组k整数中快速确定哈希。我也不在乎可逆性。

哈希示例:哈希({5,2,3})=42。(数字42并不重要,至少在这里不重要)

是否有一种通用算法可以处理nk的任何值?我无法通过搜索谷歌找到一个,或者我自己天真的努力。

共有1个答案

东门宜
2023-03-14

有一种算法可以用给定的固定k按照所有组合的词典顺序将组合编码和解码成其编号。对于组合的编码和解码,该算法与n线性。你对什么语言感兴趣?

Edit:下面是C++中的示例代码(它根据n个元素的所有组合的顺序创建一个组合的词典编号,而不是使用k元素的组合,但它确实是一个很好的起点):

typedef long long ll;

// Returns the number in the lexicographical order of all combinations of n numbers
// of the provided combination. 
ll code(vector<int> a,int n)
{
    sort(a.begin(),a.end());
    int cur = 0;
    int m = a.size();

    ll res =0;
    for(int i=0;i<a.size();i++)
    {
        if(a[i] == cur+1)
        {
            res++;
            cur = a[i];
            continue;
        }
        else
        {
            res++;
            int number_of_greater_nums = n - a[i];
            for(int j = a[i]-1,increment=1;j>cur;j--,increment++)
                res += 1LL << (number_of_greater_nums+increment);
            cur = a[i];
        }
    }
    return res;
}
// Takes the lexicographical code of a combination of n numbers and returns the 
// combination
vector<int> decode(ll kod, int n)
{
    vector<int> res;
    int cur = 0;

    int left = n; // Out of how many numbers are we left to choose.
    while(kod)
    {
        ll all = 1LL << left;// how many are the total combinations
        for(int i=n;i>=0;i--)
        {
            if(all - (1LL << (n-i+1)) +1 <= kod)
            {
                res.push_back(i);
                left = n-i;
                kod -= all - (1LL << (n-i+1)) +1;
                break;
            }
        }
    }
    return res;
}

我很抱歉我现在有一个算法来解决你现在问的问题,但我相信这将是一个很好的练习,试图理解我在上面做了什么。事实上,这是我在“算法的设计和分析”课程中教授的算法之一,这就是为什么我要预先编写它。

 类似资料:
  • 给定一个边带权的无向图和两个顶点s和t,权是非负的。最短偶路径问题是寻找一条边数为偶数且总权尽可能小的s,t-路径P。如何将最短均匀路径问题转化为最小权完美匹配问题

  • 给出不同整数的列表 我的想法:< br >一种简单的方法是一个接一个地选择一个元素,看看它形成的完美子集的大小,然后我们可以简单地返回最大值。这将是计算密集型的。< br >有什么好的解决方案吗

  • 把一个int型数组中的数字拼成一个串,这个串代表的数字最小。 #思路说明 对这个问题的理解: 有一个元素是int类型的list; 将上述list中的每个元素的数字分别取出来,然后将这些数字的顺序进行从新排列,并将其中的最小整数输入,就是题目中要求的最小数字。 如果按照上述理解,在解题中,最应当小心的是数字如果很大,比如list中的某个int元素是:2222222222222277777777777

  • 我正在尝试使用 中的 和 制作地图,其中一组点数据使用连续比例(-1 到 1)着色,一组线数据使用离散比例(a,b,c,d)着色。但是,当我在同一张地图中同时使用离散和连续美学时,我遇到了麻烦。这里发布了一个类似的问题,但它没有涉及映射美学。 下面是一个简化的示例: 很明显,连续(点数据)和离散(线数据)美学之间存在冲突,但我如何每次调用为每个数据集使用不同的颜色美学?使用<code>inheri

  • 我碰到了R的< code>range函数。它确实是一个有用的工具,并使代码更具可读性,但是如果用一个简单的包含< code>min和< code>max的一行程序来代替它,它的速度可以提高一倍。 我做了一些基准测试,range函数的“糟糕”性能让我吃惊。为了进行比较,我编写了一个名为< code>range2的函数,它使用了min和max(参见代码)。除了速度之外,如果一个简单的一行程序可以胜过这

  • 题目描述: 给一个数组,数组里面都是代表非负整数的字符串,将数组里所有的数值排列组合拼接起来组成一个数字,输出拼接成的最小的数字。 输入描述: 一个数组,数组不为空,数组里面都是代表非负整数的字符串,可以是0开头,例如:["13", "045", "09", "56"]。 数组的大小范围:[1, 50] 数组中每个元素的长度范围:[1, 30] 输出描述: 以字符串的格式输出一个数字,如果最终结果