Форум программистов, компьютерный форум CyberForum.ru

Подсчет частоты алфавита - C++

Восстановить пароль Регистрация
 
 
Рейтинг: Рейтинг темы: голосов - 9, средняя оценка - 4.78
ika11ika
0 / 0 / 0
Регистрация: 16.11.2013
Сообщений: 12
14.12.2013, 16:29     Подсчет частоты алфавита #1
Доброго времени суток. Как посчитать в тексте из файла частоту алфавита(сколько раз каждый символ встречается в приведенном тексте)? Я понимаю, что мы открываем 2 файла: в 1 изначальный текст, в другой записывается частота алфавита. Вот только не посимвольно же этот текст читать и суммировать. А как сделать это на массивах представляю очень образно и на практике не выходит. Помогите хотя бы с теоретической части, а практической может сама дойду. Заранее спасибо!
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Kuzia domovenok
 Аватар для Kuzia domovenok
1882 / 1737 / 116
Регистрация: 25.03.2012
Сообщений: 5,907
Записей в блоге: 1
14.12.2013, 16:35     Подсчет частоты алфавита #2
Цитата Сообщение от ika11ika Посмотреть сообщение
Вот только не посимвольно же этот текст читать и суммировать.
а почему бы и не посимвольно?
Цитата Сообщение от ika11ika Посмотреть сообщение
А как сделать это на массивах представляю очень образно и на практике не выходит.
C++
1
2
3
4
5
6
int symbols[256]={0};
char c;
while(!f.eof()){
  f>>c;
  symbols[c]++;//тут ещё нужно, наверн. подумать, что делать со знаковыми char
}
ika11ika
0 / 0 / 0
Регистрация: 16.11.2013
Сообщений: 12
14.12.2013, 16:38  [ТС]     Подсчет частоты алфавита #3
Цитата Сообщение от Kuzia domovenok Посмотреть сообщение
а почему бы и не посимвольно?
C++
1
2
3
4
5
6
int symbols[256]={0};
char c;
while(!f.eof()){
  f>>c;
  symbols[c]++;//тут ещё нужно, наверн. подумать, что делать со знаковыми char
}
не посимвольно, наверное потому, что если загрузить в файл приличного объема текст(ну не "Войну и мир" конечно, но тоже большое произведение), то скорее всего долга эта программа будем все эти символы считать
Xfaider
11 / 11 / 1
Регистрация: 27.10.2012
Сообщений: 26
14.12.2013, 16:52     Подсчет частоты алфавита #4
Я вижу это так:
создаем массив размере 25(для английского алфавита)
считываем строку
проходим по строке передавая каждый символ в функцию, которая в свою очередь проверяет какой это символ, и в зависимости от того какой, увеличивает значение в массиве
Пример функции:
C++
1
2
3
4
5
6
7
8
9
10
11
12
char 
    c1='a',
    c2='A';
for (int i=0; i<25; i++)
    {
        if (c1==c)
            array[i]++;
        if (c2==c)
            array[i]++;
        c1++;
        c2++;
    }
ya_noob
_
200 / 144 / 9
Регистрация: 08.10.2011
Сообщений: 432
14.12.2013, 17:06     Подсчет частоты алфавита #5
ika11ika, можно так:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <cstdio>
#include <cctype>
using namespace std;
 
int main()
{
    int freq[ 256 ] = { 0 };
 
    const int M = 10000;
    char buf[ M ];
    int m;
 
    while ( ( m = fread( buf, 1, M, stdin ) ) ) // читаем кусками по M байт за раз
        for ( int i = 0; i < m; ++i )
            ++freq[ tolower( buf[ i ] ) ];
 
    for ( char i = 'a'; i <= 'z'; ++i )
        printf( "%c: %d\n", i, freq[ i ] );
 
    return 0;
}
Kuzia domovenok
 Аватар для Kuzia domovenok
1882 / 1737 / 116
Регистрация: 25.03.2012
Сообщений: 5,907
Записей в блоге: 1
14.12.2013, 17:49     Подсчет частоты алфавита #6
Цитата Сообщение от ika11ika Посмотреть сообщение
не посимвольно, наверное потому, что если загрузить в файл приличного объема текст(ну не "Войну и мир" конечно, но тоже большое произведение), то скорее всего долга эта программа будем все эти символы считать
а ничего, что те, кто реализовывал файловые потоки в С++, наверное лучше знают как там чё буферизовать?
ValeryS
Модератор
6374 / 4840 / 441
Регистрация: 14.02.2011
Сообщений: 16,040
14.12.2013, 17:56     Подсчет частоты алфавита #7
Цитата Сообщение от Kuzia domovenok Посмотреть сообщение
symbols[c]++;//тут ещё нужно, наверн. подумать, что делать со знаковыми char
Цитата Сообщение от Kuzia domovenok Посмотреть сообщение
char c;
объявить его беззнаковым
C++
1
unsigned char c;
Цитата Сообщение от ika11ika Посмотреть сообщение
наверное потому, что если загрузить в файл приличного объема текст
одна страница текста A4 занимает примерно 1.5 кБайт
что ты подразумеваешь под файлом большого размера?
сколько страниц ?
gazlan
2855 / 1803 / 271
Регистрация: 27.08.2010
Сообщений: 4,883
Записей в блоге: 1
14.12.2013, 18:08     Подсчет частоты алфавита #8
Цитата Сообщение от ya_noob Посмотреть сообщение
// читаем кусками по M байт за раз
И для чего только страничная организация памяти придумана?
ya_noob
_
200 / 144 / 9
Регистрация: 08.10.2011
Сообщений: 432
14.12.2013, 18:24     Подсчет частоты алфавита #9
Цитата Сообщение от gazlan Посмотреть сообщение
И для чего только страничная организация памяти придумана?
не понял, поясните
gazlan
2855 / 1803 / 271
Регистрация: 27.08.2010
Сообщений: 4,883
Записей в блоге: 1
14.12.2013, 18:55     Подсчет частоты алфавита #10
Обмен памяти с диском происходит страницами. И ваш выбор const int M = 10000; лишен всякого смысла.
ika11ika
0 / 0 / 0
Регистрация: 16.11.2013
Сообщений: 12
14.12.2013, 19:28  [ТС]     Подсчет частоты алфавита #11
Цитата Сообщение от ValeryS Посмотреть сообщение
одна страница текста A4 занимает примерно 1.5 кБайт
что ты подразумеваешь под файлом большого размера?
сколько страниц ?
Ну, в том плане, что в файле может оказаться текст большего размера, чем 1 страница и если будет, например, 10 страниц, то пока она сосчитает все символы...это в моем понимании(женская логика).

Цитата Сообщение от Xfaider Посмотреть сообщение
Я вижу это так:
создаем массив размере 25(для английского алфавита)
считываем строку
проходим по строке передавая каждый символ в функцию, которая в свою очередь проверяет какой это символ, и в зависимости от того какой, увеличивает значение в массиве
Пример функции:
Не вариант, потому что мне нужны все числа и все буквы в том числе заглавные от английского и русского алфавитов. Но не это проблема, ведь, при работе с файлами все равно какой язык используется (для записи, не для вывода).
ya_noob
_
200 / 144 / 9
Регистрация: 08.10.2011
Сообщений: 432
14.12.2013, 19:41     Подсчет частоты алфавита #12
Цитата Сообщение от gazlan Посмотреть сообщение
И ваш выбор const int M = 10000; лишен всякого смысла.
M=10000 было написано "от балды", конечно оптимально будет цифра около 512 (+-). функция read1() читает текстовый файл размером 60 МБ за 1,2 сек, а функция read2() за 5 сек (посимвольное чтение предлагалось до моего первого поста)
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#include <cstdio>
#include <ctime>
#include <cctype>
using namespace std;
 
void read1( int *freq )
{
    const int M = 512;
    char buf[ M ];
 
    for ( int m; ( m = fread( buf, 1, M, stdin ) ); ) // читаем кусками по M байт за раз
        for ( int i = 0; i < m; ++i )
            ++freq[ tolower( buf[ i ] ) ];
}
 
void read2( int *freq )
{
    for ( char c; EOF != ( c = getchar() ); ++freq[ tolower( c ) ] );
}
 
int main()
{
    int freq[ 256 ] = { 0 };
    int timer;
 
    timer = clock();
    read1( freq );
    timer = clock() - timer;
    printf( "%d\n", timer );
 
    return 0;
}
gazlan
2855 / 1803 / 271
Регистрация: 27.08.2010
Сообщений: 4,883
Записей в блоге: 1
14.12.2013, 19:47     Подсчет частоты алфавита #13
Цитата Сообщение от ya_noob Посмотреть сообщение
конечно оптимально будет цифра около 512 (+-)
Прочитайте, наконец, про страничную организацию памяти. И не пишите больше про "+-".
ValeryS
Модератор
6374 / 4840 / 441
Регистрация: 14.02.2011
Сообщений: 16,040
14.12.2013, 20:15     Подсчет частоты алфавита #14
Цитата Сообщение от ika11ika Посмотреть сообщение
Ну, в том плане, что в файле может оказаться текст большего размера, чем 1 страница и если будет, например, 10 страниц, то пока она сосчитает все символы...
и что
даже 1000 страниц считает на глаз незаметно
попробуй прочитать файл побайтно и блоком и если заметишь разницу то то тогда и будем говорить
Цитата Сообщение от Kuzia domovenok Посмотреть сообщение
symbols[c]++;
а это вообще времени мизер займет
но можешь создать в памяти буфер размером с файл считать туда разом, и потом работать с этим буфером

Добавлено через 3 минуты
Цитата Сообщение от ya_noob Посмотреть сообщение
читает текстовый файл размером 60 МБ за 1,2 сек, а функция read2() за 5 сек
во первых 5 секунд это не такое большое время
а во вторых 60 МБ это примерно 50 000 страниц
где в реальности такие файлы? это БСЭ что ли считывать?
ya_noob
_
200 / 144 / 9
Регистрация: 08.10.2011
Сообщений: 432
14.12.2013, 20:29     Подсчет частоты алфавита #15
Цитата Сообщение от gazlan Посмотреть сообщение
Прочитайте, наконец, про страничную организацию памяти.
а оно мне надо? я примерно представляю, как этот процесс происходит, мне этого пока достаточно.
да и вообще, я привел пример с помощью чего можно читать файлы быстрее и не претендовал на идеальное решение. вы могли бы еще в первом ответе уточнить значение M, не тыкая в википедию (про нее я и сам знаю, но нет желания в этом подробно разбираться) и не писать эти бессмысленные фразы типа
Цитата Сообщение от gazlan Посмотреть сообщение
И для чего только страничная организация памяти придумана?
если о чем-то лучше знаете почему бы просто не рассказать об этом???

Добавлено через 2 минуты
Цитата Сообщение от ValeryS Посмотреть сообщение
где в реальности такие файлы? это БСЭ что ли считывать?
набрал строчку, нажал ctrl+C, зажал ctrl+V на несколько секунд и вуаля. Что вы до мелочей докапываетесь то?
ika11ika
0 / 0 / 0
Регистрация: 16.11.2013
Сообщений: 12
14.12.2013, 20:29  [ТС]     Подсчет частоты алфавита #16
А есть какой-нибудь вариант записать это попроще, пусть это будет немного неразумно, с учетом, что есть более "продвинутые" и результативные способы, но попроще.
ya_noob
_
200 / 144 / 9
Регистрация: 08.10.2011
Сообщений: 432
14.12.2013, 20:42     Подсчет частоты алфавита #17
Цитата Сообщение от ika11ika Посмотреть сообщение
А есть какой-нибудь вариант записать это попроще
куда уж проще, 4 строчки кода всего: объявляем массив и двумя циклами читаем и обрабатываем входные данные
ValeryS
Модератор
6374 / 4840 / 441
Регистрация: 14.02.2011
Сообщений: 16,040
14.12.2013, 20:49     Подсчет частоты алфавита #18
Цитата Сообщение от ya_noob Посмотреть сообщение
набрал строчку, нажал ctrl+C, зажал ctrl+V на несколько секунд и вуаля. Что вы до мелочей докапываетесь то?
мы о реальной задаче или о "сферических конях"?
можно и пару сотен гигабайт сгенерить, а потом спрашивать как мне быстрей его прочитать
Цитата Сообщение от ika11ika Посмотреть сообщение
А есть какой-нибудь вариант записать это попроще, пусть это будет немного неразумно, с учетом, что есть более "продвинутые" и результативные способы, но попроще.
чем тебе вариант Кузи Домовенка, не устраивает?
ika11ika
0 / 0 / 0
Регистрация: 16.11.2013
Сообщений: 12
14.12.2013, 20:56  [ТС]     Подсчет частоты алфавита #19
Цитата Сообщение от ya_noob Посмотреть сообщение
куда уж проще, 4 строчки кода всего: объявляем массив и двумя циклами читаем и обрабатываем входные данные
Не могли бы вы мне построчный комментарий написать, чтобы я разобралась, если не сложно?)

Добавлено через 5 минут
Цитата Сообщение от ValeryS Посмотреть сообщение
чем тебе вариант Кузи Домовенка, не устраивает?
я не оспариваю варианты, я просто не могу в них разобраться, вот в чем проблема
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
14.12.2013, 21:08     Подсчет частоты алфавита
Еще ссылки по теме:

C++ Подсчет количества символов русского алфавита в текстовом файле
C++ Быстрое изменение частоты дискретизации имеющегося звука онлайн
Перечислить слова алфавита C++

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
ValeryS
Модератор
6374 / 4840 / 441
Регистрация: 14.02.2011
Сообщений: 16,040
14.12.2013, 21:08     Подсчет частоты алфавита #20
Цитата Сообщение от ika11ika Посмотреть сообщение
я не оспариваю варианты, я просто не могу в них разобраться, вот в чем проблема
Цитата Сообщение от Kuzia domovenok Посмотреть сообщение
int symbols[256]={0};
char c;
while(!f.eof()){
* f>>c;
* symbols[c]++;//тут ещё нужно, наверн. подумать, что делать со знаковыми char
}
поехали по шагам

C++
1
int symbols[256]={0};
выделяем массив на 256 элементов и обнуляем его, в нем будет лежать количество букв в тексте например в 65 ячейке будет лежать количество букв 'A'
C++
1
char c;
здесь ошибка нужно объявить беззнаковую чтобы считать русские буквы
C++
1
unsigned char c;
создадим переменную куда будем считывать буквы
C++
1
while(!f.eof()){
крутим цикл пока не кончится файл
C++
1
 f>>c;
считываем символ из файла
C++
1
symbols[c]++;
увеличиваем значение ячейки на 1
например считали символ 'A' его номер 65
значит увеличиваем 65 ячейку на 1

после цикла в массиве и будет лежать частота букв
например чтобы узнать сколько раз встретилась буква 'B'
достаточно написать
C++
1
cout<<symbols['B'];
Yandex
Объявления
14.12.2013, 21:08     Подсчет частоты алфавита
Ответ Создать тему
Опции темы

Текущее время: 05:38. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru