/*******************************************************************
Copyright(c) 2016, Tyrone Li
All rights reserved.
*******************************************************************/
// 作者:TyroneLi
//
/*
Q:
数组中的逆序对:
在数组中的两个数字如果前面一个数字大于后面的数字,则这样的两个数字组成一个逆序对。
要求实现输入一个数组,求出这个数组中的逆序对的总数。
S:
1. 把数组划分成子数组,统计出子数组内的逆序对数目,然后统计相邻的子数组之间的逆序对数目,
在统计过程中还需要对数组进行排序。
*/
#include <iostream>
#include <cstdio>
#include <cstdlib>
int countInversePairs(int*num, int*copy, int start, int end)
{
if(start == end)
{
copy[start] = num[start];
return 0;
}
int length = (end - start) / 2;
// 这里传入的num和copy反序是因为?
int left = countInversePairs(copy, num, start, start+length);
int right = countInversePairs(copy, num, start+length+1, end);
int i = start + length;
int j = end;
int indexCopy = end;
int count = 0;
while(i >= start && j >= (start+length+1))
{
if(num[i] > num[j])
{
copy[indexCopy--] = num[i--];
count += (j - start - length);
}else{
copy[indexCopy--] = num[j--];
}
}
for(; i >= start; --i)
copy[indexCopy--] = num[i];
for(; j >= (start+length+1); --j)
copy[indexCopy--] = num[j];
return left+right+count;
}
int inversePairs(int*num, int length)
{
if(num == nullptr || length <= 0)
return 0;
int*copy = new int[length];
for(int i = 0; i < length; ++i)
copy[i] = num[i];
int rst = countInversePairs(num, copy, 0, length-1);
delete[] copy;
return rst;
}
void test_1()
{
std::cout << "Test 1" << std::endl;
int num[] = {7,5,6,4};
std::cout << "Input : " << std::endl;
for(auto e:num)
std::cout << e << " ";
std::cout << std::endl;
std::cout << "count inverse pair : " << inversePairs(num, 4) << std::endl;
}
void test_2()
{
std::cout << "Test 2" << std::endl;
int num[] = {4,5,6,7};
std::cout << "Input : " << std::endl;
for(auto e:num)
std::cout << e << " ";
std::cout << std::endl;
std::cout << "count inverse pair : " << inversePairs(num, 4) << std::endl;
}
void test_3()
{
std::cout << "Test 3" << std::endl;
int num[] = {7,6,5,4};
std::cout << "Input : " << std::endl;
for(auto e:num)
std::cout << e << " ";
std::cout << std::endl;
std::cout << "count inverse pair : " << inversePairs(num, 4) << std::endl;
}
void test_4()
{
std::cout << "Test 4" << std::endl;
int num[] = {4,5,6,4};
std::cout << "Input : " << std::endl;
for(auto e:num)
std::cout << e << " ";
std::cout << std::endl;
std::cout << "count inverse pair : " << inversePairs(num, 4) << std::endl;
}
void test_5()
{
std::cout << "Test 5" << std::endl;
int num[] = {7,5};
std::cout << "Input : " << std::endl;
for(auto e:num)
std::cout << e << " ";
std::cout << std::endl;
std::cout << "count inverse pair : " << inversePairs(num, 2) << std::endl;
}
void test_6()
{
std::cout << "Test 6" << std::endl;
int num[] = {7};
std::cout << "Input : " << std::endl;
for(auto e:num)
std::cout << e << " ";
std::cout << std::endl;
std::cout << "count inverse pair : " << inversePairs(num, 1) << std::endl;
}
void test_inversePairs()
{
test_1();
test_2();
test_3();
test_4();
test_5();
test_6();
}
int main(int argc, char**argv)
{
test_inversePairs();
return 0;
}