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

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 9, средняя оценка - 4.67
w0nder
0 / 0 / 0
Регистрация: 23.11.2012
Сообщений: 131
#1

Посимвольная обработка текстового файла: распределение всех слов по длине - C++

03.03.2013, 02:56. Просмотров 1157. Ответов 21
Метки нет (Все метки)

Вывести в файле распределение всех слов по длине (т.е. сколько в файле слов из одной буквы, из двух и т.д.). За слово считать цепочку символов, которая отделена пробелами, точкой, запятой, круглыми скобками, воскл.знаком, вопр.знаком.

(Данные из файла считывать посимвольно, нельзя сразу считывать весь файл или целую строчку, нельзя копировать все содержимое файла в оперативную память.)
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
03.03.2013, 02:56     Посимвольная обработка текстового файла: распределение всех слов по длине
Посмотрите здесь:

C++ Посимвольная обработка UTF8 строки
C++ Обработка текстового файла
C++ Посимвольная обработка строк
Посимвольная обработка строки C++
C++ Посимвольная обработка строк
C++ Посимвольная обработка строк
Осуществить сортировку текстового файла по длине строк циклическим слиянием/разделением C++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Черный ворон
129 / 123 / 6
Регистрация: 31.01.2012
Сообщений: 435
03.03.2013, 03:32     Посимвольная обработка текстового файла: распределение всех слов по длине #2
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
33
34
35
36
#include <fstream.h>
#include <iostream.h>
bool check(char c){
if (c==' ') return true;
if (c=='.') return true;
if (c==',') return true;
if (c=='!') return true;
if (c=='(') return true;
if (c==')') return true;
return false;
}
 
int main(){
int count[25]; //максимальная длина слова 25 символов. можно и увеличить...
int n=25;
char c;
int t=0;
for (int i=0; i<n; i++) count[i]=0;
ifstream input ("D:\\1.txt");
while (!input.eof()){
        input.get(c);
        if (!check(c)){
                t++;
        }
        else
        {
                count[t-1]++;
                t=0;
        }
}
count[t-2]++;
for (int i=0; i<n-1; i++)
cout<<"words with "<<i+1<<" letters: "<<count[i]<<endl;
system ("pause");
return 0;
}
простенький тестовый пример код прошел, но советую все-таки внимательно протестировать
w0nder
0 / 0 / 0
Регистрация: 23.11.2012
Сообщений: 131
03.03.2013, 03:49  [ТС]     Посимвольная обработка текстового файла: распределение всех слов по длине #3
Спасибо!
Только компилятор вот на что ругается:

[IMG]http://s018.***********/i515/1303/ce/ef27a7cac6e8.png[/IMG]
alsav22
5415 / 4811 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
03.03.2013, 05:13     Посимвольная обработка текстового файла: распределение всех слов по длине #4
C++
1
2
3
#include <fstream.h>
#include <iostream.h>
using namespace std;
w0nder
0 / 0 / 0
Регистрация: 23.11.2012
Сообщений: 131
09.03.2013, 23:29  [ТС]     Посимвольная обработка текстового файла: распределение всех слов по длине #5
А что делает переменная t?
Черный ворон
129 / 123 / 6
Регистрация: 31.01.2012
Сообщений: 435
09.03.2013, 23:45     Посимвольная обработка текстового файла: распределение всех слов по длине #6
w0nder, переменная t считает сколько символов в текущем просматриваемом слове
w0nder
0 / 0 / 0
Регистрация: 23.11.2012
Сообщений: 131
09.03.2013, 23:58  [ТС]     Посимвольная обработка текстового файла: распределение всех слов по длине #7
Спасибо, и еще один вопрос. Я так поняла, что с 22 по 30 строчку задействована переменная t, которая считает кол-во символов в каждом слове, и, если в файле встретится разделяющий символ, то он не будет подсчитан.

А для чего дальше строчка
C++
1
count[t-2]++;
?
Черный ворон
129 / 123 / 6
Регистрация: 31.01.2012
Сообщений: 435
10.03.2013, 00:05     Посимвольная обработка текстового файла: распределение всех слов по длине #8
w0nder, не совсем так. если в файле встречается разделяющий символ он будет не посчитан, кроме того количество слов с t буквами будет увеличено на единицу.
эта строчка нужна для верной обработки последнего слова в файле (специфика возникает из-за возможного отсутствия разделителя перед концом файла).
w0nder
0 / 0 / 0
Регистрация: 23.11.2012
Сообщений: 131
10.03.2013, 17:24  [ТС]     Посимвольная обработка текстового файла: распределение всех слов по длине #9
Черный ворон, ивиняюсь, еще - все не могу понять, какую функцию выполняет 18 строчка?
Черный ворон
129 / 123 / 6
Регистрация: 31.01.2012
Сообщений: 435
10.03.2013, 17:46     Посимвольная обработка текстового файла: распределение всех слов по длине #10
w0nder, строка 18
C++
1
for (int i=0; i<n; i++) count[i]=0;
инициализирует нулями количество подсчитываемых слов различной длинны.
w0nder
0 / 0 / 0
Регистрация: 23.11.2012
Сообщений: 131
10.03.2013, 18:45  [ТС]     Посимвольная обработка текстового файла: распределение всех слов по длине #11
И получается, что каждый раз новое значение переменной t отправляется в массив, а затем эти числа в массиве сортируются?
Черный ворон
129 / 123 / 6
Регистрация: 31.01.2012
Сообщений: 435
10.03.2013, 19:03     Посимвольная обработка текстового файла: распределение всех слов по длине #12
w0nder, нет. изначально я выделяю массив на 25 элементов предполагая, что в тексте не встретится слово больше чем из 25букв. можно увеличить хоть до ста. это не так принципиально. потом перед чтением файла инициализирую нулями количество слов с различным количеством букв. потом читаю по символам файл, когда встречаю разделить инкрементирую значение ячейки масиива отвечающие за слова только что подсчитанной длины последнего прочтенного слова. не слишком запутано? могу попробовать иначе пояснить...
w0nder
0 / 0 / 0
Регистрация: 23.11.2012
Сообщений: 131
10.03.2013, 19:09  [ТС]     Посимвольная обработка текстового файла: распределение всех слов по длине #13
Черный ворон, ну вот было бы неплохо. Просто не могу никак понять алгоритм до конца
Черный ворон
129 / 123 / 6
Регистрация: 31.01.2012
Сообщений: 435
10.03.2013, 19:22     Посимвольная обработка текстового файла: распределение всех слов по длине #14
w0nder, ну попробую на примере. представим, что у нас файл выглядит так:
C++
1
1 12 12 12 123 1234
теперь запуская программу:
предполагаем, что в файле нет слов длиннее 25 букв
C++
1
int count[25];
считаем, что пока мы не начали читать количество слов с любым количеством букв в нем равно нулю
C++
1
for (int i=0; i<n; i++) count[i]=0;
открываем файл:
C++
1
ifstream input ("D:\\1.txt");
C++
1
2
3
4
5
6
7
8
9
10
11
while (!input.eof()){ //пока не добрались до конца файла
        input.get(c); //считываем из него один символ
        if (!check(c)){ //если это не разделитель
                t++; //то в текущем слове количество букв увеличиваем на единицу и переходим к следующему символу
        }
        else //если символ - разделитель
        {
                count[t-1]++; //то в ячейке массива с индексом t-1(потому что индексация у массива с нуля) увеличиваем значение на 1 
                t=0; //обнуляем количество букв в текущем слове и переходим к следующему символу
        }
}
таким образом в нулевой ячейке массива хранится количество однобуквенных слов
в первой - двухбуквенных
во второй - трех
итд.

для случая тестового файла результат будет
1
3
1
1

так понятнее?
w0nder
0 / 0 / 0
Регистрация: 23.11.2012
Сообщений: 131
10.03.2013, 19:29  [ТС]     Посимвольная обработка текстового файла: распределение всех слов по длине #15
Черный ворон, вот теперь все понятно, спасибо большое
w0nder
0 / 0 / 0
Регистрация: 23.11.2012
Сообщений: 131
12.03.2013, 01:14  [ТС]     Посимвольная обработка текстового файла: распределение всех слов по длине #16
Кстати, протестировала получше, заметила вот что. Ведь числа же по идее не должны считаться за символ? Если речь идет именно о количестве букв в словах.
Как можно в коде сделать так, чтобы цифры не считались?
Черный ворон
129 / 123 / 6
Регистрация: 31.01.2012
Сообщений: 435
12.03.2013, 01:23     Посимвольная обработка текстового файла: распределение всех слов по длине #17
w0nder, в смысле вообще не учитывать цифры? или считать их разделителем?
если первый вариант, то цикл while изменить так:
C++
1
2
3
4
5
6
7
8
9
10
11
12
while (!input.eof()){
        input.get(c);
        if (!isdigit(c)) //если текущий символ цифра - просто переходим к следующему символу сразу
        if (!check(c)){
                t++;
        }
        else
        {
                count[t-1]++;
                t=0;
        }
}
если считать разделителем, то цикл не менять, а функцию check изменить так:
C++
1
2
3
4
5
6
7
8
9
10
bool check(char c){
if (c==' ') return true;
if (c=='.') return true;
if (c==',') return true;
if (c=='!') return true;
if (c=='(') return true;
if (c==')') return true;
if (isdigit(c)) return true;
return false;
}
кстати сейчас протестировал. похоже разницы нет. в данном случае оба варианта изменения кода дают одинаковый результат
w0nder
0 / 0 / 0
Регистрация: 23.11.2012
Сообщений: 131
12.03.2013, 01:33  [ТС]     Посимвольная обработка текстового файла: распределение всех слов по длине #18
Черный ворон, да, первый вариант, спасибо

Добавлено через 3 минуты
Вот только если вводится комбинация из букв и цифр (ww1) , то в результате выходит, что в этом слове на один символ меньше, чем есть на самом деле

Добавлено через 4 минуты
Хотя если в такой цепочке символов будут сначала цифры, а потом буквы - то считает правильно
Черный ворон
129 / 123 / 6
Регистрация: 31.01.2012
Сообщений: 435
12.03.2013, 01:34     Посимвольная обработка текстового файла: распределение всех слов по длине #19
w0nder, странно. у меня все адекватно работает.еще раз прикладываю полный код и результат:
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
33
34
35
36
37
38
39
40
#include <fstream.h>
#include <iostream.h>
bool check(char c){
if (c==' ') return true;
if (c=='.') return true;
if (c==',') return true;
if (c=='!') return true;
if (c=='(') return true;
if (c==')') return true;
//if (isdigit(c)) return true;
return false;
}
 
int main(){
int count[25]; //Г¬Г*ГЄГ±ГЁГ¬Г*ëüГ*Г*Гї äëèГ*Г* ñëîâГ* 25 ñèìâîëîâ. ìîæГ*Г® ГЁ óâåëè÷èòü...
int n=25;
char c;
int t=0;
for (int i=0; i<n; i++) count[i]=0;
ifstream input ("D:\\1.txt");
while (!input.eof()){
        input.get(c);
        cout<<c;
        if (!isdigit(c))
        if (!check(c)){
                t++;
        }
        else
        {
                count[t-1]++;
                t=0;
        }
}
cout<<endl;
count[t-2]++;
for (int i=0; i<n-1; i++)
cout<<"words with "<<i+1<<" letters: "<<count[i]<<endl;
system ("pause");
return 0;
}
Миниатюры
Посимвольная обработка текстового файла: распределение всех слов по длине  
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
12.03.2013, 01:37     Посимвольная обработка текстового файла: распределение всех слов по длине
Еще ссылки по теме:

C++ С текстового файла прочитать строку слов
Сортировка слов текстового файла путём слияния данных из файла и заданного внутреннего массива C++
C++ Обработка информации из текстового файла
Чтение текста из текстового фала, обработка слов и вывод в консоль C++
Обработка текстового файла C++

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

Или воспользуйтесь поиском по форуму:
w0nder
0 / 0 / 0
Регистрация: 23.11.2012
Сообщений: 131
12.03.2013, 01:37  [ТС]     Посимвольная обработка текстового файла: распределение всех слов по длине #20
Я просто еще немного переделала (вчитаталась в задание - нужно было, чтобы результат выводился не в консоли, а во втором файле) и добавила строчку if (count[i]>0) , может в этом дело

Код:

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
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
#include <fstream>
#include <iostream>
using namespace std;
 
bool check(char c){
    if (c==' ') return true;
    if (c==',') return true;
    if (c=='!') return true;
    if (c=='?') return true;
    if (c=='(') return true;
    if (c==')') return true;
    if (c=='\n') return true;
return false; }
 
int main(){
int ok;
do {
int count[40]; 
int n=40;
char c; 
int t=0; 
 
for (int i=0; i<n; i++) count[i]=0; 
fstream fin ("1.txt", ios::in);
fstream fout ("2.txt", ios::out);
 
    while (!fin.eof()) {
        fin.get(c);
        if (!isdigit(c)) 
        if (!check(c)){ 
            t++;  
        }
 
        else {  
            count[t-1]++; 
                                                 
            t=0; 
        }
    }
        count[t-2]++; 
 
for (int i=0; i < n-1; i++) 
    if (count[i]>0) 
    fout << "words with "<< i+1 << " letter(s): " << count[i]<<endl;
 
fin.close ();
fout.close ();
 
cout << " Vai turpinДЃt (1) vai beigt (0)?" << endl;
cin >> ok;
}
while (ok == 1);
return 0; }
Yandex
Объявления
12.03.2013, 01:37     Посимвольная обработка текстового файла: распределение всех слов по длине
Ответ Создать тему
Опции темы

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