Dizinin C'deki bir işlev kullanılarak sıralanıp sıralanmadığını kontrol etmeniz gerekir

0

Soru

Temel olarak, bir 1D dizisinin öğelerinin bir işlev kullanılarak sıralanıp sıralanmadığını kontrol etmemiz gerekir: artan düzende sıralanırlarsa: 1 değerini döndürür azalan düzende sıralanırlarsa: -1 değerini döndürür sıralanmazlarsa: 0 değerini döndürür Bu, kullandığım yöntemdir, ancak 1'i döndürmez, ancak 0'dır, Sorunun nerede olduğundan emin değilim, Sorunu çözmek için herhangi bir yorum veya yeni yöntem, yeni başlayanlardan beri açığız.

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

En iyi cevabı

2

Yanlış mantık

Op'nin kodu nedeniyle başarısız oluyor

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

olmalı

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

Durumu ne zaman düşünün A[i]==A[i+1] her iki sayaç da artmalıdır.

Önemsiz Değerler

Başlatma @kaylum eksik.

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

Alternatif yaklaşım:

4 olasılık var

  • Dizi, her yerde aynı değer değerine sahiptir - veya uzunluğu 0'dır.

  • Dizi artıyor. A[i] >= A[i-1] göre i > 0 ve uzunluk 0'dan fazla.

  • Dizi azalıyor. A[i] <= A[i-1] göre i > 0 ve uzunluk 0'dan fazla.

  • Yukarıdakilerin hiçbiri.

Sadece döngü yapın ve iki bayrak ayarlayın. int tempcr, tempdcr; sayaçlara gerek yok.

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

Basitleştirmeler ve bazı mikro optimizasyonlar mümkündür, ancak net bir yaklaşımı netleştirmek için bir şey.


Çok eğlenceli.

Eğer int a[] sabit değil, 3 yerine yineleme başına yalnızca 1 test kullanabiliriz: test ı, daha az, yukarıdaki koddan daha fazladır.

Önce eşitsizliği sondan başa doğru arayın. İlk eleman bir öncekinden farklı olacak şekilde ayarlanır.

Tüm listeyi yürürsek, işimiz biter, aksi takdirde listenin ilk kısmı son öğeden farklıdır.

Son karşılaştırma yükseliyorsa, ilk öğeyi şu şekilde ayarlayın: INT_MAX ve yükselen olmayan bir çift için başa doğru arama yapın.

Aksi takdirde
Son karşılaştırma azalan ise, ilk öğeyi şu şekilde ayarlayın: INT_MIN ve azalan olmayan bir çift için başa doğru arama yapın.

Bir karşılaştırma hatası oluştuğunda, dizi sırasızdır veya baştayız. Eğer başındaysa, o özel durumu halledin.

Her durumda, yineleme başına yalnızca 1 karşılaştırma.

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

Daha sonra biraz daha test yapacağım.

Dizi ise const, döngü başına 2 test gerekir.

2021-11-24 05:24:03

Seni kırmak dışında for her iki bayrak da bir kez (eğer) döngü false.
500 - Internal Server Error

@500-InternalServerError True, ancak bu daha fazla kontrol yaparken çalışma süresini yavaşlatabileceğinden belirli bir optimizasyon değildir. Tipik dizi kümelerine bağlıdır. IAC, O () değerini düşürmez. Daha fazla burada.
chux - Reinstate Monica

@500-İnternalServerError Eğlenmek için, her karşılaştırma adımında diziyi iki kez taramak ve bitiş noktalarını 1 boyutuna kadar kontrol etmek ilginç olabilir. En kötü durumda kesinlikle daha yavaştır, ancak erken sıralı olmayan dizileri yakalama ve tek sıralı karşılaştırma ve/veya son erken kodlara izin verme olasılığı daha yüksektir.
chux - Reinstate Monica

Büyük diziler için veya kod eşleşecek şekilde genelleştirilmişse qsort() veya bsearch() bu nedenle, erken bir kopuşun performans için yararlı olması muhtemeldir — potansiyel olarak birçok işlev çağrısından kaçınır. Veri türü olduğunda int karşılaştırma yükü çok daha küçüktür, bu nedenle erken mola ve ek testler o kadar net değildir.
Jonathan Leffler

@500-İnternalServerError Bu yüzden döngü başına sadece 1 karşılaştırma kullanmak için biraz eğlendim.
chux - Reinstate Monica

Bu, programınızı bitirmenin ve test etmenin doğru bir yolu mu? (C'de paslandım)
Kelly Bundy
1

Yeni başlayanlar için işlev şu şekilde bildirilmelidir

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

bu, en azından ilk parametrenin niteleyiciye sahip olması gerektiğidir const çünkü geçirilen dizi işlev içinde değiştirilmiyor.

Değişken tempcr ve tempdcr başlatılmadı ve belirsiz değerlere sahipti. Yani işlev tanımlanmamış davranışa sahiptir. Onları şu şekilde başlatmalısın

int tempcr = 0, tempdcr = 0;

Dizinin verimsiz olduğu için sıralanmamış olduğu zaten biliniyorsa, döngünün yinelemelerine devam etmenin bir anlamı yoktur.

Dahası, işlevin mantıksal bir hatası var.

Diziyi düşünün { 0, 0, -1 }

Bu durumda, döngünün ilk yinelemesinde değişken tempcr ıf beyanı nedeniyle artırılacaktır

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

Ancak döngünün ikinci yinelemesinde değişken tempdcr artırılacak.

Bu nedenle, işlev, azalan düzende sıralanmış olsa da dizinin sıralanmadığını bildirir.

İşlevi şu şekilde tanımlarım

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

Geçirilen dizinin tüm öğeleri birbirine eşitse, işlev onu artan düzende sıralanmış olarak değerlendirir.

İşaret ettiği gibi @chux - Monica'yı cevabında eski haline getirin öğeleri saymak yerine karşılık gelen değişkenleri boole nesneleri olarak kullanabilirsiniz. Bu durumda işlev şöyle görünebilir

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

Diğer dillerde

Bu sayfa diğer dillerde

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