Какие параметры установить в качестве основного цикла - PullRequest
3 голосов
/ 02 апреля 2020

Хорошо, у меня есть домашний вопрос, который выглядит следующим образом: Из массива составьте пары (b, c), где b - это наименьшее четное число, а c - наибольший. Запишите числа в вывод, удалите их из массива и продолжайте l oop, пока четных чисел больше не будет, или массив не станет пустым.

РЕДАКТИРОВАТЬ: Если есть только 1 четное число, выведите его как самое большое и самое низкое число одновременно, так что в конечном массиве нет четных чисел.

Вот что я сделал сейчас:

int a[100], b, c, n;
b = 9999999;
c = -9999999;

printf("Input array length: ");
scanf("%d", &n);
printf("Input elements of array: ");

for (int i = 0; i < n; i++) {
    scanf("%d", &a[i]);
}

    for (int i = 0; i < n; i++) {
        if (a[i] < b && a[i] % 2 == 0)
            b = a[i];
    }

    for (int i = 0; i < n; i++) {
        if (a[i] > c && a[i] % 2 == 0)
            c = a[i];
    }

    printf("\n%d %d\n", b, c);

return 0;

Я установил абсурдные значения для b и c при запуске, так что я на 99% уверен, что в массиве будут числа, которые ниже / выше этих значений (я пытался установить их как NULL, но это не так). Итак, мой вопрос, как установить основной l oop, который будет кружиться, пока нет четных чисел или массив не пуст? Также есть еще один способ, которым я могу инициализировать b и c.

Кроме того, для удаления четных чисел, я подумал сделать что-то вроде этого:

for (int i = pos; i < n; i++) 
    a[i] = a[i+1];
n--;

Где pos - индекс четного элемента.

Ответы [ 4 ]

2 голосов
/ 03 апреля 2020

Вы не можете изменить размер массива, но вы можете отслеживать его размер фактических элементов.

Я полагаю, что если в массиве есть только один четный элемент, то нет пары минимального и максимального четных элементов. в массиве. Так что в этом случае ничего не «удаляется» из массива, и процесс останавливается. Однако вы можете изменить подход и «удалить» даже один четный элемент.

А запрос присваивания для удаления элементов означает, что порядок элементов в массиве должен быть сохранен. Вы не можете сортировать массив. То есть, когда вас просят удалить элемент из массива, это не означает, что вы должны сортировать массив .:)

Вот демонстрационная программа.

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>

struct Pair
{
    size_t min;
    size_t max;
};

struct Pair minmax_element( const int a[], size_t n )
{
    struct Pair p = { n, n };

    for ( size_t i = 0; i < n; i++ )
    {
        if ( a[i] % 2 == 0 )
        {
            if ( p.min == n || a[i] < a[p.min] ) p.min = i;
            if ( p.max == n || a[p.max] < a[i] ) p.max = i;
        }           
    }

    return p;
}

int main(void) 
{
    enum { N = 20 };
    int a[N];

    srand( ( unsigned int )time( NULL ) );

    for ( size_t i = 0; i < N; i++ ) a[i] = rand() % N;

    for ( size_t i = 0; i < N; i++ )
    {
        printf( "%d ", a[i] );
    }

    putchar( '\n' );

    int success = 1;
    size_t n = N;

    while ( success )
    {
        struct Pair p = minmax_element( a, n );

        success = p.min != n && p.max != n;

        if ( success )
        {
            printf( "minimum even number = %d, maximum even number = %d\n",
                    a[p.min], a[p.max] );

            if ( p.max < p.min )
            {
                size_t tmp = p.min;
                p.min = p.max;
                p.max = tmp;
            }

            memmove( a + p.max, a + p.max + 1, ( n - p.max - 1 ) * sizeof( int ) );
            --n;
            memmove( a + p.min, a + p.min + 1, ( n - p.min - 1 ) * sizeof( int ) );
            --n;
        }
    }

    for ( size_t i = 0; i < n; i++ )
    {
        printf( "%d ", a[i] );
    }

    putchar( '\n' );

    return 0;
}

Ее выходные данные могут выглядеть следующим образом:

8 3 6 16 3 4 9 8 1 4 15 9 16 12 3 7 10 19 15 15 
minimum even number = 4, maximum even number = 16
minimum even number = 4, maximum even number = 16
minimum even number = 6, maximum even number = 12
minimum even number = 8, maximum even number = 10
3 3 9 8 1 15 9 3 7 19 15 15 

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

Редактировать: С учетом вашего комментария

Извините, я забыл упомянуть, что если есть только 1 элемент (в этом примере 8), вы просто выводите его 2 раза на и, как наименьшее и наибольшее число, так что конечный результат не имеет четных чисел.

демонстрационная программа может выглядеть следующим образом

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>

struct Pair
{
    size_t min;
    size_t max;
};

struct Pair minmax_element( const int a[], size_t n )
{
    struct Pair p = { n, n };

    for ( size_t i = 0; i < n; i++ )
    {
        if ( a[i] % 2 == 0 )
        {
            if ( p.min == n || a[i] < a[p.min] ) p.min = i;
            if ( p.max == n || a[p.max] < a[i] ) p.max = i;
        }           
    }

    return p;
}

int main(void) 
{
    enum { N = 20 };
    int a[N];

    srand( ( unsigned int )time( NULL ) );

    for ( size_t i = 0; i < N; i++ ) a[i] = rand() % N;

    for ( size_t i = 0; i < N; i++ )
    {
        printf( "%d ", a[i] );
    }

    putchar( '\n' );

    int success = 1;
    size_t n = N;

    while ( success )
    {
        struct Pair p = minmax_element( a, n );

        success = p.min != n;

        if ( success )
        {
            if ( p.max == n ) p.max = p.min;

            printf( "minimum even number = %d, maximum even number = %d\n",
                    a[p.min], a[p.max] );

            if ( p.max < p.min )
            {
                size_t tmp = p.min;
                p.min = p.max;
                p.max = tmp;
            }

            memmove( a + p.max, a + p.max + 1, ( n - p.max - 1 ) * sizeof( int ) );
            --n;

            if ( p.min != p.max )
            {
                memmove( a + p.min, a + p.min + 1, ( n - p.min - 1 ) * sizeof( int ) );
            --  n;
            }
        }
    }

    for ( size_t i = 0; i < n; i++ )
    {
        printf( "%d ", a[i] );
    }

    putchar( '\n' );

    return 0;
}

Ее вывод может похожи

3 10 0 12 16 0 13 11 15 16 6 8 11 10 11 12 4 14 4 3 
minimum even number = 0, maximum even number = 16
minimum even number = 0, maximum even number = 16
minimum even number = 4, maximum even number = 14
minimum even number = 4, maximum even number = 12
minimum even number = 6, maximum even number = 12
minimum even number = 8, maximum even number = 10
minimum even number = 10, maximum even number = 10
3 13 11 15 11 11 3 
2 голосов
/ 03 апреля 2020

Итак, эта проблема намного проще, если вы просто сортируете массив.

Я бы заменил ваш ток для циклов на следующую логику c:

1) Сортировка массива по убыванию.

2) Приращение по массиву из оба конца и выскакивают самые высокие и самые низкие значения тогда и только тогда, когда они четные.

3) В конце концов ваши приращения встретятся в середине, и l oop может закончиться, когда два счетчика встретятся.

Это просто простая сортировка, за которой следует единица для l oop. После того, как они появятся, вы можете установить значения, которые вы указали, равными 0.

1 голос
/ 03 апреля 2020

Вам нужно установить охват, в то время как l oop продолжает работать, пока в массиве есть даже элементы. Вы можете отказаться от этого l oop, если не найдете четных элементов в своей итерации. Также кажется, что на данный момент вы не реализовали удаление из массива; это можно сделать несколькими способами, но, на мой взгляд, проще всего просто сохранить второй «проверенный» массив, который хранит 1 или 0, чтобы показать, был ли элемент ранее взят. Следующим образом:

    int seen[n];
    for (int i = 0; i < n; i++){
        seen[i] = 0;
    }

    while (1){
        int flag = 0, ind1 = 0, ind2 = 0;
        b = 0;
        c = 0;
        for (int i = 0; i < n; i++) {
            if ((!flag || a[i] < b) && a[i] % 2 == 0 && !seen[i]){
                flag = 1;
                b = a[i];
                ind1 = i;
            }
        }

        flag = 0;
        for (int i = 0; i < n; i++) {
            if ((!flag || a[i] > c) && a[i] % 2 == 0 && !seen[i] && i != ind1){
                flag = 1;
                c = a[i];
                ind2 = i;
            }
        }
        if (!flag){
            printf("No more even elements (or only one remaining) in the array.\n");
            break;
        }

        seen[ind1] = 1;
        seen[ind2] = 1; // "removing" them from the array

        printf("\n%d %d\n", b, c);
    }

Флаг устанавливается в 0 в конце секунды для l oop, если он не может найти четное число, которое еще должно быть взято, и нарушает это условие.

Это также решает проблему инициализации b и c. Ваш текущий подход к этому, вероятно, подходит в большинстве случаев, но в этом решении вы просто устанавливаете для них первое четное значение, найденное в массиве (которое ранее не принималось), так как минимум будет меньше или равен это, и максимум больше или равен ему.

В качестве примечания, еще один (более легкий) способ «удалить значения» - установить для них нечетные числа, так как тогда вы просто пропустите их в итерации. Я решил не go использовать этот подход в интересах сохранения исходного массива, если это то, что предпочитает ваш учитель.

0 голосов
/ 16 апреля 2020

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

Сделайте переменная odd [n] ( не рекомендуется ), если вы беспокоитесь об используемой памяти, вы можете просто сделать a для l oop от 0 до n-1, чтобы узнать, сколько нечетных чисел вы можете сделать его нечетным [n_odd].

Затем вы делаете для l oop от 0 до n-1, если число нечетное, присвойте ему нечетное []. Так что вам просто нужно распечатать только нечетные числа. Если необходимо найти четные числа max & min и удалить пары, вы можете игнорировать мой комментарий (это идея, а не ответ). В противном случае ответ Влада будет правильным.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...