Как правильно сделать алгоритм подсчета для подсчета из файла? - PullRequest
0 голосов
/ 24 декабря 2018

Это программа, которая находит наибольшее четное число и время его появления из входного файла и выводит его в выходной файл.У меня проблема с выводом, кажется, есть дополнительная итерация, которая все портит.

int main(int argc, char const *argv[])
{
    int n, num, i, even, count;

    FILE * fptr;
    FILE * fptro;

    fptr =fopen("maximpar.in", "r");
    fptro=fopen("maximpar.out", "w");

   /*scanning the first line from the file to get n for for()*/

    fscanf(fptr, "%d", &n); 

    count = 0;
    even = INT_MIN;
    for(i = 0; i < n; i++)
{
    fscanf(fptr, "%d", &num);

    if( (num % 2 == 0 && num > even) || (even == num) ) 

    /*checking  for largest even number, 
    not sure about the ..||(even == num) part of the condition*/

    {
        even = num;
        count++;
    }

}

    fprintf(fptro, "%d %d", even, count);


    fclose(fptr);
    fclose(fptro);

    return 0;
}

Входной файл

 6
 9 6 9 8 9 8

Выходной файл

8 3 

Почему выходной файл не такой?Я не понимаю

8 2

Ответы [ 3 ]

0 голосов
/ 24 декабря 2018

Ответ в том, что счет был увеличен с 0 до 1, когда b = 6. 2 итерации позже, b = 8 и теперь count = 2, и 2 итерации после этого, b = 8 и count = 3.

Я также рекомендую вам поместить ваше выражение if в круглые скобки для удобства чтения.Комментирование тоже помогло бы :) Я парень по статистике, и я понятия не имею, что вы делаете, основываясь на именах ваших переменных.

Вам необходимо сбросить счетчик внутри блока if, если b> par.

Например:

if (num% 2 == 0 && num> = even) {

if (num > even){ 

    even = num; 
    count = 1; 

} else { 

    count++; 

}

}

Спасибо.

JK

0 голосов
/ 24 декабря 2018

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

Я не проверял это, но оно должно работать:

cate = 0;
par = INT_MIN;

for (i = 0; i < n; i++) {
    fscanf(fptr, "%d", &b);

    // skip odd numbers
    if ((b % 2) != 0)
        continue;

    // get new larger number
    if (b > par) {
        par = b;
        cate = 1;
        continue;
    }

    // increment count on existing largest number
    if (b == par)
        ++cate;
}

ОБНОВЛЕНИЕ:

Я не понимаю, почему явно пропускают итерации, а не только выбирают итерации, которые имеют значение?Есть ли какое-то преимущество?

Да, это лучший стиль.Он допускает простые одноуровневые операторы if, которые могут иметь свои собственные комментарии.

Это позволяет избежать беспорядочного соединения if или тройного уровня if/else лестница.

ИМО, этораспространенное заблуждение [особенно среди начинающих программистов на C], что комплекс if будет выполняться быстрее [или как-то «лучше»], чем несколько простых.

Первый if можно было бы подумать о «пропустить это»итерация "тест.Здесь есть только один.Но для более сложного кода их может быть несколько.

Множественные экранированные условия можно обрабатывать в одном if с if (c1 || c2 || c2 || ... || c10) continue;, но это быстро запутывается.

Здесь для правильной отступной if/else лестничной логики нам понадобится:

if (cond1)
    do_stuff1;
else
    if (cond2)
        do_stuff2;
    else
        if (cond3)
            do_stuff3;

Если мы не находимся в цикле, вот "уловка", чтобы избежать if/else лестничной логики,используя do { ... } while (0);:

do {
    if (cond1) {
        do_stuff1;
        break;
    }

    if (cond2) {
        do_stuff2;
        break;
    }

    if (cond3) {
        do_stuff3;
        break;
    }
} while (0);
0 голосов
/ 24 декабря 2018

заключить условие

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