Comprobar si el array está ordenado el uso de una función en C

0

Pregunta

Básicamente, necesitamos comprobar si los elementos de una 1D array están ordenadas por medio de una función: si se ordenan en orden ascendente: return 1 si se ordenan en orden descendente: return -1 si no están ordenados: return 0 Este es el método que estoy usando, sin embargo no retorno 1 pero isntead 0, Im seguro de donde está el problema, Cualquier comentario o nuevos métodos de resolución de un problema son bienvenidos, ya que soy un principiante.

int Is_Sorted(int* A, int n){
    int tempcr, tempdcr;

for (int i=0; i<N-1; i++){

    if (A[i]<=A[i+1]){
        tempcr++;
    }else if (A[i]>=A[i+1]){
    tempdcr++;
    }
}
   if(tempcr==N-1){
        return 1;
   }else if(tempdcr==N-1)
        return -1;
   else
    return 0;

}
algorithm arrays c sorting
2021-11-23 21:26:44
2

Mejor respuesta

2

Lógica incorrecta

OP código de falla debido a

}else if (A[i]>=A[i+1]){
tempdcr++;

debe ser

}
if (A[i]>=A[i+1]) {
  tempdcr++;

Considere el caso en que A[i]==A[i+1], ambos contadores debe incrementar.

No Deseado De Valores

Falta de inicialización @kaylum.

// int tempcr, tempdcr;
int tempcr = 0;
int tempdcr = 0;

Enfoque alternativo:

Hay 4 posibilidades

  • La matriz tiene el mismo valor en todos los lugares - o es de longitud 0.

  • La matriz es ascendente. A[i] >= A[i-1] para todos i > 0 y la longitud es mayor que 0.

  • La matriz es descendente. A[i] <= A[i-1] para todos i > 0 y la longitud es mayor que 0.

  • Ninguna de las anteriores.

Simplemente bucle y ajuste las dos banderas. int tempcr, tempdcr; los contadores no es necesario.

int Is_Sorted(const int* A, int n) {
  bool isAscending = true;
  bool isDescending = true;
  for (int i = 1; i<n; i++) { // start at 1
     if (A[i] < A[i-1]) isAscending = false;
     if (A[i] > A[i-1]) isDescending = false;
  }
  if (isAscending && isDescending) {
    return TBD; // Unsure what OP wants here
  }
  if (isAscending) {
    return 1;
  }
  if (isDescending) {
    return -1;
  }
  return 0;
}

Simplificaciones y algunos micro optimización posible, pero algo para aclarar un claro enfoque.


Demasiada diversión.

Si int a[] no es constante, sólo podemos utilizar 1 prueba por iteración en lugar de 3: prueba de i, es menor, es más de el código anterior.

Primer vistazo de la desigualdad, desde el final hacia el principio. El primer elemento es ajustado para que sea diferente de la última.

Si queremos recorrer toda la lista, hemos terminado, de lo contrario, la primera parte de la lista difiere del último elemento.

Si la última comparar es ascendente, establece el primer elemento a INT_MAX y la búsqueda hacia el principio de no-ascendente par.

De lo contrario,
Si la última comparación es descendente, establece el primer elemento a INT_MIN y la búsqueda hacia el principio para no descender par.

En la búsqueda de una comparación se produce el error, ya sea la matriz es desordenada o estamos en el principio. Si al principio, manejar ese caso especial.

En cualquier caso, sólo el 1 comparar por iteración.

#define ASCENDING 1
#define DESCENDING -1
#define UNORDERED 0
#define ALLSAME 1 // Adjust as desired
#define SHORT_LENGTH 1 // Adjust as desired

int is_sorted(size_t n, int *a) {
  if (n <= 1) {
    return n ? ALLSAME : SHORT_LENGTH;
  }

  int last = a[--n];
  int first = a[0];
  a[0] = !last;
  while (last == a[--n]) {
    ;
  }
  a[0] = first; // restore
  if (n == 0) {
    if (a[0] < a[1]) {
      return ASCENDING;
    }
    if (a[0] > a[1]) {
      return DESCENDING;
    }
    return ALLSAME;
  }

  if (a[n - 1] < a[n]) {
    // Only ascending, unordered possible
    a[0] = INT_MAX;
    while (a[n - 1] <= a[n]) {
      n--;
    }
    a[0] = first; // restore
    if (a[n - 1] <= a[n]) {
      return ASCENDING;
    }
  } else {
    // Only descending, unordered possible
    a[0] = INT_MIN;
    while (a[n - 1] <= a[n]) {
      n--;
    }
    a[0] = first; // restore
    if (a[n - 1] <= a[n]) {
      return DESCENDING;
    }
  }
  return UNORDERED;
}

Voy a hacer algunas pruebas más tarde.

Si la matriz es const, necesita 2 prueba por bucle.

2021-11-24 05:24:03

Usted puede salir de la for bucle de una vez (si) ambas banderas convertido en false.
500 - Internal Server Error

@500-InternalServerError Cierto, sin embargo, que no es cierto optimización como también podría retardar el tiempo de ejecución como se está haciendo más de cheques. Depende de la típica matriz de conjuntos. IAC, no reduce O(). Más aquí.
chux - Reinstate Monica

@500-InternalServerError Para la diversión, podría ser interesante bi-secta de la matriz en cada comparar paso y comprobar los puntos finales hasta abajo para tamaño 1. Sin duda más lento en el peor de los casos, pero es probable que la captura principios de no-ordenó matrices y permitir el único fin de comparar y/o final del primer código.
chux - Reinstate Monica

Para matrices grandes, o si el código es generalizada para que coincida con qsort() o bsearch()la apertura temprana es probable que sea beneficioso para el rendimiento — evita potencialmente muchas llamadas a la función. Cuando el tipo de datos es int, la sobrecarga de comparación es mucho menor, por lo que la apertura temprana vs extra de pruebas no es tan clara.
Jonathan Leffler

@500-InternalServerError Así que había un poco de diversión a utilizar sólo 1 comparar por bucle.
chux - Reinstate Monica

Es esta una manera correcta de terminar tu programa y probarlo? (Estoy oxidado en C)
Kelly Bundy
1

Para empezar, la función debe ser declarada como

int Is_Sorted( const int* A, size_t n );

que es, al menos, el primer parámetro debe tener el calificativo de const debido a que el pasado de la matriz no es ser cambiado dentro de la función.

Las variables tempcr y tempdcr no fueron inicializadas y tienen indeterminado de valores. Así que la función tiene un comportamiento indefinido. Usted tiene que inicializar ellos como

int tempcr = 0, tempdcr = 0;

No tiene ningún sentido continuar las iteraciones del bucle si es que ya se sabe que la matriz no está ordenado porque es ineficiente.

Además, la función tiene un error lógico.

Considere la matriz { 0, 0, -1 }

En este caso en la primera iteración del bucle la variable tempcr será aumentado debido a la instrucción if

if (A[i]<=A[i+1]){
    tempcr++;
}else if (A[i]>=A[i+1]){
tempdcr++;
}

Pero en la segunda iteración del bucle la variable tempdcr será mayor.

Así que la función se informe de que la matriz no está ordenado a pesar de que se clasifican en orden descendente.

Yo definiría la función de la siguiente manera

int is_sorted( const int a[], size_t n )
{
    size_t ascending = 0, descending = 0;

    for (size_t i = 1; ( ascending == 0 || descending == 0 ) && i < n; i++)
    {
        if ( a[i-1] < a[i] ) ++ascending;
        else if ( a[i] < a[i-1] ) ++descending;
    }

    return descending == 0 ? 1 : ( ascending == 0 ? -1 : 0 );
}

Si el pasado matriz tiene todos los elementos son iguales entre sí, entonces la función se considera como ordenados en orden ascendente.

Como apunta @chux - Reintegrar a Mónica en su respuesta, en vez de contar los elementos de se pueden utilizar las variables correspondientes como objetos boolean. En este caso la función se puede ver como

int is_sorted1( const int a[], size_t n )
{
    int ascending = 0, descending = 0;

    for (size_t i = 1; ( ascending == 0 || descending == 0 ) && i < n; i++)
    {
        if ( a[i-1] < a[i] ) ascending = 1;
        else if ( a[i] < a[i-1] ) descending = 1;
    }

    return descending == 0 ? 1 : ( ascending == 0 ? -1 : 0 );
}
2021-11-23 21:49:44

En otros idiomas

Esta página está en otros idiomas

Русский
..................................................................................................................
Italiano
..................................................................................................................
Polski
..................................................................................................................
Română
..................................................................................................................
한국어
..................................................................................................................
हिन्दी
..................................................................................................................
Français
..................................................................................................................
Türk
..................................................................................................................
Česk
..................................................................................................................
Português
..................................................................................................................
ไทย
..................................................................................................................
中文
..................................................................................................................
Slovenský
..................................................................................................................