Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Для новичков > Подсчёт кол-во слов в тексте.


Автор: MoxHaToe 20.5.2009, 14:55
Может быть есть у кого нибудь готовый пример?

Написать программу, которая читает текст и печатает его с добавлением последовательных номеров строк, при этом программа должна собирать все слова текста, сохраняя номера строк, в которых они встречались. Когда просмотр закончен, нужно построить таблицу, содержащую все собранные слова со списком соответствующих строк и количеством вхождения этого слова в текст в порядке возрастания количества вхождений. Для представления слов, встречающихся в тексте можно использовать бинарное дерево, каждый узел которого содержит слово в качестве значения ключа и начало списка номеров строк.

Автор: bsa 20.5.2009, 15:13
MoxHaToe, что именно не получается или вызывает затруднения?

Автор: MoxHaToe 20.5.2009, 15:28
Один из вариантов решения не получается, как перехватить ввод enter при вводе строки string. Чтобы посчитать кол-во строк?

Автор: bsa 20.5.2009, 15:31
Э... а зачем его перехватывать? Ты при вводе можешь получать только строки (нужно изрядно повозиться, чтобы перехватывать каждый вводимый символ). Т.е. ты даешь команду fgets(buffer, buf_size, stdin); И  в buffer будет вся строка, которую ввел пользователь.

Автор: MoxHaToe 20.5.2009, 15:34
В цикле можно сделать условие на нажатие enter? то есть действие на нажатие клавиши о переносе строки?

Автор: zim22 20.5.2009, 16:42
Цитата(MoxHaToe @  20.5.2009,  15:34 Найти цитируемый пост)
В цикле можно сделать условие на нажатие enter?

getline из <string> по умолчанию реагирует на Enter и std::cin из <iostream>

Автор: bsa 20.5.2009, 20:35
MoxHaToe, нужно сильно поизвращаться, чтобы получать символы из стандартного ввода до того, как пользователь нажал на ввод. Короче, строка в программу поступает только после нажатия на ввод.

Автор: MoxHaToe 24.5.2009, 19:09
Код

#include "stdafx.h"
#include <iostream>
#include <vector>
#include <map>
#include <string>
#include <windows.h> 
#include <algorithm>
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{SetConsoleOutputCP(1251);
SetConsoleCP(1251);
cout<<"Вводите текст:"<<endl; 
string s;
int l=1;char* z;
cout<<l;
cout<<' ';
vector<string> vec; /*объявление переменной из контейнера вектор (типа список)*/
vector<char*> vec2;
do {
cin >> s; /*ввод текста через пробел*/
if((s!=".")&&(s!="exit")) {cout<<"";vec.push_back(s);/*добавление в конец*/
vec2.push_back(z);} else {l++;cout<<l;cout<<' ';}
z=(char*)l;
}while(s!="exit");
}

Как здесь правильно написать, чтобы в vec2 заносился номер строки?

Автор: zim22 24.5.2009, 19:19
Цитата(MoxHaToe @  24.5.2009,  19:09 Найти цитируемый пост)
Как здесь правильно написать, чтобы в vec2 заносился номер строки?

может быть так?
Код

#include <iostream>
#include <vector>
#include <map>
#include <string>
#include <windows.h> 
#include <algorithm>
using namespace std;int main(){SetConsoleOutputCP(1251);SetConsoleCP(1251);cout<<"Вводите текст:"
<<endl;string s;int l=1;char*z;cout<<l;cout<<' ';vector<string>vec;/*объявление переменной из 
контейнера вектор (типа список)*/vector<int>vec2;int line_number=0;do{line_number++;cin
>>s;/*ввод текста через пробел*/if((s!=".")&&(s!="exit")){cout<<""
;vec.push_back(s);/*добавление в конец*/vec2.push_back(line_number);}else 
{l++;cout<<l;cout<<' ';}z=(char*)l;}while(s!="exit");}

p.s. не обращайте внимание на форматирование кода - мне так удобней было.

Автор: MoxHaToe 24.5.2009, 19:46
Мне просто в дальнейшем как то надо запомнить, число повторений слов и номера строк, в которых они встречаются, как это сделать. Вот такой у меня вопрос.

Добавлено через 1 минуту и 21 секунду
Думал на счёт того, чтобы создать вектор char и добавлять к нему соответствующие номера строк при поиске одинаковых слов.

Добавлено через 9 минут и 31 секунду
Код

#include "stdafx.h"
#include <iostream>
#include <vector>
#include <map>
#include <string>
#include <windows.h> 
#include <algorithm>
using namespace std;

int _tmain(int argc, _TCHAR* argv[])
{SetConsoleOutputCP(1251);
SetConsoleCP(1251);
cout<<"Вводите текст:"<<endl; 
string s;
int l=1,z;
cout<<l;
cout<<' ';
vector<string> vec; /*объявленпе переменной из контейнера вектор (типа список)*/
vector<int> vec2;
do {
cin >> s; /*ввод текста через пробел*/
if((s!=".")&&(s!="exit")) {cout<<"";vec.push_back(s);/*добавление в конец*/
vec2.push_back(z);} else {l++;}
z=l;
}while(s!="exit");
cout<<"Частота с какой встречаются слова"<<endl;
vector<int> v; /*еще одна переменная типа вектор*/
vector<char*> v2;
for(size_t i = 0;i<vec.size();++i) /*счетчик, а size-размер введенного текста */
{
int count = 0;
char* q;
vector<string>::iterator it = find(vec.begin(),vec.end(),vec[i]);
for(vector<string>::iterator iter = vec.begin(); iter != vec.end();++iter) /*циклик для сравнивания нового итератора со старым*/
{
    if(*iter == *it) /*и если они равны, то счетчик от слова плюсуется*/
    {++count;
    }
}
v.push_back(count); /*и это количество записывается в перменную v*/
v2.push_back(q);
}

map<string,int> m_map; /*ассоциативный массик. стринг - ключ, инт - значение*/

for(size_t i = 0;i<vec.size();++i) 
m_map[vec[i]] = v[i]; /*и вот мы собсно туда и записываем все предыдущее, слова и их встречаемость*/

for(map<string,int>::iterator iter = m_map.begin();iter != m_map.end();++iter) /*вывод на печать))*/
{
cout<<iter->first<<' '<<iter->second<<endl;
}
return 0;
}

На данный момент, работает только число потворений (взят пример). 

Автор: zim22 24.5.2009, 20:19
Цитата(MoxHaToe @  24.5.2009,  19:46 Найти цитируемый пост)
Мне просто в дальнейшем как то надо запомнить, число повторений слов и номера строк, в которых они встречаются, как это сделать

сохраняйте слова в map.
ключом будет слово, значением - число его повторений в тексте.
первоначально значение = 0, в дальнейшем инкрементируется на 1.

задача состоит из подзадач. реализуя их вы реализуете задачу.
Цитата(MoxHaToe @  20.5.2009,  14:55 Найти цитируемый пост)
 программу, которая читает текст

Цитата(MoxHaToe @  20.5.2009,  14:55 Найти цитируемый пост)
 печатает его с добавлением последовательных номеров строк

Цитата(MoxHaToe @  20.5.2009,  14:55 Найти цитируемый пост)
программа должна собирать все слова текста, сохраняя номера строк, в которых они встречались

Цитата(MoxHaToe @  20.5.2009,  14:55 Найти цитируемый пост)
построить таблицу


Автор: MoxHaToe 24.5.2009, 20:27
*Реализация для вводимого текста также возможна.

Автор: zim22 25.5.2009, 07:44
Цитата

число повторений слов и номера строк, в которых они встречаются

каждому слову будет соответствовать свой set, в котором будут номер строк указаны, в которых оно встречается. число повторений есть размер set'a
Код

std::map<std::string, std::set<int> > numbers_of_line;


Автор: sdukshis 25.5.2009, 21:04
Вот примерная идея.
Код
#include <iostream>
#include <sstream>
#include <map>
#include <list>
#include <string>
#include <vector>
#include <algorithm>

using namespace std;

struct WordCount{        // Для хранения слова и количества его вхождений в текст
    string word;
    size_t count;

    WordCount(string _word , size_t _count =0):word(_word),count(_count){};
};

struct WordGreat{        //Функтор для сортировки по количеству вхождений
    bool operator()(const WordCount& lhs, const WordCount& rhs){
        return lhs.count > rhs.count;
    }
};

int main(int argc, char *argv[]){
    
    map<string, list<int> > Words;    // Для хранения слов и номеров строк
    int line_num = 1;
    string str,word;

    while(!getline(cin,str).eof()){ // Считываем очередную строку в str
        stringstream sstr(str);        // Создаем stringstream на основе этой строки
        while(!sstr.eof()){            
            sstr >> word;            // Считываем по одному слову
            Words[word].push_back(line_num); // Добавляем слово и номер строки (с дублировнием)
        }
        cout << line_num++ << " " << str << endl;
    }

    cout << endl;

    
    vector<WordCount> v;        

    map<string, list<int> >::iterator mi;
    
    for(mi=Words.begin(); mi!= Words.end(); ++mi){    // Создаем vector на основе map
        v.push_back(WordCount(mi->first,mi->second.size()));
        mi->second.unique();                // Удаляем повторяюшиеся номера строк
    }

    sort(v.begin(),v.end(),WordGreat());   // Сортируем

    vector<WordCount>::iterator vi;
    list<int>::iterator li;

    for(vi = v.begin(); vi != v.end(); ++vi){
        cout << vi->word << " total count: " << vi->count << " lines: "; // Выводим слово и количество его вхождений
            list<int>& tmp_list = Words[vi->word];
            for(li = tmp_list.begin(); li !=tmp_list.end(); ++li){  // Выводим номера строк где оно встретилось
                cout << *li << " ";
            }
        cout << endl;
    }

    return 0;
}



Автор: MoxHaToe 26.5.2009, 14:45
О спасибо, разобрался. Делал попытку через массив сделать, но понял, что всё гораздо сильно усложняется.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)