Bisogno di controllare se l'array è ordinato in base a una funzione in C

0

Domanda

Fondamentalmente, abbiamo bisogno di verificare se gli elementi di una 1D array sono ordinati utilizzando una funzione: se essi sono ordinati in ordine crescente: return 1 se essi sono ordinati in ordine decrescente: return -1 se non sono ordinati: 0 Questo è il metodo im utilizzando, tuttavia non ritorno 1 ma isntead 0, Im sicuro dove è il problema, commenti o nuovi metodi per risolvere il problema sono i benvenuti dal momento che sono 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

Migliore risposta

2

Logica errata

OP codice non riesce a causa di

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

dovrebbe essere

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

Consideriamo il caso in cui A[i]==A[i+1]entrambi i contatori devono incremento.

Spazzatura Valori

Manca l'inizializzazione @kaylum.

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

Approccio alternativo:

Ci sono 4 possibilità

  • Matrice ha lo stesso valore in ogni dove - o è di lunghezza pari a 0.

  • Array è crescente. A[i] >= A[i-1] per tutti i > 0 e la lunghezza è maggiore di 0.

  • Array è decrescente. A[i] <= A[i-1] per tutti i > 0 e la lunghezza è maggiore di 0.

  • Nessuna delle precedenti.

Semplicemente ciclo e regolare di due bandiere. int tempcr, tempdcr; i contatori non sono necessari.

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;
}

Semplificazioni e alcuni micro ottimizzazione possibile, ma è qualcosa da chiarire un approccio chiaro.


Troppo divertente.

Se int a[] non è costante, si può utilizzare solo 1 test per ogni iterazione invece di 3: test che ho, è di meno, è più il codice.

Primo sguardo per la disuguaglianza dalla fine verso l'inizio. Il primo elemento è regolato per essere diverso dal precedente.

Se siamo in piedi l'intero elenco, abbiamo finito, altrimenti la prima parte dell'elenco è diverso dall'ultimo elemento.

Se l'ultimo confronto è crescente, impostare il primo elemento di INT_MAX e di ricerca verso l'inizio per un non-crescente coppia.

Altrimenti
Se l'ultimo confronto è decrescente, impostare il primo elemento di INT_MIN e di ricerca verso l'inizio per un non-decrescente coppia.

Alla ricerca di un confronto si verifica un errore, l'array è ordinato o siamo all'inizio. Se, all'inizio, di gestire quel caso particolare.

In ogni caso, solo 1 confrontare per ogni iterazione.

#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;
}

Farò qualche test in più in seguito.

Se la matrice è const, bisogno di 2 test per loop.

2021-11-24 05:24:03

Puoi rompere il for loop una volta (se) sia le bandiere diventano false.
500 - Internal Server Error

@500-InternalServerError Vero, ma che non è certo l'ottimizzazione potrebbe anche rallentare il tempo di esecuzione, come sta facendo più il controllo. Dipende, di tipica matrice di imposta. IAC, non riduce O(). Di più qui.
chux - Reinstate Monica

@500-InternalServerError Per divertimento, potrebbe essere interessante bi-setta la matrice a ogni confrontare passaggio e controllare i punti finali fino alla misura 1. Certamente più lento nel peggiore dei casi, ma in grado di attirare precocemente non-array ordinati e consentire per un singolo ordine confrontare e/o di fine-inizio del codice.
chux - Reinstate Monica

Per le matrici di grandi dimensioni, o se il codice è generalizzata a partita qsort() o bsearch()l'interruzione precoce potrebbe essere vantaggioso per le prestazioni — evita potenzialmente molte chiamate di funzione. Quando il tipo di dati è intil sovraccarico di confronto è molto più piccolo, così i primi a rompere vs extra test non è così evidente.
Jonathan Leffler

@500-InternalServerError Così ho avuto qualche divertimento per utilizzare solo 1 confrontare per loop.
chux - Reinstate Monica

È questo un modo corretto per terminare il programma e provarlo? (Io sono arrugginito in C)
Kelly Bundy
1

Per cominciare, la funzione deve essere dichiarata come

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

che è almeno il primo parametro deve avere il qualificatore const perché la matrice passata non è cambiato all'interno della funzione.

Le variabili tempcr e tempdcr non sono state inizializzate e hanno indeterminato valori. In modo che la funzione ha un comportamento indefinito. È necessario inizializzare loro come

int tempcr = 0, tempdcr = 0;

Non ha senso continuare iterazioni del loop se è già noto che l'array è ordinato, perché è inefficiente.

Inoltre, la funzione di una logica di bug.

Si consideri la matrice { 0, 0, -1 }

In questo caso nella prima iterazione del ciclo la variabile tempcr sarà incrementata per l'istruzione if

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

Ma nella seconda iterazione del ciclo la variabile tempdcr sarà aumentata.

Quindi, la funzione di report che l'array è ordinato se è ordinato in ordine decrescente.

Vorrei definire la funzione seguente modo

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 );
}

Se la matrice passata ha tutti gli elementi uguali l'un l'altro, la funzione si considera come ordinati in ordine crescente.

Come fa notare @chux - Ripristinare Monica nella sua risposta, invece di contare elementi che è possibile utilizzare le corrispondenti variabili come gli oggetti booleani. In questo caso, la funzione può apparire come

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

In altre lingue

Questa pagina è in altre lingue

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