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

Программа для анализа русских/английских текстов - C++

Восстановить пароль Регистрация
 
Whiteha
Программист
33 / 33 / 4
Регистрация: 08.07.2011
Сообщений: 190
Записей в блоге: 1
16.03.2012, 04:19     Программа для анализа русских/английских текстов #1
Уфф, в общем я студент-самоучка, пытаюсь охватить побольше теории, но с практикой дело у меня идёт не очень активно.
Тк мой код никто кроме препода с первого курса больше не видел(сейчас на втором), я иногда сомневаюсь в том что пишу как "все нормальные люди", а не так как не надо.
Если есть время - прошу покритиковать мою программку; цель - поиск нелепостей и несуразностей в логике, стиле и всём чём только можно, хочу услышать критику которая поможет стать лучше.
P.S. Я лишь смутно догадываюсь о возможных недостатках, но увидеть их сейчас не в состояние.

Программа для анализа, русских/английских текстов(функциональный стиль выбран намеренно).
Создаёт текстовый файл, который содержит отсортированный в порядке убывания по повторяемости список слов, с указанием процента повторяемости.

Возможности:
- подключаемый список слов-исключений(перечислять через пробел или перенос строки), указывающий на необходимость игнорировать данные слова при анализе.
- анализ слов указанной длины

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

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
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
// FrequencyOfWords.cpp : Defines the entry point for the console application.
//
#include <windows.h>
#include <process.h>
#include <algorithm>
#include <iostream>
#include <iomanip>
#include <fstream>
#include <conio.h>
#include <string>
#include <deque>
#include <set>
#include <map>
 
namespace FOW
{
    using namespace std;
 
    // ========================================== //
    // Список используемых переменных и объектов  //
    // ========================================== //
 
    string bad_simbols       = "$?\"\\“”‚„«»‹›\
           §…&%#!{}[],.:;?*№()<>/*+=0123456789";     // Символы, которые не должны содержаться в слове
 
    string delim(59, '-');                           // Строка-разделитель
    string file_in            =         "in.txt";    // Имя анализируемого файла по умолчанию
    string file_of_exceptions = "exceptions.txt";    // Имя файла со списком слов-исключений
    string file_out           =        "out.txt";    // Имя результирующего файла по умолчанию
 
    size_t words_counter(0);                         // Всего слов в тексте(счётчик)
    int min_word_size = 3;                           // Минимальный размер слова по умолчанию
    set<string> exc;                                 // Список слов-исключений (в нижнем регистре)
    map<string, double> words;                       // Список анализируемых слов (в нижнем регистре), слово - ключ к числу повторений
 
    volatile bool ThreadFlag = true;                 // Флаг для управления потоком progress, при false поток завершается
    streamoff all_f_size(1);                         // Размер файла
    streamoff current_f_size(1);                     // На данный момент прочитано из файла
 
    // ========================================== //
    //            Функциональная часть            //
    // ========================================== //
 
    unsigned _stdcall progress(void*)
    {
        setlocale(LC_ALL, "");
        cout << "Прогресс:\n " << flush;
        cout.precision(4);
 
        while(ThreadFlag)
        {
            cout << "        " << '\r' << flush; // Очищаем пред. вывод
            cout << (((100 / (long double)all_f_size) * current_f_size)) << "%" << flush << '\r';
            if (ThreadFlag) Sleep(100);
        }
 
        // Гарантирует отображение "100%", при малых размерах файла и быстрой работе
        cout << "        " << '\r' << flush;
        cout << 100 << "%\r" << flush;
 
        // Возвращаем переменные в исходное состояние для возможного перезапуска программы
        all_f_size     = (1);
        current_f_size = (1);
 
        return 0;
    }
 
    void read_exceptions(string& exc_file)
    {
 
        ifstream file(exc_file);
        if (!file)
        {
            cout << "\nФайл с исключениями не загружен." << endl;
            return;
        }
 
        string buf;
        while (file >> buf)
        {
            for_each(buf.begin(), buf.end(), [] (char& ch) {ch = tolower(ch);});
            exc.insert(buf);
        }
 
        cout << "\nПрочитано исключений: " << exc.size() << endl;
        file.close();
    }
 
    int  read_text_file(string& inp_file, bool mode = true)
    {
        ifstream file(inp_file, ios::binary);
        if (!file)
        {
            cout << "\nФайл с текстом для анализа не загружен." << endl;
            return 1;
        }
 
        // Узнаём размер файла
        file.seekg (0, std::ios_base::end);
        all_f_size = file.tellg();
        file.seekg (0, std::ios_base::beg);
 
        string buf;
        while(file >> buf)
        {
            current_f_size = file.tellg();
 
            for_each(buf.begin(), buf.end(), [] (char& it) {it = tolower(it);});
 
            // Удаление паразитных знаков из кандитата на слово
            for (string::size_type pos = buf.find_first_of(bad_simbols); pos != string::npos;)
            {
                buf.erase(pos);
                pos = buf.find_first_of(bad_simbols);
            }
            // Если слово начинается с "'" или "—" или "-" - обрабатываем эту ситуацию
            if ((buf.begin() != buf.end()) && ((*buf.begin() == '\'') || (*buf.begin() == '—') || (*buf.begin() == '-'))) buf.erase(buf.begin());
            // То же самое, если оканчивается на "'" или "—" или "-"
            if ((buf.begin() != buf.end()) && ((*(--buf.end()) == '\'') || (*(--buf.end()) == '—') || (*(--buf.end()) == '-'))) buf.erase((--buf.end()));
 
            // Конец удаления паразитных знаков
 
            if (mode)
            {
                // Если слово не найдено в списке исключений и длиннее min_word_size
                if (!exc.count(buf) && (buf.size() >= (unsigned)min_word_size))
                {
                    if (words.count(buf)) ++words[buf];
                    words.insert(make_pair(buf, 1));
                    ++words_counter;
                }
            }
            else
            {
                // Если слово не найдено в списке исключений и равно длине min_word_size
                if (!exc.count(buf) && (buf.size() == (unsigned)min_word_size))
                {
                    if (words.count(buf)) ++words[buf];
                    words.insert(make_pair(buf, 1));
                    ++words_counter;
                }
            }
        }
        file.close();
        return 0;
    }
 
    void write_results(string& outp_file)
    {
        ofstream file(outp_file);
 
        // Подготавливаем для вывода, высчитываем для каждого слова процент его употребления в тексте
        for (map<string, double>::iterator it = words.begin(); it != words.end(); ++it)
        {
            it->second = it->second / (double)words_counter * 100;
        }
 
        // Собираем очередь и сортируем в порядке убывания процента повторения
        deque<pair<double, string>> buf;
        for (map<string, double>::iterator i = words.begin(); i != words.end(); ++i)
        {
            buf.insert(buf.begin(), make_pair(i->second, i->first));
        }
        sort(buf.rbegin(), buf.rend());
 
        // Сохраняем
        size_t count(0);
        //long double temp_buf = 0;
        for_each(buf.begin(), buf.end(), [/*&temp_buf, */&file, &count] (pair<double, string> it) 
        {
            //temp_buf += it.first;
            file  << '['<< ++count << "] " << std::setw(25) << std::left << it.second << std::right << it.first << '%' << endl;
        });
        count = 0;
        //cout << "sum = " << temp_buf << endl;
        file.close();
 
    }
 
    void input_name()
    {
        bool fl = false;
        do
        {
            if (fl) cout << "\nИмя анализируемого файла некорректно, повторите ввод:" << ends;
            else cout << "\nИмя анализируемого файла:" << ends;
            cin >> file_in;
            fl = true;
        }
        while (!ifstream(file_in));
    }
    
    int _main()
    {
        system("cls");
        cout << " Программа анализирует частоту употребления слов в тексте." << endl << delim << endl;
        bool mode = true;
 
        bool inp_err(false);
        do
        {
            if (inp_err) cout << "n должно быть > 0" << ends;
            cout << "\nСчитать словом буквенную последовательность от n символов, где n =" << ends;
            cin >> min_word_size;
            inp_err = true;
        }
        while (min_word_size < 1);
        inp_err = (false);
 
        char ch;
        do
        {
            if (inp_err) cout << "\n(y/n)!" << ends;
            cout << "\nИскать слова точно равные по длине " << min_word_size << "(y), или все равные и больше(n)? " << ends;
            ch = tolower(_getche());
            inp_err = true;
        }
        while (ch != 'y' && ch != 'n');
        inp_err = (false);
        (ch == 'n')? mode = true: mode = false;
 
        do
        {
            if (inp_err) cout << " - (Выбор - y/n!)" << ends;
            cout << "\nЗадать имена используемых файлов вручную?(y/n)" << ends;
            ch = tolower(_getche());
            inp_err = true;
        }
        while (ch != 'y' && ch != 'n');
        inp_err = (false);
 
        if (ch == 'y')
        {
            input_name();
            cout << "Имя файла содержащего слова-исключения:" << ends; cin >> file_of_exceptions;
            cout << "Имя файла для вывода:" << ends; cin >> file_out;
        }
 
        read_exceptions(file_of_exceptions);
 
        HANDLE hThread = (HANDLE)_beginthreadex(NULL, NULL, progress, NULL, NULL, NULL);
 
        read_text_file(file_in, mode);
 
        write_results(file_out);
 
        ThreadFlag = false;
        WaitForSingleObject(hThread, 120); // Даём время потоку завершиться
 
        cout << "\nНайдено слов: " << words_counter << endl;
 
        ch = 'e';
        do
        {
            if (inp_err) cout << " - (Выбор - y/n!)" << ends;
            cout << "\nРасчёт завершён, проанализировать новый файл?(y/n)" << ends;
            ch = tolower(_getche());
            inp_err = true;
        }
        while (ch != 'y' && ch != 'n');
        inp_err = (false);
 
        int ret(0); // Возвращаемое значение
 
        if (ch == 'y') ret = true;
        else cout << "\n\n" << delim << endl;
 
        // Сбрасываем всё что рассчитывали, для возможного перезапуска с новыми данными
        ThreadFlag = true;
        words_counter = 0;
        exc.clear();
        words.clear();
 
        return ret;
    }
}
 
int main()
{
    setlocale(LC_ALL, "");
    while (FOW::_main());
    system("pause");
    return 0;
}
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
16.03.2012, 04:19     Программа для анализа русских/английских текстов
Посмотрите здесь:

вывод в документ. китайские иероглифа вместо русских или английских букв C++
Подсчитать во сколько раз русских букв больше чем английских C++
Программа анализа текста C++
C++ Текстовый файл. Открыть, посчитать в нем количество английских и русских букв
Программа анализа графика отпусков C++
Программа анализа характеристик чисел личности C++
Написать программу-кодировщик английских текстов C++
C++ Программа для вывода русских букв

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

Или воспользуйтесь поиском по форуму:
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
ValeryS
Модератор
6375 / 4841 / 443
Регистрация: 14.02.2011
Сообщений: 16,044
16.03.2012, 05:22     Программа для анализа русских/английских текстов #2
Цитата Сообщение от Whiteha Посмотреть сообщение
Находя самые употребляемые слова в том или ином тексте и изучая их в первую очередь, мы облегчаем задачу понимания сути написанного.
не факт
важно выучить грамматику тогда выхватывая в предложении подлежащее/сказуемое можешь понять о чем речь даже не зная половины слов
По теме
если хочешь писать документированные программы то надо описавать функции так
что делает функция
что возвращает
какие аргументы
пример
C++
1
2
3
4
5
6
7
8
9
//-----------------------------------------------------------------------
    // Summary:
    //     Call this method to check if CommandBar exists in the list
    // Parameters:
    //      pCommandBar - CommandBar to test
    // Returns:
    //      TRUE if CommandBar exists in the list
    //-----------------------------------------------------------------------
    BOOL Lookup(CXTPCommandBar* pCommandBar) const;
Yandex
Объявления
16.03.2012, 05:22     Программа для анализа русских/английских текстов
Ответ Создать тему
Опции темы

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