Precisa verificar se a matriz é classificada usando uma função em C

0

Pergunta

Basicamente, nós precisamos verificar se os elementos de um array 1D são classificados usando uma função: se eles são ordenados em ordem crescente: return 1 se eles estiverem classificados em ordem decrescente: return -1 se eles não são classificados: return 0 Este é o método que estou usando, no entanto, ele não retornar 1, mas isntead 0, Im certeza de onde está o problema, Quaisquer comentários ou novos métodos de resolução do problema são bem-vindos desde que eu sou um novato.

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

Melhor resposta

2

Lógica errada

OP código de falha devido a

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

deve ser

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

Considere o caso quando A[i]==A[i+1], ambos os contadores devem aumentar.

Lixo Valores

Faltando inicialização @kaylum.

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

Abordagem alternativa:

Existem 4 possibilidades

  • Matriz tem o mesmo valor de valor cada de onde ou é de tamanho 0.

  • Matriz é crescente. A[i] >= A[i-1] para todos i > 0 e o comprimento é superior a 0.

  • Matriz é decrescente. A[i] <= A[i-1] para todos i > 0 e o comprimento é superior a 0.

  • Nenhuma das acima.

Simplesmente loop e ajustar duas bandeiras. int tempcr, tempdcr; contadores não são necessárias.

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

Simplificações e alguns micro otimização possível, mas algo para esclarecer de uma abordagem clara.


Muito divertido.

Se int a[] não é constante, podemos usar apenas 1 teste por iteração em vez de 3: teste eu, é menos, é mais do que o código acima.

Primeiro olhar para a desigualdade a partir do final para o início. O primeiro elemento é ajustado para ser diferente do último.

Se nós percorrer a lista inteira, nós somos feitos, caso contrário, a primeira parte da lista difere do último elemento.

Se a última comparação é ascendente, define o primeiro elemento para INT_MAX e de pesquisa para o início de um não-ascendente par.

Caso contrário,
Se a última comparação é decrescente, define o primeiro elemento para INT_MIN e de pesquisa para o início de um não-decrescente, par.

Ao encontrar uma comparação falha ocorre, a matriz é desordenada ou estamos no início. Se, no início, identificador de caso especial.

Em qualquer caso, apenas 1 compare por iteração.

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

Eu vou fazer mais alguns testes posteriores.

Se a matriz é const, precisa de teste 2 por ciclo.

2021-11-24 05:24:03

Você pode quebrar a for repetir uma vez (se) ambos os sinalizadores tornar false.
500 - Internal Server Error

@500-InternalServerError Verdadeiro, ainda que não seja uma certa otimização de como ele poderia também diminuir o tempo de execução como está fazendo mais verificação. Depende do típico matriz de conjuntos. IAC, isso não reduz O(). Mais aqui.
chux - Reinstate Monica

@500-InternalServerError Por diversão, pode ser interessante para bi-seita da matriz em cada comparar passo e verificar os pontos de extremidade até o tamanho de 1. Certamente mais lento, no pior dos casos, mas provavelmente para pegar cedo não ordenada matrizes e permitir único, a fim de comparar e/ou final do início do código.
chux - Reinstate Monica

Para matrizes grandes, ou se o código é generalizada para correspondência qsort() ou bsearch(), o início da ruptura é susceptível de ser benéfico para o desempenho — evita potencialmente muitas chamadas de função. Quando o tipo de dados é int, a sobrecarga de comparação, é muito menor, de modo que o início da quebra vs extra teste não é tão evidente.
Jonathan Leffler

@500-InternalServerError Então eu tinha um pouco de diversão para utilizar apenas 1 compare por ciclo.
chux - Reinstate Monica

É esta uma maneira correta para terminar o seu programa e testá-lo? (Eu estou enferrujado em C)
Kelly Bundy
1

Para começar, a função deve ser declarada como

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

pelo menos, o primeiro parâmetro deve ter o qualificador const porque o passado matriz não está sendo alterado dentro da função.

As variáveis tempcr e tempdcr não foram inicializados e ter indeterminado valores. Então, a função tem um comportamento indefinido. Você tem que inicializar-los como

int tempcr = 0, tempdcr = 0;

Não há sentido continuar iterações do loop se já é sabido que a matriz é não-ordenada, porque é ineficiente.

Além disso, a função tem uma lógica erro.

Considere a matriz { 0, 0, -1 }

Neste caso, na primeira iteração do loop a variável tempcr vai ser aumentado devido a instrução if

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

Mas, na segunda iteração do loop a variável tempdcr vai ser aumentado.

Então, a função irá relatar que a matriz é não-ordenada que é classificada em ordem decrescente.

Gostaria de definir a função da seguinte forma

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 o passado matriz tem todos os elementos iguais uns aos outros, então a função de considera-lo como ordenados em ordem crescente.

Como apontado @chux - Restabelecer Mônica, na sua resposta, em vez da contagem de elementos que você pode usar as variáveis correspondentes as boolean objetos. Neste caso, a função pode olhar 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

Em outros idiomas

Esta página está em outros idiomas

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