// Sort_and_Count.cpp : 定义控制台应用程序的入口点。
//
#pragma once
#include "stdafx.h"
#include <fstream>
#include <vector>
#include <iostream>
#include <sstream>
using namespace std;
int fileLength = 10000;
int numbers[10000];//存储所有数据的数组
long int inversionCount=0;
void readData(char* filePath){
ifstream fin;
string line;
int oneNumber;
stringstream ss;
fin.open(filePath);
cout<<"开始读文件..."<<endl;
int i=0;
while(getline(fin,line)){
ss<<line;
ss>>oneNumber;
ss.clear();
numbers[i++] = oneNumber;
//cout<<"i="<<i<<endl;
}
cout<<"读文件结束,i="<<i<<endl;
}
void printArray(int left,int right){
for(int i=left;i<=right;i++){
cout<<numbers[i]<<",";
}
cout<<endl;
}
int quickSort(int arrayBegin,int arrayEnd){
//cout<<arrayBegin<<","<<arrayEnd<<endl;
if(arrayBegin>=arrayEnd){
return 0;
}else{
int leftIndex = arrayBegin;
int rightIndex = arrayEnd;
int center = numbers[leftIndex];//选定最左端的元素作为中轴值
int centerIndex = leftIndex;//中轴值的index
while(leftIndex<rightIndex){
//从后向前找,找到比中轴值小的元素,写到中轴位置处
while(leftIndex<rightIndex&&numbers[rightIndex]>=center){
rightIndex--;
}
if(leftIndex<rightIndex){//找到了
numbers[centerIndex]=numbers[rightIndex];
centerIndex = rightIndex;
rightIndex--;
}
//从前向后找,找到比中轴值大的元素,写到中轴值位置处
while(leftIndex<rightIndex&&numbers[leftIndex]<=center){
leftIndex++;
}
if(leftIndex<rightIndex){//找到了
numbers[centerIndex] = numbers[leftIndex];
centerIndex=leftIndex;
leftIndex++;
}
}
numbers[centerIndex]=center;
quickSort(arrayBegin,centerIndex-1);
quickSort(centerIndex+1,arrayEnd);
return 1;
}
}
void writeData(char * filePath){
ofstream fout;
stringstream ss;
string s;
fout.open(filePath);
cout<<"开始写文件..."<<endl;
for(int i=0;i<fileLength;i++){
ss<<numbers[i];
ss>>s;
ss.clear();
fout<<s<<endl;
}
cout<<"写文件结束"<<endl;
}
int combine(int left,int right){
if(left>=right){
return 0;
}
int center = (right+left)/2;
//两段数据分别进行排序
quickSort(left,center);
quickSort(center+1,right);
int compareIndex=left;
//遍历后半段数据,计算每个数的逆序数值
for(int i = center+1;i<=right;i++){
int value = numbers[i];
while(compareIndex<=right&&numbers[compareIndex]<=value){
compareIndex++;
}
if(compareIndex<=right){
int temp = center-compareIndex+1;
//cout<<value<<"的逆序数是:"<<temp<<endl;
inversionCount = inversionCount+temp;
}
}
return inversionCount;
}
//计算逆序数个数
int countInversion(int left,int right){
if(left>=right){
return 0;
}else{
//cout<<"left="<<left<<",right="<<right<<endl;
int center = (right+left)/2;
int n1 = countInversion(left,center);
int n2 = countInversion(center+1,right);
int n3 = combine(left,right);
return n1+n2+n3;
}
}
int _tmain(int argc, _TCHAR* argv[])
{
readData("Q5.txt");
cout<<"开始计算逆序数..."<<endl;
//quickSort(0,fileLength-1);
countInversion(0,fileLength-1);
cout<<"结束逆序数计算,inversionCount="<<inversionCount<<endl;
//writeData("result.txt");
getchar();
return 0;
}
分治法求解逆序数问题
最新推荐文章于 2023-03-05 18:00:14 发布