例:输入-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万)