首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >倒置计数的除法和征服算法

倒置计数的除法和征服算法
EN

Code Review用户
提问于 2015-10-25 14:57:46
回答 1查看 953关注 0票数 4

我已经编写了一个程序,它使用用C++11编写的除法和征服算法来计算倒置的数量。

代码语言:javascript
运行
复制
#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;
}

我发现代码在某些方面非常冗长,比如指定元组的类型。而且,它的一部分是令人困惑的。我怎样才能重写这段代码,使它更简洁、更清晰?

EN

回答 1

Code Review用户

发布于 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);

会变成这样:

代码语言:javascript
运行
复制
IntVec as = count_inv(left, count);
IntVec bs = count_inv(right, count);
return count_split_inv(as, bs, count);

main()中,这个:

代码语言:javascript
运行
复制
long long inv;
std::tie(ys, inv) = count_inv(xs);

会变成这样:

代码语言:javascript
运行
复制
long long inv = 0;
count_inv(xs, inv);
票数 2
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/108671

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档