HiveBrain v1.2.0
Get Started
← Back to all entries
patterncppMinor

Divide and Conquer algorithm for counting inversions

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
dividecountinginversionsalgorithmforandconquer

Problem

I've written a program that counts the number of inversions using a Divide and Conquer algorithm, written in C++11.

#include 
#include 
#include 

using IntVec = std::vector;

std::tuple count_inv(IntVec xs);
std::tuple count_split_inv(IntVec xs, IntVec ys);

std::tuple count_inv(IntVec xs) {
    int n = xs.size();

    if (n  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  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;
}


I find that the code is very verbose in some areas, such as specifying the type of the tuple. Also, parts of it are confusing. How could I rewrite this code such that it is more concise and clearer?

Solution

More clear by using extra argument?

If you passed in a count by reference to each function, and each function incremented this count instead of returning a new count in a tuple, the code might look cleaner. For example, this:

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);


would become this:

IntVec as = count_inv(left, count);
IntVec bs = count_inv(right, count);
return count_split_inv(as, bs, count);


And in main(), this:

long long inv;
std::tie(ys, inv) = count_inv(xs);


would become this:

long long inv = 0;
count_inv(xs, inv);

Code Snippets

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);
IntVec as = count_inv(left, count);
IntVec bs = count_inv(right, count);
return count_split_inv(as, bs, count);
long long inv;
std::tie(ys, inv) = count_inv(xs);
long long inv = 0;
count_inv(xs, inv);

Context

StackExchange Code Review Q#108671, answer score: 2

Revisions (0)

No revisions yet.