我已经编写了一个程序,它使用用C++11编写的除法和征服算法来计算倒置的数量。
#include <iostream>
#include <tuple>
#include <vector>
using IntVec = std::vector<int>;
std::tuple<IntVec, long long> count_inv(IntVec xs);
std::tuple<IntVec, long long> count_split_inv(IntVec xs, IntVec ys);
std::tuple<IntVec, long long> count_inv(IntVec xs) {
int n = xs.size();
if (n < 2) return std::make_tuple(xs, 0);
IntVec::iterator middle = xs.begin() + (n / 2);
IntVec left(xs.begin(), middle);
IntVec right(middle, xs.end());
long long left_inv, right_inv, split_inv;
IntVec as, bs, cs;
std::tie(as, left_inv) = count_inv(left);
std::tie(bs, right_inv) = count_inv(right);
std::tie(cs, split_inv) = count_split_inv(as, bs);
return std::make_tuple(cs, left_inv + right_inv + split_inv);
}
std::tuple<IntVec, long long> count_split_inv(IntVec xs, IntVec ys) {
int n = xs.size() + ys.size();
IntVec zs(n);
long long split_inv = 0;
int i = 0, j = 0, k = 0;
for (; k < n && i < xs.size() && j < ys.size(); ++k) {
if (xs[i] <= ys[j]) {
zs[k] = xs[i];
++i;
} else {
zs[k] = ys[j];
++j;
split_inv += xs.size() - i;
}
}
for (; i < xs.size(); ++k, ++i)
zs[k] = xs[i];
for (; j < ys.size(); ++k, ++j)
zs[k] = ys[j];
return std::make_tuple(zs, split_inv);
}
int main() {
std::vector<int> xs;
int x;
while (std::cin >> x) {
xs.push_back(x);
}
IntVec ys;
long long inv;
std::tie(ys, inv) = count_inv(xs);
std::cout << inv << std::endl;
return 0;
}我发现代码在某些方面非常冗长,比如指定元组的类型。而且,它的一部分是令人困惑的。我怎样才能重写这段代码,使它更简洁、更清晰?
发布于 2015-10-30 08:50:49
如果您通过引用每个函数传递一个计数,并且每个函数都增加了这个计数,而不是在元组中返回一个新的计数,那么代码看起来可能更干净。例如,这是:
IntVec as,bs,cs;std::tie(as,left_inv) =count_inv(左);std::tie(bs,right_inv) =count_inv(右);std::tie(cs,split_inv) = count_split_inv(as,bs);返回std::make_tuple(cs,left_inv + right_inv + split_inv);
会变成这样:
IntVec as = count_inv(left, count);
IntVec bs = count_inv(right, count);
return count_split_inv(as, bs, count);在main()中,这个:
long long inv;
std::tie(ys, inv) = count_inv(xs);会变成这样:
long long inv = 0;
count_inv(xs, inv);https://codereview.stackexchange.com/questions/108671
复制相似问题