[C/C++] Составить частотный словарь вводимого текста. Распечатать его по алфавиту.
Решать его требуется без структур и (очень желательно) без классов...
До сих пор не могу ничего придумать по поводу поиска одинаковых слов и самое проблематичное : упорядочивание по алфавиту... все буквы латинские.
И в чем проблема сравнивать латинскии буквы? strcmp есть например.
qwerty 3
qaz 1
qwerty 2
qwerty 1
Я думаю задание с алфивитом можно не рассматривать как обязательное, а вот подсчёт слов было бы очень желательно сделать.
Хотя, я бы не отказался от решения даже со связанными списками, лишь бы оно работало и всё было понятно откуда берётся.
P.S. Так все-таки, какой язык предлагается для решения задачи? Уже миллион раз указывалось, что С и С++ - суть разные вещи.
Ага... А ведь strtok, strcmp - это для С-style string. И как быть?
А чем не нравится вариант с массивом? Имхо, самое простое и очевидное решение - создать массив слов и отсортировать его по алфавиту. А затем пройтись по отсортированному массиву, подсчитать частоту каждого слова и выдать результаты на экран. Все! И никаких там связных списков, структур и классов, столь ненавистных автору :)
А разве в С++ запрещено использовать С-style стрки?
Возможно :) А как предлагаешь организывать массив, если заранее кол-во слов неизвестно.
Ну, можно сначала посчитать слова, а потом создать массив. А можно просто ограничить количество слов каким-нибудь числом. Например, длиной строки. Ведь количество слов никак не может быть больше, чем количество символов в строке.
А если еще учесть, что слова должны быть разделены как минимум одним пробелом, то получится, что количество слов в строке s не может превышать 1+strlen(s)/2.
Имеется ввиду STL(список).
[LEFT]Такие задачи,как раз,надо делать с STL.Классический пример по созданию словаря из книги Стенли Липпмана.Язык программирования С++.Используется vector и map.C.Липпман решает похожую задачу: считывает текстовый файл,в котором находится книга Кэррола "Алиса в стране Чудес" и составляет словарь автора,т.е. определяет сколько он использует слов,сколько встречаются в тексте те или инные слова. Задача,кстати,не такая уж и простая.Правда,Липпман делает это очень изящно,он убирает пробелы, знаки препинания,союзы,приводит слова к стандарной форме (без падежей).К чему я это говорю - он использует, почему,то STL ? Почему ? Вот и подумай кому будет лучше решать без них ? Точно не тебе,как программисту.Какой язык вы учите ? С++ ? Зачем тогда С-style ? У тебя задача похожа на ту,что решает Липпман, только он пользуется как программист преимуществами С++,а ты ограничен достаточно жесткими рамками.Т.е мало того,что квалификация Липпмана несоизмерима с твоей(он один мировых авторитетов в С++,а ты студент),так тебе еще навязываны эти рамки. На С++ с STL решение твоей задачи будет строк 10( !!!),если хочешь могу набросать,минут за 15 а на С...имхо:не самая простая задача(это ж словарь,значит дубли надо поудалять,отсортировать,т.е ф-ию написать и т.д.) - 1.5 часа думаю...
P.S.Такие ограничения - зло,поскольку не дают возможность студентам использовать С++.Студенты думают,что учат С++,а на самом деле учат С с классами,как говорит Б.Страуструп.Считаю,что любая задача должна решаться наиболее простыми и современными способами,а не сложными и устаревшиими.[/LEFT]
Задача нужна почти в любом варианте и срочно!
Я не хочу губить одной нерешённой задачей всю курсовую и экзамен...
Защитить то я её скорее всего смогу, но написать никак не выходит.
#include <iostream>
#include <vector>
#include <map>
#include <string>
#include <algorithm>
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
wcout.imbue(locale(".866"));
wcout<<L"Вводите текст"<<endl;
string s;
vector<string> vec;
while(cin >> s)
vec.push_back(s);
wcout<<L"Частота с какой встречаются слова"<<endl;
vector<int> v;
for(size_t i = 0;i<vec.size();++i){
int count = 0;
vector<string>::iterator it = find(vec.begin(),vec.end(),vec);
for(vector<string>::iterator iter = vec.begin();
iter != vec.end();++iter){
if(*iter == *it) ++count;
}
v.push_back(count);
}
map<string,int> m_map;
for(size_t i = 0;i<vec.size();++i)
m_map[vec] = v;
for(map<string,int>::iterator iter = m_map.begin();iter !=
m_map.end();++iter){
cout<<iter->first<<' '<<iter->second<<endl;
}
return 0;
}
Для прекращения ввода-нажать в новой строке Ctrl+Z.
[LEFT]Такие задачи,как раз,надо делать с STL.Классический пример по созданию словаря из книги Стенли
Липпмана.Язык программирования С++.Используется vector и map.C.Липпман
решает похожую задачу:считывает текстовый файл,в котором находится книга Кэррола "Алиса в
стране Чудес" и составляет словарь автора,т.е. определяет сколько он использует слов,сколько
встречаются в тексте те или инные слова.Задача,кстати,не такая уж и простая.Правда,Липпман
делает это очень изящно,он убирает пробелы,знаки препинания,союзы,приводит слова к стандарной
форме(без падежей).К чему я это говорю - он использует,почему,то STL ? Почему ? Вот и подумай
кому будет лучше решать без них ? Точно не тебе,как программисту.Какой язык вы учите ?
С++ ? Зачем тогда С-style ? У тебя задача похожа на ту,что решает Липпман,только он пользуется как программист
преимуществами С++,а ты ограничен достаточно жесткими рамками.Т.е мало того,что квалификация
Липпмана несоизмерима с твоей(он один мировых авторитетов в С++,а ты студент),так тебе еще навязываны
эти рамки.На С++ с STL решение твоей задачи будет строк 10( !!!),если хочешь могу набросать,
минут за 15 а на С...имхо:не самая простая задача(это ж словарь,значит дубли надо поудалять,
отсортировать,т.е ф-ию написать и т.д.) - 1.5 часа думаю...
P.S.Такие ограничения - зло,поскольку не дают возможность студентам использовать С++.Студенты
думают,что учат С++,а на самом деле учат С с классами,как говорит Б.Страуструп.Считаю,что любая
задача должна решаться наиболее простыми и современными способами,а не сложными и устаревшиими.[/LEFT]
Вот этот пост, если из него убрать лишние эмоции;), можно вывесить в прилепленные темы данного раздела, имхо. Чтобы студент, изучающий С++, сам понял, что это такое на самом деле. И не стеснялся распечатать эти слова и показать их косному преподавателю.
Скромное замечание по существу поста.
Единственно, могу сказать что эта книга по уровню и глубине охвата STL - далеко не самая мощная (субъективно, но многие думаю, согласятся). Но, по понятности и доступности объяснений она очень хороша, и m_Valery совершенно правильно советует ее. Я присоединяюсь.
...
Скромное замечание по существу поста.
Единственно, могу сказать что эта книга по уровню и глубине охвата STL - далеко не самая мощная (субъективно, но многие думаю, согласятся). Но, по понятности и доступности объяснений она очень хороша, и m_Valery совершенно правильно советует ее. Я присоединяюсь.
Да,разумеется, это не Николай Джосьютис "Стандартная библиотека для профессионалов";)
Книга Липпмана и не претендует на статус книги по STL.
Содержание книги Липпмана соответсвует своему собственному названию "Язык программирования С++.Вводный курс". У нее есть преимущества,наверно,есть и недостатки.Мне нравится,что Липпман обходится без С-style,никаких массивов,С-строк,макросов и т.д.Ту же задачу по составлению словаря он решает с map. Хотя бы потому,что тот же Алекс Степанов(помним,что он - создатель STL) в своей книге "Стандартная библиотека шаблонов С++"
упорно называет мар не отображением,а cловарем!!! Если это словарь,то о каких массивах стоит, вообще, говорить в этой задаче ? :D Книга Липпмана описывает С++,в соответствии со
стандартом.(соавтором при написании была Жози Лажойе,одна из разработчиц стандарта)
Из студенческих учебников,думаю,книга Липпмана одна из лучших.Попались,как то ,мне в руки методические указания для студентов-программистов.Предмет называется просто,но со вкусом-"С++".30 уроков,после 15 - зачет по С(,причем тут С! до С++ еще не добрались),далее 2 урока - структуры(это то же С),7 уроков-классы, остальные работа с файлами в С и работа с файлами в С++.Все.Из 30 уроков по С++ - 10(мало).Зато далее по MFC - 60 уроков(не много ли?)
Почитал,мое мнение-отрава.Безцеремонно содрано с Дейтела, фактически из С++ только классы(изложены очень поверхностно).Про STL - ни слова.Понять по этой методичке,например,полиморфизм, наследование практически нереально.
Читая эту методичку,мне вспомнились слова Страуструпа:"Знание С не является обязательным для изучения С++...Чем лучше вы знаете С,тем труднее вам будет избежать программирования на С++ в стиле С,теряя при этом потенциальные преимущества С++."И далее там же:"
из Рекомендаций для программистов на С
...[3] Не используйте malloc(),оператор new делает то же самое,только лучше.Вместо realloc() пользуйтесь vector.
...[5]Сведите к минимуму использования массивов символов и строк С.Стандартные библиотеки классов С++ string u vector упрощают программирование по сравнению с традиционным стилем С."
Не следует так же забывать то,что STL разрабатывался лучшими экспертами С++и игнорировать их труд,что бы облегчить свой собственный по-моему не разумно.
P.S.Может,действително,стоит завести отдельную тему.Вопрос о соотношении С и С++,о негласном запрете STL и других ограничениях постоянно возникает при решении студенческих задач.
Что это за явление,почему возникло и чем обернется ? Там и обсудим.ИМХО:это интересно.
Но, к сожалению, требовалось создать класс "Частотный словарь" используя массивы. Другие задания были создать классы список, стек и т.д. и реализовать действия с ними...
Как объяснить преподователю, бессмысленность изобретания велосипеда? ,)
У меня похожая задача. необходимо создать частотный словарь категоризировать слова в текстАХ, то есть существует несколько типов текстов. поэтому нужно вести неск частот (допустим три типа текстов) для каждого слова - частота вхождения в первый тип текста, частота вхождения слова во второй и частота вхождения в третий тип текста.
Как с пом STL более рационально вести словарь?
2 ALL
К сожалению, плохо знаком с STL и был бы признателен, если б вы объяснили как с пом данной библиотеки обновлять статистику частот, то есть сравнивать каждое слово с уже имеющимся в словаре и увеличивать частоту при совпадении.
istream_iterator<string> ifile1(in1);
istream_iterator<string> eos1;
vector<string> coll1;
copy(ifile1,eos1,inserter(coll1,coll1.begin()));...
После этого каждый вектор содержит слова из соответсвующего файла.Далее используем множество set и сливаем содержимое каждого вектора в него.В set получим только уникальные слова,без повторов.Теперь надо подсчитать сколько раз каждое слово содержиться в том или ином файле и занести куда то результаты. Я использовал вектор векторов,для этого обьявил typedef vector< vector<int> > T; и создал такой 2мерный вектор так
T mass(collection.size(), vector<int>(3));
...
где collection.size() - кол-во строк этого вектора,т.е длина set или количество уникальных слов,количество столбцов 3,т.е это количество файлов.Все элементы этого вектора равны нулю изначально.Нужно определить сколько раз встречается каждое слово из множества в каждом из файлов.Сделать это можно так для одного файла,пришлось повторить этот кусок кода трижды для каждого из файлови заполнить 2мерный вектор по столбцам.
size_t k = 0;
for(set<string>::iterator it = collection.begin();it != collection.end();++it){
int count1 = 0;
set<string>::iterator it1 = find(collection.begin(),collection.end(),*it);
for(vector<string>::iterator iter = coll1.begin();
iter != coll1.end();++iter)
if(*iter == *it1){
++count1;
mass[k][0] = count1;
}
++k;
}
k = 0;...
После этого мы имеем 2мерный вектор,количество строк которого равно - количеству уникальных слов,а кол-во столбцов -это количество файлов.Вектор векторов содержит нужные нам частоты.Практически все готово.Осталось только заполнить сам словарь, т.е контейнер STL map.Однако,есть один ньюанс.Этот словарь должен в качестве ключа содержать слово,а в качестве значения - вектор.Как это сделать ? Очень просто.Для этого обьявляем typedef vector<int> frequency; - это частота...И все.Вот теперь создадим словарь.map<string,frequency> freqDictionary;Осталось только его заполнить
size_t i = 0;
for(set<string>::iterator it = collection.begin();
it != collection.end();++it){
freqDictionary.insert(map<string,frequency>::value_type(string(*it),
frequency(mass)));
++i;
}...
и потом распечатать результат.Это первое,что пришло в голову...В принципе готовый код могу дать,но попытайся сделать сам,очень полезно.
Поговорил с руководителем по диплому, убедил его в нерациональности поставленной задачи. тк эта задача может быть отдельной темой для диплома - категоризация настроения отправителя сообщений:eek: (мой диплом состоит из неск модулей. вообщем - сбор стат информации сервера, фильтрация и тд).
сошлись на сборе стат информации по типу слов в сообщении - спам и неспам.
т е необх вести частотный словарь вида:
уникальное слово частота встречаемости в спаме частота встречаемости в неспаме
пришел 1й текстовый файл (к примеру, "Купи слона"), кот мы прочти и пометили спамом. создали частотн словарь:
слово спам неспам
купи 1 0
2е сообщение - "Купи кафель от Степана"
слово спам неспам
купи 2 0
кафель 1 0
от 1 0
Степана 1 0
3е сообщение "Привет от Степана" - не спам.
слово спам неспам
купи 2 0
кафель 1 0
от 1 1
Степана 1 1
Привет 0 1
и тд и тп
диплом весь готов. кроме этого модуля:(
m_Valery, как более рационально и быстрее сделать? с помощью ф-ций STL или с пом стандартных ф-ций С\С++? каких? (с С++ познакомился только неск месяцев назад:() буду очень благодарен за консультацию эксперта.
PS: прошу прощения за отдельно созданную тему. не разобрался с форумом.
диплом весь готов. кроме этого модуля:(
m_Valery, как более рационально и быстрее сделать? с помощью ф-ций STL или с пом стандартных ф-ций С\С++? каких? (с С++ познакомился только неск месяцев назад:() буду очень благодарен за консультацию эксперта.
...
Разумеется рациональнее и быстрее сделать при помощи STL, конечно, если есть знания STL,если нет...Я тебе ж даже написал как делать примерно.Там весь код в 30 строк...Без STL будет достаточно сложно сделать.Бери книгу по STL,разберись что такое контейнеры,какие бывают,для чего предназначены,что такое итераторы и что такое алгоритмы. http://anatolix.naumen.ru/Books/CPPSTL?v=dbl - тут книга,одна из лучших по STL,Николая Джосюттиса.На ее освоение потребуется время...сколько ? неизвестно... :rolleyes: Вопрос о том можно ли и нужно ли в твоей задаче использовать STL тебе надо решать с преподом.Я так понимаю,что диплом должен делаться на базе тех знаний и того материала,который вы изучали.Если делать без STL,опять же нужны знания по С.Надо считывать файлы,записывать их содержимое куда-то(в динамический массив),разбивать на слова,удалять дубликаты...Потом сам частотный словарь наверное должен сохраняться в каком то файле и при каждом запуске программы считываться,если есть новое сообщение надо вставлять из него слова в словарь и записывать в файл обновленный словарь ?
У меня схожая проблема, только вот текст:
"Import SAM and SYSTEM Registry Files" –
the importing of user data from SAM registry file. If the imported SAM file is additionally encrypted by SYSKEY (enabled by default in Windows 2000/XP/2003/Vista), the program will also need the SYSTEM Windows registry file, located at the same Windows directory, where SAM file was – %SystemRoot%\System32\Config. Copies of these files may be also found in the %SystemRoot%\Repair and %SystemRoot%\Repair\RegBack folders. (Note: %SystemRoot% is the system folder of Windows OS; commonly C:\WINDOWS or C:\WINNT).
немного усложнённый.
Но самое интересное то, что пытаяся отделить слова от всяких знаков, пробелов и переносов с помощью
пропускаю пробелы. Почему?
Вот наконецто нашел время отписаться)) написал прогу, защитил диплом)
БОЛЬШОЕ СПАСИБО за книгу. очень помогла.
ск понадобилось времени на изучение STL? полдня:cool: естественно на изучение ТОЛЬКО необходимого материала)))
ск понадобилось времени на изучение STL? полдня:cool: естественно на изучение ТОЛЬКО необходимого материала)))
Оффтоп:
Не торопись:) И не говори никому. ;) Я когда это прочел вспомнил слова Скотта Маейрса,он любит иногда посетовать на то,что он не достаточно хорошо знает С++,что не до конца понимает STL,то,говорит, в шаблонах слабоват...:D