Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: Определить слово с самым большим количеством заглавных букв  (Прочитано 9538 раз)
0 Пользователей и 2 Гостей смотрят эту тему.
wooopt
Новенький

ru
Offline Offline

« : 24-03-2019 19:14 » new

Файл содержит набор символов. Слово - произвольная последовательность латинских символов, разделители-любые другие символы.Определить слово с самым большим количеством заглавных букв. Если таких несколько вывести все
Подскажите пожалуйста как все слова вывести
Вроде понимаю Завести массив строк и счетчик, изначально в нем 0. Если в слове нужных букв меньше, чем в уже найденном максимальном - ничего не делать. Если равно - добавить слово в массив, инкрементировать счетчик. Если больше - записать слово в первый элемент массива, в счетчик - единицу.
Но реализовать не могу
Еще есть вариант такой: проходим файл 2 раза, на первом проходе ищем максимальное количество заглавных букв(maxUppers), содержащихся в словах (просто число!), а на втором — выводим слова, содержащие найденное количество указанных букв. Как встречаем такое слово, так сразу и выводим

Код:
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#define N 100
#define DELIM " \t\n"

int upper_letters(const char * word) {
    int uppers = 0;
 
    for ( ; *word; ++word )
        uppers += !!isupper(*word);
   
    return uppers;
}

int main(int argc, char const *argv[])
{

  char buf[N];//обьявление строкового массива
int i=0,max=0;
FILE *filP;
filP=fopen("file.txt","r");

fgets(buf,N,filP);


 
    fgets(buf,N,filP);
        char * str = buf, * maxWord, * curWord;
        int maxUppers, curUppers;
 
        for ( ; *str; ++str )
            if ( ! isalpha(*str) )
                *str = ' ';
       
        maxWord = strtok(buf, DELIM);
        maxUppers = upper_letters(maxWord);
 
        while ( ( curWord = strtok(NULL, DELIM) ) ) {
            curUppers = upper_letters(curWord);
            if ( curUppers > maxUppers ) {
                maxWord = curWord;
                maxUppers = curUppers;
            }
        }
 
        printf("First word with max. upper letters: %s\n", maxWord);
   
 

fclose(filP);
return 0;
}
Записан
Вад
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #1 : 24-03-2019 22:21 » 

Цитата
Еще есть вариант такой: проходим файл 2 раза, на первом проходе ищем максимальное количество заглавных букв(maxUppers), содержащихся в словах (просто число!), а на втором — выводим слова, содержащие найденное количество указанных букв. Как встречаем такое слово, так сразу и выводим
Примерно так.
Есть разные направления оптимизации: так, слова могут быть длинными (ну, когда ту же задачу не к словам применять, а к гигабайтным файлам, например), поэтому считать число букв дважды может быть плохим решением, и эффективнее будет в отдельный массив/файл для каждого слова посчитать число заглавных букв в нём, найти максимум по массиву (можно и в тот же проход), потом новым проходом печатаем все слова, у которых счётчики нужное число насчитали. Но для начала можно и так, двумя полными проходами.

Да, можно и в 1 проход всё сделать, с массивом. Только это уже не совсем чистый массив будет, т.к. заранее неизвестно, сколько там слов понадобится хранить. std::deque хорошо подойдёт, а большего не скажу. Можно записывать туда как сами слова, так и позиции, где они в файле находятся (ftell в помощь).

В вашем полу-рабочем варианте осталось сделать fseek в начало файла и повторить цикл чтения с токенизацией, только уже выводя все слова, у которых заглавных ровно maxUppers штук.
upd. А вот с указателями как-то вольно очень обращаетесь. И в strtok ерунда какая-то передаётся, и в maxWord ерунда будет при невозможности за раз прочитать весь файл (буфера не хватит если), и читать так из файла не стоит. В любом случае, с указателями советую разобраться - или не трогать их вообще, а работать с более безопасными типами. И из файла читать посимвольно, а то у вас в задании разделители - "любые символы", а в коде только перевод строки и каретки, так нельзя.
« Последнее редактирование: 24-03-2019 22:38 от Вад » Записан
Sla
Команда клуба

ua
Offline Offline
Пол: Мужской

WWW
« Ответ #2 : 25-03-2019 08:14 » 

все делается в один проход, без массивов

Посимвольное чтение и занесение считанных  символов в буфер
Поиск происходит ло разделителя, как толко разделитель, то считается количество  заглавных и слово заносится  в результат
И так до конца данных.
На вхоже одно слово с максимальным количеством сиволов



Записан

Мы все учились понемногу... Чему-нибудь и как-нибудь.
Вад
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #3 : 26-03-2019 20:00 » 

все делается в один проход, без массивов

Посимвольное чтение и занесение считанных  символов в буфер
А буфер - не массив? Улыбаюсь Я бы всё-таки вместо единого буфера дек для слов использовал, раз их неизвестно сколько там. Чтоб потом не делать переаллокацию.

Цитата
Поиск происходит ло разделителя, как толко разделитель, то считается количество  заглавных и слово заносится  в результат
Тогда можно ещё проще - посимвольно читать, и сразу считать встречающиеся заглавные. Как только разделитель - проверять, сколько насчитали, сбрасывать счётчик.
« Последнее редактирование: 26-03-2019 20:07 от Вад » Записан
Sla
Команда клуба

ua
Offline Offline
Пол: Мужской

WWW
« Ответ #4 : 27-03-2019 22:42 » 

все делается в один проход, без массивов

Посимвольное чтение и занесение считанных  символов в буфер
А буфер - не массив? Улыбаюсь Я бы всё-таки вместо единого буфера дек для слов использовал, раз их неизвестно сколько там. Чтоб потом не делать переаллокацию.

Нет - это просто строка

Цитата
Поиск происходит ло разделителя, как толко разделитель, то считается количество  заглавных и слово заносится  в результат
Тогда можно ещё проще - посимвольно читать, и сразу считать встречающиеся заглавные. Как только разделитель - проверять, сколько насчитали, сбрасывать счётчик.

Так именно это и предлагаю
т.е. в буфер (строку) - считіваем до разделителя и считаем символы

А уж потом, можно  и реструктуризировать, в момент считывания, или в момент достижения разделителя

Записан

Мы все учились понемногу... Чему-нибудь и как-нибудь.
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines