我试图编写一个可以检查动态数组是否已排序的代码,但是我收到错误。代码必须是递归的。
当我输入一个未排序的数组时似乎没有问题,但是当我输入一个已排序的数组时,程序会突然停止:
流程返回-1073741571
这是我的代码:
#include <stdio.h>
#include <stdlib.h>
int ordenado(int*);
int main() {
int i = 0, res = 0;
int*arr = NULL;
arr = (int*) malloc(sizeof (int));
while (arr[i] != 0) {
i++;
arr = (int*) realloc(arr, (i + 1) * sizeof (int));
scanf("%d", &arr[i]);
}
res = ordenado(arr);
printf("\n%d ", res);
return 0;
}
int ordenado(int* arr) {
if (arr[0] == 0) {
return 1;
}
if (arr[0] <= arr[1]) {
return ordenado(arr++);
}
else return 0;
}
答案 0 :(得分:3)
抱歉,我的第一个回答是不对的。我在下面纠正了。
scanf("%d", &arr[i]);
来填充arr[0]
ordenado
功能
0
然后return 1
x
但下一个元素是0
然后return 1
时(注意||
是短路。如果您没有点击0
然后有一个下一个元素。所以你也可以在这里查看0
。)return 0
(我认为更快)not 0
并调用ordenado(++arr)
(前缀,而不是后缀)关于前缀和后缀的注意事项:
许多编程语言中前缀和后缀之间的区别是执行顺序。在两个语句中执行之前,假设i
和j
为0
。
i += ++j;
以上代码相当于此
j = j + 1;
i = i + j;
以下代码
i += j++;
等同于此
i = i + j;
j = j + 1;
即。在前缀中,增量发生在计算表达式之前,而在后缀中,增量发生在计算表达式之后。这通常适用于数据类型(即包括指针)。
您的代码行
return ordenado(arr++);
等同于
return ordenado(arr);
a++;
导致无数次的函数调用,如@BLUEPIXY指出的那样。
#include <stdio.h>
#include <stdlib.h>
int ordenado(int*);
int main() {
int i = 0, res = 0;
int* arr = NULL;
arr = (int*) malloc(sizeof (int));
scanf("%d", &arr[i]);
while (arr[i] != 0) {
i++;
arr = (int*) realloc(arr, (i + 1) * sizeof (int));
scanf("%d", &arr[i]);
}
res = ordenado(arr);
printf("\n%d ", res);
return 0;
}
int ordenado(int* arr) {
if (arr[0] == 0 || arr[1] == 0)
return 1;
if (arr[0] > arr[1])
return 0;
else
return ordenado(++arr);
}
Input: 0
Output: 1
Input: 1 newline 0
Output: 1
Input: 1 newline 2 newline 3 newline 0
Output: 1
Input: 2 newline 1 newline 0
Output: 0
Input: 1 newline 2 newline 3 newline 2 newline 3 newline 0
Output: 0
答案 1 :(得分:2)
在这些方面:
arr = malloc(sizeof (int));
while (arr[i] != 0)
你不能指望具有任何特定价值的malloc内存。它是未初始化。
看起来你正在使用输入零作为哨兵。正确的方法是:
int i = 0;
int *arr = malloc(sizeof (int));
do {
i++;
arr = realloc (arr, (i + 1) * sizeof (int));
scanf ("%d", &arr[i-1]);
} while (arr[i-1] != 0);
我还修复了元素零没有分配值。
我怀疑您遇到的错误是由失控的递归引起的。
答案 2 :(得分:1)
您的代码有多个问题:
0
)0
,您将获得潜在的不匹配; arr
,从而导致无限递归。您收到错误的事实证明编译器不处理尾递归,并且您的代码最终因堆栈溢出而失败。如果您可以更改ordenado
函数的API,则应该传递数组中实际元素的数量。这个函数应该是递归的,如果编译器没有检测到尾递归,选择一个限制递归以避免堆栈溢出的算法。
这是我的建议:
#include <stdio.h>
#include <stdlib.h>
int ordenado(int *array, int count);
int main() {
int i = 0, n, res;
int *arr = NULL;
while (scanf("%d", &n) == 1 && n != 0) {
arr = realloc(arr, (i + 1) * sizeof(int));
if (!arr) {
printf("out of memory\n");
return 1;
}
arr[i++] = n;
}
res = ordenado(arr, i);
printf("%d\n", res);
return 0;
}
int ordenado(int *arr, int n) {
int m = n >> 1;
return (m == 0) ||
(ordenado(arr, m) && arr[m - 1] <= arr[m] && ordenado(arr + m, n - m));
}
注意:一次重新分配一个int
数组是非常低效的,但不是讨论的主题。