题目描述
- 在你的计算机上实现最大子数组问题的暴力算法和递归算法。请指出多大的问题规模n0是性能交叉点——从此之后递归算法将击败暴力算法?
代码
#include <iostream>
#include <vector>
#include <cstdlib>
#include <ctime>
#include <assert.h>
using namespace std;
void generateRandomArray(int arr[], int n, int rangeL, int rangeR);//生成包含n个数的随机数组
vector<int> bruteSearch(int arr[], size_t n);//暴力搜索算法
vector<int> recursiveSearch(int arr[], int low, int high);//递归算法
vector<int> crossSubarray(int arr[], int low, int mid, int high);//用于求解递归算法中最大子字符串跨越中点的情况
int main() {
constexpr unsigned n = 1000000;
cout << "输入规模为:" << n << endl;
static int arr[n];
generateRandomArray(arr, n, -100, 100);
clock_t start2, finish2;
vector<int> ans2;
start2 = clock();
ans2 = recursiveSearch(arr, 0, n - 1);
finish2 = clock();
cout << "The answer of recursive search is:" << endl;
for (auto &c : ans2) {
cout << c << endl;
}
cout << "运行时间为:" << (double)(finish2 - start2) / CLOCKS_PER_SEC << endl;
cout << "---------------------------------------" << endl;
clock_t start1, finish1;
vector<int> ans1;
start1 = clock();
ans1 = bruteSearch(arr, n);
finish1 = clock();
cout << "The answer of brute search is:" << endl;
for (auto &c : ans1) {
cout << c << endl;
}
cout << "运行时间为:" << (double)(finish1 - start1) / CLOCKS_PER_SEC << endl;
cout << "---------------------------------------" << endl;
};
void generateRandomArray(int arr[], int n, int rangeL, int rangeR) {
assert(rangeL <= rangeR);
// srand(time(NULL)); // 随机种子
for (int i = 0; i < n - 1; i++)
arr[i] = rand() % (rangeR - rangeL + 1) + rangeL;
}
vector<int> bruteSearch(int arr[], size_t n) {
int max_sum = INT_MIN;
int left = 0;
int right = 0;
for (size_t i = 0; i != n - 1; ++i) {
int sum = 0;
for (size_t j = i; j != n; ++j) {
sum += arr[j];
if (sum > max_sum) {
max_sum = sum;
left = i;
right = j;
}
}
}
return { left, right, max_sum};
}
vector<int> crossSubarray(int arr[], int low, int mid, int high) {
int left_sum = INT_MIN;
int max_left = 0;
int max_right = 0;
int sum = 0;
for (int i = mid; i >= low; --i) {
sum += arr[i];
if (sum > left_sum) {
left_sum = sum;
max_left = i;
}
}
int right_sum = INT_MIN;
sum = 0;
for (int i = mid + 1; i <= high; ++i) {
sum += arr[i];
if (sum > right_sum) {
right_sum = sum;
max_right = i;
}
}
return { max_left, max_right, left_sum + right_sum };
}
vector<int> recursiveSearch(int arr[], int low, int high) {
if (high == low) {
return { low, high, arr[low] };
}
else {
int mid = (low + high) / 2;
vector<int> vec_left = recursiveSearch(arr, low, mid);
vector<int> vec_right = recursiveSearch(arr, mid+1, high);
vector<int> vec_cross = crossSubarray(arr, low, mid, high);
if (vec_left[2] >= vec_right[2] && vec_left[2] >= vec_cross[2])
return vec_left;
else if (vec_right[2] >= vec_left[2] && vec_right[2] >= vec_cross[2])
return vec_right;
else return vec_cross;
}
}
- 实验发现,n<10000时,暴力搜索算法性能更好,n=10000时,两种算法性能相当,n>10000时,递归算法开始展现出明显优势
- 实验结果如下;