我正在编写代码来查找C中的最大和连续子数组。根据我的逻辑,这似乎很好,但输出仍然不正确。请查看代码。该算法将一个较大的数组分为2个子数组。然后,通过检查左数组,右数组以及包含中点的数组来检查最大和子数组(它将从中点向右和向左检查,然后返回包含中点的最大和子数组)。
int* cross_max(int arr[], int low, int mid, int high) { int left_max, left_sum = -2000; int sum = 0; int i; for(i=mid; i>=low;i--) { sum = sum + arr[i]; if(sum > left_sum) { left_sum = sum; left_max = i; } } int right_max, right_sum = -2000; for(i=mid+1; i<=high;i++) { sum = sum + arr[i]; if(sum > right_sum) { right_sum = sum; right_max = i; } } // 0 - sum // indices - 1,2 int temp_arr[3] = {0,0,0}; temp_arr[0] = left_sum + right_sum; temp_arr[1] = left_max; temp_arr[2] = right_max; int *p = temp_arr; printf("\n Maximum sum = %d\n",*p); printf("\n low = %d\n",*(p+1)); printf("\n high = %d\n",*(p+2)); return p; } int* find_max(int arr[], int low, int high) { int temp_arr[3] = {0,0,0}; if(low == high) { temp_arr[0] = arr[low]; temp_arr[1] = low; temp_arr[2] = low; int *q = temp_arr; return q; } int mid = (low + high)/2; int* a1 = find_max(arr,low,mid); int* a2 = find_max(arr,mid+1,high); int* a3 = cross_max(arr,low,mid,high); if (*a1 > *a2 && *a1 > *a3) return a1; else if (*a2 > *a1 && *a2 > *a3) return a2; else return a3; } int main() { int arr[8] = {1,1,2,-2,3,3,4,-4}; int *point = find_max(arr,0,7); printf("\n Maximum sum = %d\n",*point); printf("\n low = %d\n",*(point+1)); printf("\n high = %d\n",*(point+2)); return 0; }
代码中存在未定义行为的两个问题:
第一个是您传递的9as high将用于索引八元素数组的第十个元素。这将是第十,因为在cross_max循环中时i <= high,您将进行索引arr[9]。请记住,数组索引的大小是从零到负一(因此,您可以为数组索引从0到7)。索引超出范围将包含未定义(即随机)值。
9
high
cross_max
i <= high
arr[9]
0
7
第二个问题是您正在从中返回指向局部变量的指针cross_max。当您使用该返回的指针时,这将导致未定义的行为。局部变量仅在它们声明的范围内有效,并且当函数返回时,该局部变量使用的内存区域将被回收并用于下一个函数。