C++ C++;:使用数组创建函数
编写一个具有以下功能的函数:C++ C++;:使用数组创建函数,c++,C++,编写一个具有以下功能的函数: input: array of pairs (unique id and weight) length of N, K =< N output: K random unique ids (from input array) 输入:对数组(唯一id和权重)长度为N,K=i)输入权重中减去权重,并求和权重 将输入[i]移动到位置[n-1](将中间的元素向下滑动一个插槽)。这是一个昂贵的部分,因为它是O(n),我们要做K次。您可以在最后一次迭代中跳过这一步
input: array of pairs (unique id and weight) length of N, K =< N
output: K random unique ids (from input array)
输入:对数组(唯一id和权重)长度为N,K=
注意:被多次调用在输出中出现某些Id的频率应该越高,它的权重就越大。
示例:权重为5的id在输出中出现的频率应该是权重为1的id的5倍。此外,分配的内存量应在编译时已知,即不应分配额外的内存
我的问题是:如何解决这个任务
编辑谢谢大家的回复
目前,我无法理解配对的重量如何影响配对在输出中的出现频率,您能给我更清楚的“for dummy”解释它是如何工作的吗?好的,因此您得到如下输入:
(3, 7)
(1, 2)
(2, 5)
(4, 1)
(5, 2)
您希望选择一个随机数,以便每个id的权重反映在选择中,即从以下列表中选择一个随机数:
3 3 3 3 3 3 3 1 1 2 2 2 2 2 4 5 5
最初,我创建了一个临时数组,但这也可以在内存中完成,您可以通过将所有权重相加=X来计算列表的大小,在本例中为=17
在[0,X-1]之间选择一个随机数,通过循环列表,对权重进行累加,计算应该返回哪个id。假设我有一个随机数8
(3, 7) total = 7 which is < 8
(1, 2) total = 9 which is >= 8 **boom** 1 is your id!
这是一个好问题:)此解决方案适用于非整数权重,并使用常量空间(即:空间复杂度=O(1))。不过,它确实修改了输入数组,但最后唯一的区别是元素的顺序不同
- 将每个输入的权重添加到以下输入的权重中,从底部开始逐步向上。现在,每个权重实际上是该输入的权重和之前所有权重的总和
- sum_weights=所有权重之和,n=n
- K次:
- 选择范围为[0,加权和]的随机数r
- 二进制搜索(现在求和)权重大于或等于r,i的第一个插槽的前n个元素
- 将输入[i].id添加到输出
- 减去输入[i-1]。从输入[i]中减去权重。权重(除非i==0)。现在减去输入[i]。从以下(>i)输入权重中减去权重,并求和权重
- 将输入[i]移动到位置[n-1](将中间的元素向下滑动一个插槽)。这是一个昂贵的部分,因为它是O(n),我们要做K次。您可以在最后一次迭代中跳过这一步
- 从n中减去1
- 通过减去前面输入的权重,将所有权重从n-1减到1
- 将每个输入的权重添加到下一个输入的权重中,从底部开始向上计算。现在每个权重实际上是该输入的权重和之前所有权重的总和
- sum_weights=所有权重之和,n=n
- K次:
- 选择范围为[0,加权和]的随机数r
- 二进制搜索(现在求和)权重大于或等于r,i的第一个插槽的前n个元素
- 将输入[i].id添加到输出
- 通过减去前面输入的权重,将所有权重从n-1减到1
时间复杂度为O(K*log(N))。假设有足够好的随机数生成器:
- 将重量相加(
)总重量
- 重复K次:
- 选择一个介于0和
之间的数字(总重量
)选择
- 查找从数组开始到该对的所有权重之和大于或等于
选择的第一对
- 将该对的第一部分写入输出
- 选择一个介于0和
您需要足够的存储空间来存储总重量。我确实假设输出中的ID必须是唯一的。这使得此问题成为随机采样问题的一个特定实例 我能想到的第一种方法是在O(N^2)时间内解决这个问题,使用O(N)内存(输入数组本身加上常量内存)。 我假设权重是正的 设A为对的数组 1) 将N设置为A长度 2) 计算所有权重W的总和 3) 循环K次 3.1)r=rand(0,W)
3.2)在A上循环并找到第一个索引i,这样A[1].w+…+A[i].w我的简短回答是:绝对不会 仅仅因为问题定义不正确。正如我们所注意到的:
需求中有一点矛盾。它表明K您的问题到底是什么?结果ID的顺序重要吗?即[1,2]和[2,1]被认为是不同的结果?@Sergey,@javamonkey79请求可能没有明确说明,但我认为很明显:回答这个面试问题。要求中有一点矛盾。它说明K更正:没有有趣的面试问题。@Vic没有“将原始数组的副本创建到hastable中”打破了“分配的内存数量在编译时应该是已知的,即不应该分配额外的内存”的要求,这是O(NK),并且您正在为哈希表分配内存,OP说这是不允许的(我想他指的是O(1)空间)
O(n) : create copy of original array into hastable +
(
O(n) : calculate sum of weights +
O(1) : calculate random between range +
O(n) : cumulative totals
) * K random pickings
= O(n*k) overall
#include <iostream>
#include <cstdlib>
#include <ctime>
// 0 - id, 1 - weight
typedef unsigned Pair[2];
unsigned Random(Pair* i_set, unsigned* i_indexes, unsigned i_size)
{
unsigned sumOfWeights = 0;
for (unsigned i = 0; i < i_size; ++i)
{
const unsigned index = i_indexes[i];
sumOfWeights += i_set[index][2];
}
const unsigned random = rand() % sumOfWeights + 1;
sumOfWeights = 0;
unsigned i = 0;
for (; i < i_size; ++i)
{
const unsigned index = i_indexes[i];
sumOfWeights += i_set[index][3];
if (sumOfWeights >= random)
{
break;
}
}
return i;
}
template<unsigned N, unsigned K>
void Generate(Pair (&i_set)[N], unsigned (&o_res)[K])
{
unsigned deck[N];
for (unsigned i = 0; i < N; ++i)
{
deck[i] = i;
}
unsigned max = N - 1;
for (unsigned i = 0; i < K; ++i)
{
const unsigned index = Random(i_set, deck, max + 1);
std::swap(deck[max], deck[index]);
o_res[i] = i_set[deck[max]][0];
--max;
}
}
int main()
{
srand((unsigned)time(0));
const unsigned c_N = 5; // N
const unsigned c_K = 2; // K
Pair input[c_N] = {{0, 5}, {1, 3}, {2, 2}, {3, 5}, {4, 4}}; // input array
unsigned result[c_K] = {};
const unsigned c_total = 1000000; // number of iterations
unsigned counts[c_N] = {0}; // frequency counters
for (unsigned i = 0; i < c_total; ++i)
{
Generate<c_N, c_K>(input, result);
for (unsigned j = 0; j < c_K; ++j)
{
++counts[result[j]];
}
}
unsigned sumOfWeights = 0;
for (unsigned i = 0; i < c_N; ++i)
{
sumOfWeights += input[i][1];
}
for (unsigned i = 0; i < c_N; ++i)
{
std::cout << (double)counts[i]/c_K/c_total // empirical frequency
<< " | "
<< (double)input[i][1]/sumOfWeights // expected frequency
<< std::endl;
}
return 0;
}
N = 5, K = 2
Frequencies
Empiricical | Expected
0.253813 | 0.263158
0.16584 | 0.157895
0.113878 | 0.105263
0.253582 | 0.263158
0.212888 | 0.210526
N = 5, K = 5
Frequencies
Empiricical | Expected
0.2 | 0.263158
0.2 | 0.157895
0.2 | 0.105263
0.2 | 0.263158
0.2 | 0.210526