priority_queue中的C ++ lambda函数,通过引用捕获

时间:2017-08-14 16:16:17

标签: algorithm lambda comparator priority-queue

我正在解决一个算法问题 - “找到第k个难看的数字”,下面是问题陈述和我的实现。

Write a program to find the n-th ugly number.
Ugly numbers are positive numbers whose prime factors only include 2, 3, 5. 
For example, 1, 2, 3, 4, 5, 6, 8, 9, 10, 12 is the sequence of the first 10 ugly numbers.

vector<int> tmp(1,1);
vector<int> primes({2,3,5});
vector<int> indices(3, 0);
// lambda function pass in variables are captured by reference
priority_queue<int, vector<int>, function<bool(const int&, const int&)>> pq([&](const int& a, const int& b){
    return primes[a] * tmp[indices[a]] > primes[b] * tmp[indices[b]];
});
pq.push(0); pq.push(1); pq.push(2);
while(tmp.size() <= 3) { // find the first three ugly number
    int primeIndex = pq.top();
    pq.pop();
    int nextval = primes[primeIndex] * tmp[indices[primeIndex]];
    pq.push(primeIndex + 1);
    indices[primeIndex]++;

    while(!pq.empty() && primes[pq.top()] & tmp[indices[pq.top()]]) {
        primeIndex = pq.top();
        pq.pop();
        pq.push(primeIndex + 1);
        indices[primeIndex]++;
    }
    cout << nextval << endl;
    tmp.push_back(nextval);
}
return 0;

priority_queue的使用是此解决方案的优化。 Priority_queue在O(logN)时间内找到“下一个丑陋”的数字。 priority_queue使用primes []的索引作为其元素。它使用lambda函数作为比较器,并通过引用捕获所有外部变量。我测试了我的代码输出前3个丑陋的数字(应该是2,3,4),但是我的代码给了我“2,6,0”。我认为我的lambda函数在priority_queue中有问题,但我找不到原因。任何人都可以给我一个解决我的错误的提示吗?非常感谢你。

1 个答案:

答案 0 :(得分:0)

您的代码的直接问题是您正在访问tmp向量越界。您使用indices的元素作为tmp的索引,并在外部while循环的迭代中的多个位置递增indices的元素(在内部while循环之前一次,并且可能在内部while循环中一次或多次,并且只在外部while循环的迭代结束时增加tmp的大小。与此同时,在内部while循环的条件下,在增加tmp的大小之前,使用可能已增加的索引(可能多次)索引tmp