Trzeba sprawdzić, posortowana czy tablicy za pomocą funkcji w C

0

Pytanie

W zasadzie, musimy sprawdzić, sortowane czy elementy 1D-tablicy za pomocą funkcji: jeśli są one sortowane w porządku rosnącym: oddajcie 1 jeśli są one sortowane w kolejności malejącej: oddajcie -1 jeśli nie są sortowane: oddajcie 0 Jest to metoda, która używam, jednak on nie zwraca 1, ale jest równa 0, nie wiem, w czym problem, Wszelkie uwagi lub nowe metody rozwiązania problemu mile widziane, jako, że jestem nowy.

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

Najlepsza odpowiedź

2

Błędna logika

Kod operacji wywala z powodu

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

powinno być

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

Rozważmy przypadek, gdy A[i]==A[i+1]oba licznika powinny rosnąć.

Niepotrzebne Wartości

Brakuje inicjowanie @kaylum.

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

Alternatywne podejście:

Są 4 możliwości

  • Tablica ma to samo znaczenie, gdzie lub ma długość 0.

  • Tablica rośnie. A[i] >= A[i-1] dla wszystkich i > 0 i długość jest większa niż 0.

  • Tablica idzie malejąco. A[i] <= A[i-1] dla wszystkich i > 0 i długość jest większa niż 0.

  • Żaden z powyższych.

Po prostu зациклите i ustaw dwie flagi. int tempcr, tempdcr; liczniki nie są potrzebne.

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

Możliwe są pewne uproszczenia i микрооптимизация, ale coś wyjaśni wyraźny podejście.


Zbyt zabawne.

Jeśli int a[] nie jest stały, możemy użyć tylko 1 test na iterację zamiast 3: testy i, mniej, więcej z powyższego kodu.

Najpierw spójrz na nierówności od końca do początku. Pierwszy element jest regulowany tak, aby różnił się on od tego ostatniego.

Jeśli przejdziemy pełna lista skończymy, w przeciwnym razie pierwsza część listy różni się od ostatniego elementu.

Jeśli to ostatnie porównanie jest wykonywane w kolejności rosnącej, zaznacz pierwszy element wartość INT_MAX i szukajcie na początku nie wzrosty na parze.

Inaczej
Jeśli to ostatnie porównanie jest wykonywane malejąco, zaznacz pierwszy element wartość INT_MIN i szukajcie na początku неубывающую parę.

W przypadku wykrycia błędu porównania lub tablica неупорядочен, albo znajdujemy się na początku. Jeśli na początku zapoznaj się z tym szczególnym wydarzeniem.

W każdym razie, tylko 1 porównanie za iterację.

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

Zrobię jeszcze kilka testów później.

Jeśli tablica jest consttrzeba 2 test na cykl.

2021-11-24 05:24:03

Można wyrwać się z for cykl jeden raz (jeżeli) obie flagi stają się false.
500 - Internal Server Error

@500-InternalServerError Prawda, ale to nie jest pewnego optymalizacją, ponieważ może to również spowolnić czas realizacji, ponieważ wykonywana jest więcej kontroli. Zależy od typowych zestawów tablic. IAC, to nie zmniejsza O(). Więcej informacji tutaj.
chux - Reinstate Monica

@500-InternalServerError Dla rozrywki może być ciekawe podziel tablicę na dwie części na każdym kroku porównania i sprawdzać punkty końcowe, dopóki rozmiar nie zmniejszy się do 1. Oczywiście, w najgorszym wypadku wolniej, ale najprawdopodobniej będzie przechwytywać wczesne nieuporządkowane tablice i pozwoli porównać jedno zamówienie i/lub uzupełniać wcześniejszy kod.
chux - Reinstate Monica

Dla dużych tablic lub jeśli kod uogólnione dla zgodności qsort() lub bsearch(), wczesne przerwę, prawdopodobnie będzie to przydatne dla wydajności, pozwala uniknąć potencjalnie wielu wywołań funkcji. Gdy typ danych jest int, koszty porównaj znacznie mniej, więc o wcześniejszą przerwę przeciwko testowania nie jest tak oczywiste.
Jonathan Leffler

@500-InternalServerError Tak, że było mi z tym trochę zabawy użyć tylko 1 porównanie na cykl.
chux - Reinstate Monica

To jest właściwy sposób zakończyć swój program i przetestować go? (Jestem zardzewiały w C)
Kelly Bundy
1

Na początek funkcja musi być zadeklarowana w następujący sposób

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

czyli, przynajmniej pierwszy parametr musi mieć kwalifikacje const bo przekazany do tablicy nie zmienia się wewnątrz funkcji.

Zmienne tempcr i tempdcr nie były inicjowane i mają wartości nieokreślone. W ten sposób funkcja ma niepewne zachowanie. Musisz zainicjować ich, jak

int tempcr = 0, tempdcr = 0;

Nie ma sensu kontynuować iteracji pętli, jeśli już wiadomo, że tablica несортирован, bo on jest nieskuteczne.

Ponadto, w funkcji jest błąd logiczny.

Rozważmy tablicę { 0, 0, -1 }

W tym przypadku na pierwszej iteracji pętli zmienna tempcr zostanie zwiększona poprzez oświadczenia if

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

Ale na drugiej iteracji pętli zmienna tempdcr zostanie zwiększona.

W ten sposób funkcja informuje, że tablica nie jest posortowana, choć jest posortowana w kolejności malejącej.

Ja bym określił funkcję w następujący sposób

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

Jeśli przekazany tablica zawiera wszystkie elementy równe sobie nawzajem, to funkcja uważa go отсортированным w porządku rosnącym.

Jak wskazał @chux - Przywróć Monice w swojej odpowiedzi, zamiast liczenia elementów można użyć odpowiednie zmienne jako logicznych obiektów. W tym przypadku funkcja może wyglądać tak

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

W innych językach

Ta strona jest w innych językach

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