Как определить, что список чисел увеличивается, уменьшается или неупорядочен, просто используя простой оператор вместо массива, карты или другой функции?

#c

Вопрос:

Ниже приведен код, который я использовал для определения списка порядка чисел (увеличение, уменьшение или неупорядоченный). Или есть какой-либо другой более простой математический способ определить, что список чисел неупорядочен, вместо использования 3 переменных?

Редактировать: 1. В списке может быть дублированный номер (так что я тоже должен иметь сравнение для равного состояния. Спасибо тем, кто указывает на это).

 #include <stdio.h>
int main()
{
    int num, counter, a, b, c, pattern, unordered_flag;
    printf("How many number u want to enter? ");
    scanf("%d", amp;num);
    
    counter = 0; b = 0; c = 0;
    while(counter < num){
        printf("Enter number [%d] : ",counter 1);
        scanf("%d", amp;a);
        printf("a=%d b=%d c=%d pattern=%dn",a,b,c,pattern); //I used this to check the value of a,b,c and pattern
        if(a>b>c){
            pattern = 99; //i use 99 to represent increasing order
        }
        else if(a<b<c){
            pattern = 11; //i use 11 to represent decreasing order
        }
        else{
            pattern = 55; //i use 55 to represent unordered order
            unordered_flag = 404;
        }
        c = b;
        b = a;
        counter = counter   1; 
    }
    if (unordered_flag == 404){
        printf("nThe pattern is : Unordered");
    }
    else if(pattern == 99){
        printf("nThe pattern is : Increasing");
    }
    else if(pattern == 11)
        printf("nThe pattern is : Decreasing");
  
    return 0;  
}
 

Комментарии:

1. if(a>b>c) не делает то, что вы думаете. Вам нужно if(a>b amp;amp; b>c)

2. Вам просто нужно сравнить первые два числа, чтобы увидеть, увеличиваются они или уменьшаются. Затем сравните каждое оставшееся число с предыдущим, чтобы увидеть, находятся ли они в том же порядке, что и первые два. Как только заказ изменится, вы можете сообщить, что он неупорядочен.

3. вам нужно проверить 4 состояния, а не только три. Четвертое : все равны.

4. @Barmarесли все равны, будет трудно назвать это «неупорядоченным»

5. Это принесло бы большую пользу от enum использования вместо магических чисел — вот для чего оно существует. Это можно рассматривать как простой конечный автомат.

Ответ №1:

Это и есть концепция монотонности. В конечном сильно упорядоченном списке вы могли бы использовать конечный автомат.

Монотонный FSM.

С помощью (1): переменной для хранения 8 состояний (практически может быть enum указателем функции or) и (2): памяти последнего элемента, можно полностью определить в режиме онлайн следующее состояние. Расстояние в три перехода — это минимум, который требуется для покрытия вершин.

* Редактировать: более слабую версию этого можно сделать, свернув состояния, выделенные синим цветом.

Например, этот (очень неполный) конечный автомат может быть таким, как это можно было бы сделать с enum помощью . Это предпочтительнее, чем использовать целочисленные магические значения для удобства чтения и отладки.

 #include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <limits.h>

/* X-Macro; just lazy. */
#define STATES X(EMPTY), X(ONE), X(STRICT_INCREASE), X(STRICT_DECREASE), 
    X(EQUAL), X(INCREASE), X(DECREASE), X(UNORDERED)

int main(int argc, const char **argv) {
    struct {
#define X(x) x
        enum { STATES } state;
#undef X
        int prev;
    } sm = { EMPTY, 0 };
#define X(x) #x
    static char *names[] = { STATES };
#undef X
    int success = EXIT_FAILURE;
    (void)argc; /* Unused; `argv` is null-terminated. */
    errno = 0; /* `strtol` on POSIX-compliant systems gives more info. */
    while(*(  argv)) {
        /* Read a parameter from the command line. */
        char *end;
        int num;
        long temp = strtol(argv[0], amp;end, 0);
        if(errno) goto catch;
        if(temp < INT_MIN || temp > INT_MAX)
            { errno = ERANGE; goto catch; }
        if(*end != '')
            { errno = EILSEQ; goto catch; }
        num = (int)temp;
        /* Plug the parameter into the state machine. */
        switch(sm.state) {
        case EMPTY:
            sm.state = ONE; break;
        case ONE:
            if(sm.prev < num) sm.state = STRICT_INCREASE;
            else if(num < sm.prev) sm.state = STRICT_DECREASE;
            else sm.state = EQUAL;
            break;
        case STRICT_INCREASE: /**** TODO! ****/
        case STRICT_DECREASE:
        case EQUAL:
        case INCREASE:
        case DECREASE:
            sm.state = UNORDERED; break;
        case UNORDERED:
            break;
        }
        sm.prev = num;
    }
    printf("This is %s.n", names[sm.state]);
    { success = EXIT_SUCCESS; goto finally; }
catch:
    perror("list-of-ints");
finally:
    return success;
}
 

Комментарии:

1. Интересно! Решение OP (с использованием нескольких переменных с сумасшедшими «значениями флага», такими как «99» и «11»)… это просто неправильно. Вы правы: одна «переменная состояния», которая является «перечислением», — это абсолютно правильный путь. Но нужен ли нам полноценный FSM .. или просто простой цикл «while ()» — это решать оператору.