Нужно проверить, отсортирован ли массив с помощью функции в C

0

Вопрос

В принципе, нам нужно проверить, отсортированы ли элементы 1D-массива с помощью функции: если они отсортированы в порядке возрастания: верните 1 , если они отсортированы в порядке убывания: верните -1 , если они не отсортированы: верните 0 Это метод, который я использую, однако он не возвращает 1, но равен 0, я не уверен, в чем проблема, Любые комментарии или новые методы решения проблемы приветствуются, так как я новичок.

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

Лучший ответ

2

Неправильная логика

Код операции выходит из строя из-за

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

должно быть

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

Рассмотрим случай, когда A[i]==A[i+1], оба счетчика должны увеличиваться.

Ненужные Ценности

Отсутствует инициализация @kaylum.

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

Альтернативный подход:

Есть 4 возможности

  • Массив имеет одно и то же значение, где - или имеет длину 0.

  • Массив растет. A[i] >= A[i-1] для всех i > 0 и длина больше 0.

  • Массив идет по убыванию. A[i] <= A[i-1] для всех i > 0 и длина больше 0.

  • Ни один из вышеперечисленных.

Просто зациклите и отрегулируйте два флага. int tempcr, tempdcr; счетчики не нужны.

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

Возможны упрощения и некоторая микрооптимизация, но кое-что прояснит четкий подход.


Слишком весело.

Если int a[] не является постоянным, мы можем использовать только 1 тест на итерацию вместо 3: тест i, меньше, больше из приведенного выше кода.

Сначала посмотрите на неравенство от конца к началу. Первый элемент настраивается так, чтобы он отличался от последнего.

Если мы пройдем весь список, мы закончим, в противном случае первая часть списка отличается от последнего элемента.

Если последнее сравнение выполняется по возрастанию, установите для первого элемента значение INT_MAX и ищите в начале не восходящую пару.

Иначе
Если последнее сравнение выполняется по убыванию, установите для первого элемента значение INT_MIN и ищите в начале неубывающую пару.

При обнаружении ошибки сравнения либо массив неупорядочен, либо мы находимся в начале. Если в начале, разберитесь с этим особым случаем.

В любом случае, только 1 сравнение за итерацию.

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

Я проведу еще несколько тестов позже.

Если массив является const, нужно 2 теста на цикл.

2021-11-24 05:24:03

Вы можете вырваться из for цикл один раз (если) оба флага становятся false.
500 - Internal Server Error

@500-InternalServerError Верно, но это не является определенной оптимизацией, так как это также может замедлить время выполнения, поскольку выполняется больше проверок. Зависит от типичных наборов массивов. IAC, это не уменьшает O(). Подробнее здесь.
chux - Reinstate Monica

@500-InternalServerError Для развлечения может быть интересно разделить массив на две части на каждом шаге сравнения и проверять конечные точки до тех пор, пока размер не уменьшится до 1. Конечно, в худшем случае медленнее, но, скорее всего, будет перехватывать ранние неупорядоченные массивы и позволит сравнивать один заказ и/или завершать ранний код.
chux - Reinstate Monica

Для больших массивов или если код обобщен для соответствия qsort() или bsearch(), ранний перерыв, вероятно, будет полезен для производительности — он позволяет избежать потенциально многих вызовов функций. Когда тип данных является int, накладные расходы на сравнение намного меньше, поэтому ранний перерыв против дополнительного тестирования не так очевиден.
Jonathan Leffler

@500-InternalServerError Так что мне было немного весело использовать только 1 сравнение за цикл.
chux - Reinstate Monica

Это правильный способ завершить вашу программу и протестировать ее? (Я заржавел в C)
Kelly Bundy
1

Для начала функция должна быть объявлена следующим образом

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

то есть, по крайней мере, первый параметр должен иметь квалификатор const потому что переданный массив не изменяется внутри функции.

Переменные tempcr и tempdcr не были инициализированы и имеют неопределенные значения. Таким образом, функция имеет неопределенное поведение. Вы должны инициализировать их, как

int tempcr = 0, tempdcr = 0;

Нет смысла продолжать итерации цикла, если уже известно, что массив несортирован, потому что он неэффективен.

Кроме того, в функции есть логическая ошибка.

Рассмотрим массив { 0, 0, -1 }

В этом случае на первой итерации цикла переменная tempcr будет увеличено за счет заявления if

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

Но на второй итерации цикла переменная tempdcr будет увеличен.

Таким образом, функция сообщит, что массив не отсортирован, хотя он отсортирован в порядке убывания.

Я бы определил функцию следующим образом

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

Если переданный массив содержит все элементы, равные друг другу, то функция считает его отсортированным в порядке возрастания.

Как указал @chux - Восстановите Монику в своем ответе, вместо подсчета элементов вы можете использовать соответствующие переменные в качестве логических объектов. В этом случае функция может выглядеть так

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

На других языках

Эта страница на других языках

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

Популярное в этой категории

Популярные вопросы в этой категории