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

Программа анализа текста - C++

Восстановить пароль Регистрация
 
Рейтинг: Рейтинг темы: голосов - 9, средняя оценка - 4.78
8VAid8
12 / 12 / 2
Регистрация: 21.04.2012
Сообщений: 190
29.05.2012, 16:14     Программа анализа текста #1
Имеется код.
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
#include <iostream>
#include <string>
#include <map>
#include <fstream>
 
using namespace std;
 
int main()
{
 
map <string,int> words;
ifstream in;
in.open("in.txt");
string word;
while (in>>word)
words[word]++;
ofstream out;
out.open("out.txt");
int count=0;
map <string,int>::iterator cur;
out<<"Words count:"<<endl;
for (cur=words.begin();cur!=words.end();cur++)
{out<<(*cur).first<<": "<<(*cur).second<<endl;count+=(*cur).second;}
out<<"Words percenc:"<<endl;
 
for (cur=words.begin();cur!=words.end();cur++)
out<<(*cur).first<<": "<<(float)((float)(*cur).second/(float)count)*100<<"%"<<endl;
 
return 0;
}
Нужно отсеять вывод так, чтобы в файле out находились только 20 наиболее встречающихся слов и колличество их использования.
С массивом мап не имел дела, так что прошу помощи!

Добавлено через 1 час 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
using System;
using System.Linq;
using System.Text;
using System.IO;
 
class Program
{
    static void Main(string[] args)
    {
        char[] delimiters = Enumerable.Range(0, 127)
            .Select(Convert.ToChar)
            .Where(c => Char.IsWhiteSpace(c) || Char.IsPunctuation(c))
            .ToArray();
        string[] words = File.ReadAllText("E:\\matrix.txt", Encoding.Default)
            .Split(delimiters, StringSplitOptions.RemoveEmptyEntries);
        var pop = (from word in words
                                   let count = words.Count(w => w == word)
                                   orderby count descending
                                   select new { Word = word, Count = count })
                                   .Distinct().Take(20);
        foreach (var i in pop)
            Console.WriteLine("{0}: {1}", i.Word, i.Count);
    }
}
Но как его преобразовать?!...
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Deviaphan
Делаю внезапно и красиво
Эксперт C++
 Аватар для Deviaphan
1283 / 1217 / 50
Регистрация: 22.03.2011
Сообщений: 3,744
29.05.2012, 16:19     Программа анализа текста #2
Цитата Сообщение от 8VAid8 Посмотреть сообщение
С массивом мап не имел дела
Раза с двадцатого только понял, о чём ты вообще говоришь. map это не массив.

Одно из решений:
1 скопируй все данные из map в vector
2 сортируй вектор по убыванию, сравнивая int
3 выведи в файл первые 20 пар.
8VAid8
12 / 12 / 2
Регистрация: 21.04.2012
Сообщений: 190
29.05.2012, 16:30  [ТС]     Программа анализа текста #3
Deviaphan, Здесь его называют ассоциативным массивом -> http://adorning.ru/2010/01/18/s-urok...ivnyiy-massiv/
Deviaphan
Делаю внезапно и красиво
Эксперт C++
 Аватар для Deviaphan
1283 / 1217 / 50
Регистрация: 22.03.2011
Сообщений: 3,744
29.05.2012, 16:40     Программа анализа текста #4
Цитата Сообщение от 8VAid8 Посмотреть сообщение
ассоциативным массивом
И правильно делают. Но просто массивом называть низя.
8VAid8
12 / 12 / 2
Регистрация: 21.04.2012
Сообщений: 190
29.05.2012, 16:43  [ТС]     Программа анализа текста #5
Понял.Больше не буду=)
8VAid8
12 / 12 / 2
Регистрация: 21.04.2012
Сообщений: 190
29.05.2012, 17:13  [ТС]     Программа анализа текста #6
Сделал, как и планировалось, но код не работает.Ничего не выводит.
C++
1
2
3
4
5
6
7
8
9
10
vector<int> s;
while (in>>word)
s.push_back(words[word]); 
sort(s.end(), s.begin()); 
vector<int>::iterator at, ini, end; 
ini = s.begin(); 
end = s.end(); 
ofstream lo("out2.txt");
for(at=ini; at<20;at++) 
lo<<*at<<endl;
Вероятно это от криворукости.Где ошибка?
Deviaphan
Делаю внезапно и красиво
Эксперт C++
 Аватар для Deviaphan
1283 / 1217 / 50
Регистрация: 22.03.2011
Сообщений: 3,744
29.05.2012, 17:17     Программа анализа текста #7
А давай ты попробуешь написать код, который компилируется?
Или подумай хотя бы о том, как пишешь. Сейчас у тебя ошибки начиная со строки 3 и почти во всех последующих строках.
8VAid8
12 / 12 / 2
Регистрация: 21.04.2012
Сообщений: 190
29.05.2012, 17:29  [ТС]     Программа анализа текста #8
это я end неудачно заменил на 20...

Добавлено через 8 минут
А как в вектор положить одновременно и слово(string) и число его повторений(int)?
Deviaphan
Делаю внезапно и красиво
Эксперт C++
 Аватар для Deviaphan
1283 / 1217 / 50
Регистрация: 22.03.2011
Сообщений: 3,744
29.05.2012, 17:34     Программа анализа текста #9
Слово "пара" я написал не случайно. Берёшь из map значение типа value_type. Это пара std:air<string, int>. Вот эти пары значений в вектор положить и надо. И написать функцию сравнения, чтобы по int сравнивать.
8VAid8
12 / 12 / 2
Регистрация: 21.04.2012
Сообщений: 190
29.05.2012, 20:01  [ТС]     Программа анализа текста #10
Цитата Сообщение от Deviaphan Посмотреть сообщение
Слово "пара" я написал не случайно. Берёшь из map значение типа value_type. Это пара std:air<string, int>. Вот эти пары значений в вектор положить и надо. И написать функцию сравнения, чтобы по int сравнивать.
Это оказалось слишком сложно.Составил новый код:
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
// ff.cpp: îïðåäåëÿåò òî÷êó âõîäГ* äëÿ ГЄГ®Г*ñîëüГ*îãî ïðèëîæåГ*ГЁГї.
//
 
#include<iostream>
#include<algorithm>
#include<vector>
#include<string>
#include <fstream>
using namespace std;
 
struct rec{string s;int n;};
vector<rec> v;
vector<rec>::iterator vi;
 
 bool find(string s){for(vi=v.begin();vi!=v.end();vi++) if(vi->s==s) return true; return false; }
 bool foo ( rec elem1, rec elem2 ){   return elem1.n > elem2.n;}
int main()
{   setlocale(LC_ALL, "Russian");
    string buf;
    string s;
    ifstream in("in.txt");
    while(!in.eof())
    {getline(in,buf);
    s=s+buf;
    }
    //cout<<s<<endl;
    //**********************************
    string d="";
    for(int i=0;i<s.length();i++){
        if(s[i]==' '){
            if(find(d)){
                vi->n++;
            } else {
                rec r; r.n=1; r.s=d;
                v.push_back(r);
            };  d=""; 
        } else {d+=s[i];}
    }
    sort(v.begin(),v.end(),foo);
    for(vi=v.begin();vi!=v.end();vi++)
    cout<<vi->s<<'\t'<<vi->n<<'\n';
    getchar();
 
system( "" );    
    return 0;
}
Но как сделать, чтобы выводилось только 20 пар:слово-кол-во повторений?
Deviaphan
Делаю внезапно и красиво
Эксперт C++
 Аватар для Deviaphan
1283 / 1217 / 50
Регистрация: 22.03.2011
Сообщений: 3,744
29.05.2012, 20:08     Программа анализа текста #11
В строке 40, вместо итераторов используй индекс и выведи только 20 значений. Ты же уже самую сложную часть написал.)
zvoronz
 Аватар для zvoronz
270 / 237 / 21
Регистрация: 29.05.2012
Сообщений: 889
29.05.2012, 20:32     Программа анализа текста #12
Ну добавь вот что то типа такого
C++
1
2
3
4
5
6
7
    int n = 0;
    for(vi=v.begin();vi!=v.end();vi++)
    {
         cout<<vi->s<<'\t'<<vi->n<<'\n';
         if(++n == 20) break;
    }
    getchar();
8VAid8
12 / 12 / 2
Регистрация: 21.04.2012
Сообщений: 190
29.05.2012, 20:54  [ТС]     Программа анализа текста #13
Уже по своему сделал. Разложил в 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
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
// ff.cpp: îïðåäåëÿåò òî÷êó âõîäГ* äëÿ ГЄГ®Г*ñîëüГ*îãî ïðèëîæåГ*ГЁГї.
//
 
#include<iostream>
#include<algorithm>
#include<vector>
#include<string>
#include <fstream>
using namespace std;
 
struct rec{string s;int n;};
vector<rec> v;
vector<rec>::iterator vi;
 
 bool find(string s){for(vi=v.begin();vi!=v.end();vi++) if(vi->s==s) return true; return false; }
 bool foo ( rec elem1, rec elem2 ){   return elem1.n > elem2.n;}
int main()
{   setlocale(LC_ALL, "Russian");
    string buf;
    string s;
    ifstream in("in.txt");
    while(!in.eof())
    {getline(in,buf);
    s=s+buf;
    }
    //cout<<s<<endl;
    //**********************************
    string d="";
    for(int i=0;i<s.length();i++){
        if(s[i]==' '){
            if(find(d)){
                vi->n++;
            } else {
                rec r; r.n=1; r.s=d;
                v.push_back(r);
            };  d=""; 
        } else {d+=s[i];}
    }
    //****************************
    string mas[1000];
    int mas2[1000];int i=0;
    //******************************
    sort(v.begin(),v.end(),foo);
    for(vi=v.begin();vi!=v.end();vi++)
    {mas[i]=vi->s;mas2[i]=vi->n;i++;}
    for(int j=0;j<20;j++)
    cout<<mas[j]<<" "<<mas2[j]<<endl;
    //cout<<vi->s<<'\t'<<vi->n<<'\n';
    getchar();
 
system("pause");    
    return 0;
}
Добавлено через 4 минуты
Но вариант zvoronz'a больше нравится и красивее выводит.

Добавлено через 5 минут
Но не сортирует....
talis
 Аватар для talis
789 / 541 / 37
Регистрация: 11.05.2010
Сообщений: 1,298
Записей в блоге: 1
29.05.2012, 21:05     Программа анализа текста #14
Под катом работающая прога. Кому интересно решить самому - не смотрите

Работающее решение
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
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <algorithm>
#include <iterator>
 
/*
 * представляет пару "слово - количество"
 */
struct word_t
{
    std::string word; // слово
    size_t count;     // количество
 
    // к-р по-умолч.
    word_t() :
        word(),
        count()
    {
    }
 
    // к-р копирования
    word_t( const word_t &other ) :
        word( other.word ),
        count( other.count )
    {
    }
 
    // к-р из строки и числа
    // по-умолчанию считается, что слово встречается 1 раз
    word_t( const std::string &str, const size_t &count = 1 ) :
        word( str ),
        count( count )
    {
    }
 
    // для std::find
    bool operator==( const std::string &other ) const
    {
        return word == other;
    }
 
    // для std::sort
    bool operator<( const word_t &other ) const
    {
        return count < other.count;
    }
};
 
/*
 *  для вывода
 */
std::ostream & operator<<( std::ostream &os, const word_t &word )
{
    return os << word.word << ": " << word.count;
}
 
 
int main( )
{
    std::ofstream fout( "out.txt" );
 
    if( !fout.good() )
    {
        perror( "out.txt" );
        return 1;
    }
 
    std::ifstream fin( "in.txt" );
 
    if( !fin.good() )
    {
        perror( "in.txt" );
        return 1;
    }
 
    // список слов
    typedef std::vector<word_t> words_count_t;
    words_count_t words_count;
 
    // обходим каждое слово в потоке
    std::for_each( std::istream_iterator<std::string> ( fin ),
                   std::istream_iterator<std::string> (),
                   [&]( const std::string &str )
                   {
                       std::string word; // слово без знаков препинания
 
                       // копируем слово по буквам без знаков препинания
                       std::copy(
                              // ищем первую букву с начала слова
                              std::find_if( str.begin(), str.end(), []( const char &ch ){ return isalpha( ch ); } ),
 
                              // ищем первую букву с конца слова
                              std::find_if( str.rbegin(), str.rend(), []( const char &ch ){ return isalpha( ch ); } ).base(),
 
                              // всё, что между ними, копируем во временный объект
                              std::back_inserter( word )
                            );
 
                       // если в нём есть хотя бы один символ
                       if( word.length() )
                       {
                           // ищем такое слово в списке слов
                           words_count_t::iterator it = std::find( words_count.begin(), words_count.end(), word );
 
                           // если не найдено
                           if( words_count.end() == it )
                               words_count.push_back( word_t( word ) );  // загоняем его туда
                           else
                               it->count++; // иначе увеличиваем количество встречаний
                       }
                   }
                  );
 
    // сортируем элементы по возрастанию количества встречаний
    std::sort( words_count.rbegin(), words_count.rend() );
 
    // выводим поэлементно
    {
        size_t i = 20;
 
        for( words_count_t::const_iterator it = words_count.begin();
            i && it != words_count.end();
            i--, it++ )
                fout << *it << '\n';
    }
 
    return 0;
}
in.txt:
Let me take you far away
You'd like a holiday
Let me take you far away
You'd like a holiday

Exchange the cold days for the sun
A good time and fun
Let me take you far away
You'd like a holiday

Let me take you far away
You'd like a holiday
Let me take you far away
You'd like a holiday

Exchange your troubles for some love
Wherever you are
Let me take you far away
You'd like a holiday

Longing for the sun you will come
To the island without name
Longing for the sun be welcome
On the island many miles away from home
Be welcome on the island without name
Longing for the sun you will come
To the island many miles away from home
out.txt:
you: 9
the: 9
away: 8
Let: 6
me: 6
take: 6
far: 6
You'd: 6
like: 6
a: 6
holiday: 6
for: 5
sun: 4
island: 4
Longing: 3
come: 2
To: 2
without: 2
name: 2
welcome: 2
8VAid8
12 / 12 / 2
Регистрация: 21.04.2012
Сообщений: 190
29.05.2012, 21:32  [ТС]     Программа анализа текста #15
talis, Настроил свой вариант. Стал более ли менее нормально работать.
Пытаюсь твой запустить-вылетает ошибка компилятора:
\ðàáî.cpp In function `int main()':
85ðàáî.cpp expected primary-expression before '[' token
85 \ðàáî.cpp expected primary-expression before ']' token
85 ðàáî.cpp expected primary-expression before "const"

Каким компилятором пользуешься?
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
29.05.2012, 21:37     Программа анализа текста
Еще ссылки по теме:

Программа анализа графика отпусков C++
Бинарное дерево для анализа текста C++
Программа анализа характеристик чисел личности C++

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

Или воспользуйтесь поиском по форуму:
talis
 Аватар для talis
789 / 541 / 37
Регистрация: 11.05.2010
Сообщений: 1,298
Записей в блоге: 1
29.05.2012, 21:37     Программа анализа текста #16
gcc 4.6. нужен компилятор с поддержкой C++11. у вас он споткнулся о лямбду.
Yandex
Объявления
29.05.2012, 21:37     Программа анализа текста
Ответ Создать тему
Опции темы

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