-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtopk.cpp
More file actions
120 lines (110 loc) · 3.02 KB
/
topk.cpp
File metadata and controls
120 lines (110 loc) · 3.02 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
#include <vector>
#include <queue>
#include <algorithm>
#include <utility>
#include <cassert>
#include<iostream>
using namespace std;
// ---------- 1) 数组版本:保留降序前 k 大 ----------
void topk_desc_array(double *s, int *address, int n, int k)
{
if (!s || !address || n <= 0 || k <= 0)
return;
if (k > n)
k = n;
using Node = pair<double, int>; // {值, 地址}
// 小根堆(堆顶是当前 top-k 中最小的那个)
auto cmp = [](const Node &a, const Node &b)
{ return a.first > b.first; };
priority_queue<Node, vector<Node>, decltype(cmp)> heap(cmp);
for (int i = 0; i < n; ++i)
{
if ((int)heap.size() < k)
{
heap.emplace(s[i], address[i]);
}
else if (s[i] > heap.top().first)
{
heap.pop();
heap.emplace(s[i], address[i]);
}
}
// 取出并按降序排好,得到与“全量降序后取前k”的同序结果
vector<Node> topk;
topk.reserve(k);
while (!heap.empty())
{
topk.push_back(heap.top());
heap.pop();
}
sort(topk.begin(), topk.end(), [](const Node &a, const Node &b)
{
return a.first > b.first; // 降序
});
for (int i = 0; i < k; ++i)
{
s[i] = topk[i].first;
address[i] = topk[i].second;
}
}
// ---------- 2) 向量版本:保留升序前 k 小 ----------
void topk_asc_vector(vector<double> &s, vector<int> &address, int k)
{
int n = (int)s.size();
assert((int)address.size() == n);
if (n <= 0 || k <= 0){return;}
if (k > n){k = n;}
struct Node
{
double v;
int id;
// 默认优先队列是大根堆;为了“保留最小的 k 个”,我们让堆顶是当前 top-k 中最大的
bool operator<(const Node &o) const { return v < o.v; } // v 大的更“优先”
};
priority_queue<Node> heap; // 大根堆(堆顶是最大)
for (int i = 0; i < n; ++i)
{
if ((int)heap.size() < k)
{
heap.push(Node{s[i], address[i]});
}
else if (s[i] < heap.top().v)
{
heap.pop();
heap.push(Node{s[i], address[i]});
}
}
vector<Node> topk;
topk.reserve(k);
while (!heap.empty())
{
topk.push_back(heap.top());
heap.pop();
}
sort(topk.begin(), topk.end(), [](const Node &a, const Node &b)
{
return a.v < b.v; // 升序
});
for (int i = 0; i < k; ++i)
{
s[i] = topk[i].v;
address[i] = topk[i].id;
}
}
int main(){
vector<double> s={1,2,4,3,0};
vector<int> address={0,1,2,3,4};
int k=2;
topk_asc_vector(s,address,k);
// for(auto x:address){
// cout<<x<<' ';
// }
vector<double> topk_check_delay;
// topk_check_delay.resize(2);
topk_check_delay.push_back(1.2);
topk_check_delay.push_back(1.2);
topk_check_delay.resize(1);
cout<<topk_check_delay.size()<<' ';
cout<<topk_check_delay[0]<<endl;
return 0;
}