使用步骤:
1.写出你要测试的算法,这里以从大到小的快速排序为例
template<typename T>
void quicksort(vector<T>& vec, int start, int end){
T key=vec[end]; //将枢纽值保存,枢纽值一趟排序就放在了最终位置,之前的数据大于他,之后的数据小于他
int i=end;
int j=start;
while (i>j){
while (vec.at(j)>=key && j<i)
j++;
vec.at(i)=vec[j];
while (vec.at(i)<=key && i>j)
i--;
vec.at(j)=vec.at(i);
}
vec.at(i)=key; //枢纽值放在最终位置,i位置排序完成
if(i-1>start) //key前面如果有2个及其以上的元素,将这些元素排序
quicksort(vec,start,i-1);
if(i+1<end)
quicksort(vec,i+1,end); //key后面有2个及其以上的元素
}
template<typename T>
void sort(vector<T>& vec){
quicksort(vec, 0,vec.size()-1);
}
注:改进的快排:随机快速排序
//随机快速排序
//设数组最后一个元素arr[R]为枢纽值,将数组划分为三个区域:左边小于arr[R]区域,中间等于arr[R],右边大于arr[R],一次排序一个枢纽值和多个位置(等于枢纽值)
template<typename T>
int* partition(T arr[], int L, int R) {
int less = L - 1; //小于枢纽值的区域的最后一个位置
int more = R; //等于枢纽值的区域的最后一个位置
while (L < more) {
if (arr[L] > arr[R]) {
swap(arr[L], arr[--more]); //大于枢纽值的数据移到后面,因为--more位置的数据与arr[R]的关系不知道,所以交换后L不变,继续判断L位置
}
else if (arr[L] < arr[R]) {
swap(arr[L++], arr[++less]); //++less位置的数据等于枢纽值,将小于枢纽值的数据域枢纽值交换,L++判断下一个位置
}
else L++; //等于枢纽值的区域扩张
}
swap(arr[more], arr[R]); //最后将枢纽值与第一个大于枢纽值的数据交换
int* p{ new int[2]{less + 1,more} };
return p; //返回等于枢纽值区域的左边界和右边界
}
template<typename T>
void quickSort(T arr[], int L, int R) {
if (L < R) {
srand(unsigned(time(NULL)));
swap(arr[R], arr[rand() % (R - L + 1) + L]); //将枢纽值设置为数组里的随机值
int* p = partition(arr, L, R);
quickSort(arr, L, p[0] - 1); //未排序区域继续排序
quickSort(arr, p[1] + 1, R);
delete[] p;
}
}
template<typename T>
void quickSort(T arr[], int size) {
quickSort(arr, 0, size - 1);
}
2.写出一个绝对正确的算法,这个算法的复杂度可以很差,不过一定要正确。这
里使用STL里的
template<typename T>
bool myCompare(T a, T b)
{
return a>b;
}
template<typename T>
void rightMethod(vector<T>& vec){
sort(vec.begin(), vec.end(),myCompare<T>);
}
3.写一个将两种算法进行比对的函数,用来检测你写的算法是否有问题。
template<typename T>
bool isEqual(vector<T>& vec1, vector<T>& vec2){
if(vec1.size()!=vec2.size())
return false;
else {
//cout<< "size1: " <<vec1.size() << "size2: "<< vec2.size() <<endl;
/*
for(int i=0; i<vec1.size(); i++)
if(vec1.at(i)!=vec2.at(i))
return false;
*/
//偷个懒,因为用容器存储数据,直接使用stl提供的equal算法判断容器数据是否相等
return equal(vec1.begin(),vec1.end(),vec2.begin());
}
return true;
}
4.写产生随机数组的函数和拷贝数组的函数,用来产生测试的案例。
template<typename T>
void generateRandomArray(vector<T>& vec, int maxSize, T minValue, T maxValue){
assert(maxValue>minValue);
srand((unsigned int)time(nullptr));
int size = rand()%maxSize + 1;
vec = vector<T> (size, -1);
for (auto it=vec.begin(); it!=vec.end(); it++){
*it = rand()%(maxValue-minValue) + minValue + 1;
}
return;
}
template<typename T>
void copyArray(vector<T>& vec1, vector<T>& vec2){
if(!vec1.size())
return;
vec2 = vec1;
}
5.写打印案例的函数,用来打印出错的案例,方便分析错误原因。
template<typename T>
void printArray(vector<T>& vec){
cout<< "error array : " <<endl;
for(auto i : vec)
cout<< i <<" ";
cout<<"\n";
}
6.开始测试
void testAlgorithm(){
int testCount (2000000); //测试案例的个数
int maxSize (10); //数组的最大元素个数
int minValue (-100); //元素的最小值
int maxValue (100); //元素的最大值
bool succeed (true);
clock_t startTime,endTime; //计算算法执行时间
startTime = clock();
for(int i=0; i<testCount; i++){
vector<int> vec1, vec2, vec3;
generateRandomArray(vec1,maxSize,minValue,maxValue);
vec2 = vec1;
vec3 = vec1;
rightMethod(vec1);
sort(vec1);
rightMethod(vec2);
/*
//方便查看
printArray(vec1);
printArray(vec2);
*/
if(!isEqual(vec1,vec2)){
succeed=false;
printArray(vec3);
break;
}
//一定要回收内存
vector<int> ().swap(vec1);
vector<int> ().swap(vec2);
vector<int> ().swap(vec3);
}
if(succeed)
cout<<"Beautiful,Nice!"<<endl;
else
cout<<"please calmly analyze,debug!"<<endl;
endTime = clock();
cout<< "time cost: " << double(endTime-startTime)/CLOCKS_PER_SEC << " s" <<endl;
}
温馨提示:当你的算法出错的时候,请冷静下来,调试代码。
如果你写的算法正确,祝贺你,你很强哦。