Estoy tratando de escribir un código que pueda verificar si una matriz dinámica está ordenada, pero aparece un error. El código tiene que ser recursivo.
Cuando ingreso una matriz no ordenada, parece que no hay problema, pero cuando ingreso una matriz ordenada, el programa se detiene abruptamente con:
Tramitar devolución -1073741571
Aquí está mi código:
#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; }Lo siento, mi primera respuesta no fue correcta. Corrijo a continuación.
scanf("%d", &arr[i]); antes del ciclo para llenar arr[0]ordenado la función de orden0 , return 1x pero el siguiente elemento es 0 , return 1 (Tenga en cuenta que || es un cortocircuito. Si no presiona 0 , entonces hay un siguiente elemento. Por lo tanto, puede verificar que sea 0 aquí también).return 0 (creo que es más rápido)not 0 y llama a ordenado(++arr) (prefijo, no posfijo)Nota sobre el prefijo y el posfijo:
La diferencia entre prefijo y posfijo en muchos lenguajes de programación es el orden de ejecución. Suponga que i y j son 0 antes de la ejecución en ambas declaraciones.
i += ++j;El código anterior es equivalente a este
j = j + 1; i = i + j;Mientras que el siguiente código
i += j++;es equivalente a esto
i = i + j; j = j + 1;Es decir, en prefijo el incremento tiene lugar antes de que se evalúe la expresión, mientras que en postfijo el incremento tiene lugar después de que se evalúe la expresión. Esto suele ser cierto sin importar el tipo de datos (es decir, incluye puntero).
Su línea de código
return ordenado(arr++);es equivalente a
return ordenado(arr); a++;lo que conduce a un número infinito de llamadas a funciones como señaló @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: 0En estas lineas:
arr = malloc(sizeof (int)); while (arr[i] != 0)No puede contar con que la memoria malloc tenga un valor particular. No está inicializado .
Parece que está utilizando una entrada cero como centinela. La forma correcta de hacer esto es:
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);También he corregido el elemento cero al que no se le ha asignado un valor.
Sospecho que el error que experimentó fue causado por una recursividad fuera de control.
Su código tiene múltiples problemas:
0 )0 ;arr antes de incrementarlo, lo que provoca una recursión infinita. El hecho de que obtenga un error demuestra que el compilador no maneja la recursividad de la cola, y su código eventualmente falla con un desbordamiento de pila . Si puede cambiar la ordenado para la función de orden, debe pasarle la cantidad de elementos reales en la matriz. Se supone que esta función es recursiva, elija un algoritmo que limite la recursividad para evitar el desbordamiento de la pila si el compilador no detecta la recursividad de la cola.
Aquí está mi sugerencia:
#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)); } NB: Reasignar la matriz de un int a la vez es dolorosamente ineficiente, pero no es el tema de esta discusión.