假设我有一个矢量如下
std::vector<int> v = {3, 9, 7, 7, 2};
我想对这个元素向量进行排序,以便将向量存储为77932.首先,我们存储公共元素(7),然后我们将其余元素从最高到最低排序。
如果我有一个矢量如下
std::vector<int> v = {3, 7, 7, 7, 2};
在这里,它将导致77732.
相同
std::vector<int> v = {7, 9, 2, 7, 9};
它应该导致99772,因为9s高于7s。
最后一个例子
std::vector<int> v = {7, 9, 7, 7, 9};
它应该导致77799,因为7s比9s多。
实现此目的的最快算法是什么?
答案 0 :(得分:5)
使用std::multiset
为您计算。然后使用简单的自定义比较器进行排序,使用std::tie
实现的打破平局逻辑:
std::vector<int> data = {7, 9, 2, 7, 9};
std::multiset<int> count(data.begin(), data.end());
std::sort(
data.begin()
, data.end()
, [&](int a, int b) {
int ca = count.count(a);
int cb = count.count(b);
return std::tie(ca, a) > std::tie(cb, b);
}
);
std::copy(data.begin(), data.end(), std::ostream_iterator<int>(std::cout, " "));
编辑: count(n)
std::multiset
的函数在重复数量上是线性的,这可能会降低排序算法的性能。您可以在其位置使用std::unordered_map
来解决此问题:
std::vector<int> data = {7, 9, 2, 7, 9};
std::unordered_map<int,int> count;
for (auto v : data)
count[v]++;
std::sort(
data.begin()
, data.end()
, [&](int a, int b) {
return std::tie(count[a], a) > std::tie(count[b], b);
}
);
std::copy(data.begin(), data.end(), std::ostream_iterator<int>(std::cout, " "));
答案 1 :(得分:1)
你需要一个辅助频率计数结构,然后你可以定义一个比较器lambda并使用你喜欢的任何类型,std::sort
是一个合理的默认值
std::unordered_map<int, size_t> frequency;
std::for_each(v.begin(), v.end()
, [&](int i) { ++frequency[i]; });
std::sort(v.begin(), v.end()
, [&](int lhs, int rhs)
{
return std::tie(frequency[lhs], lhs) < std::tie(frequency[rhs], rhs);
});
答案 2 :(得分:0)
如果候选人为这项任务提出了辅助地图,我不会感到满意 - 很明显,这种工作的大部分工作,辅助结构应该是一个载体(或者,在我实际尝试之后)实现它,2个向量):
void custom_sort(vector<int> &v)
{
if (v.size() < 2)
return;
sort(v.begin(), v.end(), std::greater<int>());
vector<int> dupl;
vector<int> singl;
int d;
bool dv = false;
for (int i = 1; i < v.size(); ++i)
{
if (!dv)
{
if (v[i - 1] == v[i])
{
d = v[i];
dv = true;
dupl.push_back(d);
}
else
{
singl.push_back(v[i - 1]);
}
}
else
{
dupl.push_back(d);
if (v[i] != d)
dv = false;
}
}
if (!dv)
singl.push_back(v.back());
else
dupl.push_back(d);
auto mid = copy(dupl.begin(), dupl.end(), v.begin());
copy(singl.begin(), singl.end(), mid);
}
但是,是的,分支是棘手的 - 如果你想将它用于更多的inverview,请测试它...: - )
答案 3 :(得分:0)
答案 4 :(得分:0)
有O(N Log(N))算法和额外的O(N)存储器。
Random r = new Random();
int[] array = IntStream.generate(() -> r.nextInt(100)).limit(1000).toArray();
long odd = 0;
long even = 0;
long divisibleBy3 = 0;
long start = System.nanoTime();
//for (int i: array) {
// if (i % 2 == 1) {
// odd++;
// }
// if (i % 2 == 0) {
// even++;
// }
// if (i % 3 == 0) {
// divisibleBy3++;
// }
//}
even = Arrays.stream(array).parallel().filter(x -> x % 2 == 0).toArray().length;
odd = Arrays.stream(array).parallel().filter(x -> x % 2 == 1).toArray().length;
divisibleBy3 = Arrays.stream(array).parallel().filter(x -> x % 3 == 0).toArray().length;
System.out.println(System.nanoTime() - start);