
例:输入-2,11,-4,13,-5,-2时,答案为20(从A2到A4)
代码如下:
#include <stdio.h>
#include <stdlib.h> //malloc()、calloc()、realloc()、free()、system()、atoi()、atol()、rand()、srand()、exit()等等
#include <string.h> //strstr
#include <time.h> //clock()
//返回3个数中的最大值
int Max3(int a, int b, int c){
return a > b ? (a > c ? a : c) : (b > c ? b : c);
}
//算法1---O(N的立方)
int MaxSum1(int arr[], int n){
int i,j,k,ThisSum,MaxSum=0;
for(i=0; i<n; i++){
for(j=i; j<n; j++){
ThisSum = 0;
for(k=i; k<=j; k++)
ThisSum += arr[k];
if(ThisSum > MaxSum)
MaxSum = ThisSum;
}
}
return MaxSum;
}
//算法2---O(N的平方)
int MaxSum2(int arr[], int n){
int i,j,k,ThisSum,MaxSum=0;
for(i=0; i<n; i++){
ThisSum = 0;
for(j=i; j<n; j++){
ThisSum += arr[j];
if(ThisSum > MaxSum)
MaxSum = ThisSum;
}
}
return MaxSum;
}
/*
* 分治:将数组分成左右两部分,分别求出左边,中间及右边的最大子序列的和,取三个中最大值
* 求中间的最大值:
* 1)左边求出包含最后一个项在内的最大了序列的和M;
* 2)右边求出包含第一个项在内的最大子序列的和N;
* 3)M + N 即为中间的最大子序列和;
* 递归时,MaxLeftSum,MaxRightSum均为已知条件,由上一次递归返回
*/
int MaxSum3(int arr[], int Left, int Right){
int MaxLeftSum, MaxRightSum;
int MaxLeftBorderSum, MaxRightBorderSum;
int LeftBorderSum, RightBorderSum;
int Center, i;
//递归的基准条件
if(Left == Right){
if(arr[Left] > 0)
return arr[Left];
else
return 0;
}
Center = (Left + Right) / 2;
MaxLeftSum = MaxSum3(arr, Left, Center);
MaxRightSum = MaxSum3(arr, Center+1, Right);
MaxLeftBorderSum = 0;
LeftBorderSum = 0;
for(i=Center; i>=Left; i--){
LeftBorderSum += arr[i];
if(LeftBorderSum > MaxLeftBorderSum)
MaxLeftBorderSum = LeftBorderSum;
}
MaxRightBorderSum = 0;
RightBorderSum = 0;
for(i=Center+1; i<=Right; i++){
RightBorderSum += arr[i];
if(RightBorderSum > MaxRightBorderSum)
MaxRightBorderSum = RightBorderSum;
}
return Max3(MaxLeftSum, MaxRightSum, MaxRightBorderSum + MaxLeftBorderSum);
}
//联机算法
int MaxSum4(int arr[], int n){
int ThisSum=0, MaxSum=0, j;
for(j=0; j<n; j++){
//每次循环时,ThiSum里已经是前j项里子序列里的最大值
ThisSum += arr[j];
if(ThisSum > MaxSum)
MaxSum = ThisSum;
else if(ThisSum < 0)
ThisSum = 0;
}
return MaxSum;
}
//文件读取
char *FileLoad(char *file_name){
char *pchBuf = NULL;
int nLen = 0;
FILE *pf = fopen(file_name,"r");
fseek(pf, 0, SEEK_END);//文件指针移到文件尾部
nLen = ftell(pf);//得到当前指针位置,即是文件的长度
rewind(pf);//文件指针恢复到文件头位置
//动态申请空间,为保存字符串结尾标志\0,多申请一个字符的空间
pchBuf = (char *)malloc(sizeof(char)*nLen + 1);
if(!pchBuf){
perror("内存不够!\n");
exit(0);
}
//读取文件内容,读取的长度和源文件长度可能有出入,这里自动调整nLen
nLen = fread(pchBuf, sizeof(char), nLen, pf);
pchBuf[nLen] = '\0'; //添加字符串结尾标志
//printf("%s\n", pchBuf); //输出文件内容
fclose(pf); //关闭文件
return pchBuf;
//free(pchBuf); //释放空间
}
/**
* Split a string into some strings according to a list of separators.
*
* @Param dest out: storage the strings has be split.
* @Param count out: the number of strings has be split successfully, 0 for failed to split.
* @Param s_str in: the strings for split.
* @Param separator in: the list of split separators.
* @Param number_separator in: the numbers of separators.
* @Param compress_separator in: will be create a empty string when two split adjacent
* if compress_separator > 0 and not for compress_separator == 0
* @Param keep_separator in: the separators will be put into parameter 'dest' if keep_separator > 0
*/
int strsplit(char ***dest, int *count, char *s_str, char **separator, int number_separators, int compress_separator, int keep_separator)
{
int i = 0;
char **result = NULL;
char **temp_result = NULL;
unsigned int curt_size = 0;
unsigned int new_size = 0;
char *look_ahead = NULL;
char *most_front_separator_start = NULL;
char *most_front_separator_end = NULL;
char *separator_start = NULL;
int find_a_separator = 0;
int find_a_string = 0;
*count = 0;
*dest = NULL;
/* check parameters */
if (
dest == NULL
|| s_str == NULL || *s_str == '\0'
|| separator == NULL
|| number_separators <= 0
|| compress_separator < 0
|| keep_separator < 0
)
return -1;
for (i = 0; i < number_separators; i++)
if (separator[i] == NULL || *separator[i] == '\0')
return -1;
for (look_ahead = s_str; *look_ahead != '\0'; look_ahead = most_front_separator_end)
{
most_front_separator_start = look_ahead + strlen(look_ahead);
most_front_separator_end = look_ahead + strlen(look_ahead);
find_a_separator = 0;
/* find the next separator. */
for (i = 0; i < number_separators; i++)
{
separator_start = strstr(look_ahead, separator[i]);
if (separator_start == NULL)
continue;
find_a_separator = 1;
/* update the most front separator. */
if (separator_start < most_front_separator_start)
{
most_front_separator_start = separator_start;
most_front_separator_end = most_front_separator_start + strlen(separator[i]);
}
}
find_a_string = (look_ahead == most_front_separator_start) ? 0 : 1;
/* allow put the new string into result if need. */
new_size = (find_a_string > 0) ? (curt_size + 1) : ((compress_separator > 0) ? curt_size : (curt_size + 1));
/* allow put the separator into result if need. */
new_size = (keep_separator > 0) ? (new_size + 1) : new_size;
if (new_size == curt_size)
continue;
temp_result = (char **)malloc((new_size) * sizeof(char *));
if (temp_result == NULL)
{
if (result != NULL)
{
for (i = 0; i < curt_size; i++)
if (result[i] != NULL)
free(result[i]);
free(result);
result = NULL;
}
return -2;
}
/* copy the pointers of string find early. */
memset(temp_result, 0, new_size);
for (i = 0; i < curt_size; i++)
temp_result[i] = result[i];
if (find_a_string == 0)
{
if (compress_separator == 0)
{
temp_result[curt_size] = (char *)malloc(sizeof(char));
if (temp_result[curt_size] == NULL)
{
if (temp_result != NULL)
{
for (i = 0; i < curt_size; i++)
if (temp_result[i] != NULL)
free(temp_result[i]);
free(temp_result);
temp_result = NULL;
}
return -2;
}
memset(temp_result[curt_size], 0, 1);
}
}
else
{
/* put the new string into result. */
temp_result[curt_size] = (char *)malloc((most_front_separator_start - look_ahead + 1) * sizeof(char));
if (temp_result[curt_size] == NULL)
{
if (temp_result != NULL)
{
for (i = 0; i < curt_size; i++)
if (temp_result[i] != NULL)
free(temp_result[i]);
free(temp_result);
temp_result = NULL;
}
return -2;
}
memset(temp_result[curt_size], 0, most_front_separator_start - look_ahead + 1);
strncpy(temp_result[curt_size], look_ahead, most_front_separator_start - look_ahead);
temp_result[curt_size][most_front_separator_start - look_ahead] = '\0';
}
if (keep_separator > 0)
{
/* put the separator into result. */
temp_result[new_size - 1] = (char *)malloc(most_front_separator_end - most_front_separator_start + 1);
if (temp_result[new_size - 1] == NULL)
{
if (temp_result != NULL)
{
for (i = 0; i < new_size - 1; i++)
if (temp_result[i] != NULL)
free(temp_result[i]);
free(temp_result);
temp_result = NULL;
}
return -2;
}
memset(temp_result[new_size - 1], 0, most_front_separator_end - most_front_separator_start + 1);
strncpy(temp_result[new_size - 1], most_front_separator_start, most_front_separator_end - most_front_separator_start);
temp_result[new_size - 1][most_front_separator_end - most_front_separator_start] = '\0';
}
/* update result. */
free(result);
result = temp_result;
temp_result = NULL;
curt_size = new_size;
}
*dest = result;
*count = curt_size;
return 0;
}
int main(void){
//文件读取,并切割成数组
char *str = FileLoad("./1W.txt");//注意将该字符串使用完后free掉
char *separator[] = {","};//定义切割符
char **result = NULL;
int n_str = 0,i;
strsplit(&result, &n_str, str, separator, 1, 1, 1);
//去掉分割符
int key=0,n_str_arr = n_str-1, temp_arr[n_str_arr];//去掉结尾的空白符
for (i=0; i<(n_str-1); i++){
if(strcmp(result[i],",") == 0)
n_str_arr -= 1;
else{
temp_arr[key] = atoi(result[i]); //注:result[i]存储的是一个字符串
key++;
}
}
//完成的数组
int arr[n_str_arr];
for(i=0; i<n_str_arr; i++){
arr[i] = temp_arr[i];
//printf("%d\n",arr[i]);
}
for (i = 0; i < n_str; i++)
free(result[i]);
free(result);
/*int arr[] = {-2,11,-4,13,-5,-2};*/
int len = sizeof(arr)/sizeof(arr[0]);
double start, finish;
//算法1---O(N的立方)
start = clock();//取开始时间
int res1 = MaxSum1(arr, len);
finish = clock();//取结束时间
printf( "O(N的立方):%f seconds\n",(finish - start) / CLOCKS_PER_SEC);//以秒为单位显示之
//算法2---O(N的平方)
start = clock();//取开始时间
int res2 = MaxSum2(arr, len);
finish = clock();//取结束时间
printf( "O(N的平方):%f seconds\n",(finish - start) / CLOCKS_PER_SEC);//以秒为单位显示之
//分治算法
start = clock();//取开始时间
int res3 = MaxSum3(arr, 0 , len-1);
finish = clock();//取结束时间
printf( "分治算法:%f seconds\n",(finish - start) / CLOCKS_PER_SEC);//以秒为单位显示之
start = clock();//取开始时间
int res4 = MaxSum4(arr, len);
finish = clock();//取结束时间
printf( "联机算法:%f seconds\n\n",(finish - start) / CLOCKS_PER_SEC);//以秒为单位显示之
printf("res1(O(N的立方))=%d\n", res1);
printf("res2(O(N的平方))=%d\n", res2);
printf("res3(分治算法)=%d\n", res3);
printf("res4(联机算法)=%d\n", res4);
}数据说明:-99999到99999这间的随机数
结果1:(数据量级:2000)
O(N的立方):6.370000 seconds O(N的平方):0.010000 seconds 分治算法:0.000000 seconds 联机算法:0.000000 seconds res1(O(N的立方))=4904628 res2(O(N的平方))=4904628 res3(分治算法)=4904628 res4(联机算法)=4904628
结果2:(数据量级:4000)
O(N的立方):50.840000 seconds O(N的平方):0.050000 seconds 分治算法:0.000000 seconds 联机算法:0.000000 seconds res1(O(N的立方))=7641451 res2(O(N的平方))=7641451 res3(分治算法)=7641451 res4(联机算法)=7641451
结果3:(数据量级:10000) 注:算法1-O(N的立方)运行时间估算在10个多小时,已经没法正常使用
O(N的平方):0.260000 seconds
分治算法:0.000000 seconds
联机算法:0.000000 seconds
res2(O(N的平方))=5849432
res3(分治算法)=5849432
res4(联机算法)=5849432
结果4:(数据量级:10万)注:算法2-O(N的平方)运行时间估算在18个多小时,已经没法正常使用
分治算法:0.020000 seconds 联机算法:0.000000 seconds res3(分治算法)=15878572 res4(联机算法)=15878572
结果4:(数据量级:100万)