Форум программистов, компьютерный форум, киберфорум
C++ Builder
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.56/27: Рейтинг темы: голосов - 27, средняя оценка - 4.56
1 / 1 / 0
Регистрация: 06.03.2013
Сообщений: 21

Построение семантической сети - программа для поиска ассоциаций заданному слову в тексте

23.09.2013, 21:17. Показов 5775. Ответов 5
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
В институте задали задачку:
Алгоритм работы семантической сети в режиме обучения
1. Ввести некий текст, содержащий не менее 500 слов.
2. Из текста извлечь все слова и поместить в сеть.
3. Ассоциативным весам сети присвоить значения = 0
4. Запустить текст на обработку весов.
5. Вес между стоящими в тексте рядом словами увеличить на N
6. Вес между стоящими в тексте через одно словами увеличить на N/2

В рабочем режиме программа обработки по введенному слову выдает список ассоциаций, причем первыми в списке выводятся слова с наибольшими весами ассоциаций.

На первый взгляд задача простая. Алгоритм работы понятен. Заносим текст в массив, каждый указатель которого указывает на 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
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
void __fastcall TForm1::Button1Click(TObject *Sender)
{
int word_weight=2;
TStringList *words=new TStringList;
words->Text=StringReplace(Memo2->Text," ","\n",TReplaceFlags()<<rfReplaceAll);
 
int word_count=words->Count;
 
AnsiString **mass=new AnsiString*[word_count];
 for (int i = 0;  i< word_count; i++) {mass[i] = new AnsiString[word_weight]; }
 
AnsiString *mass_2=new AnsiString[word_count];
 
 for (int i = 0; i < word_count; i++) {mass_2[i]=words->Strings[i]; }
 Memo1->Clear();
 
for (int i = 0; i < word_count; i++)
{
    if (mass_2[i]==Edit1->Text) {
    if (i==0) {
    Memo1->Lines->Add(mass_2[i]);
    Memo1->Lines->Add(mass_2[i+1]);
    Memo1->Lines->Add(mass_2[i+2]);goto ezz;}
    if (i==1) {
    Memo1->Lines->Add(mass_2[i-1]);
    Memo1->Lines->Add(mass_2[i]);
    Memo1->Lines->Add(mass_2[i+1]);
    Memo1->Lines->Add(mass_2[i+2]); goto ezz;}
    if (i==word_count-1) {
    Memo1->Lines->Add(mass_2[i-2]);
    Memo1->Lines->Add(mass_2[i-1]);
    Memo1->Lines->Add(mass_2[i]); goto ezz;}
    if (i==word_count-2) {
    Memo1->Lines->Add(mass_2[i-2]);
    Memo1->Lines->Add(mass_2[i-1]);
    Memo1->Lines->Add(mass_2[i]);
    Memo1->Lines->Add( mass_2[i+1]); goto ezz;}
    if (2<i<word_count-2) {
    Memo1->Lines->Add(mass_2[i-2]);
    Memo1->Lines->Add(mass_2[i-1]);
    Memo1->Lines->Add(mass_2[i]);
    Memo1->Lines->Add(mass_2[i+1]);
    Memo1->Lines->Add(mass_2[i+2]);  }
 
}  ezz:
}
 
 int new_memo=Memo1->Lines->Count;
 words->Text=StringReplace(Memo1->Text,"","",TReplaceFlags()<<rfReplaceAll);
for (int i = 0; i < new_memo; i++) {
mass[i][0]=words->Strings[i]; mass[i][1]="0";}
 
for (int i = 0; i < new_memo ; i++) {
if (mass[i][0]==Edit1->Text) {
     if (i==0) {
     mass[i+1][1]=IntToStr(mass[i+1][1].ToInt()+2);
     mass[i+2][1]=IntToStr(mass[i+2][1].ToInt()+1); goto ezz2; }
     if (i==1) {
     mass[i-1][1]=IntToStr(mass[i-1][1].ToInt()+2);
     mass[i+1][1]=IntToStr(mass[i+1][1].ToInt()+2);
     mass[i+2][1]=IntToStr(mass[i+2][1].ToInt()+1); goto ezz2; }
     if (i==new_memo-1) {
     mass[i-2][1]=IntToStr(mass[i-2][1].ToInt()+1);
     mass[i-1][1]=IntToStr(mass[i-1][1].ToInt()+2); goto ezz2;}
     if (i==new_memo-2) {
     mass[i-2][1]=IntToStr(mass[i-2][1].ToInt()+1);
     mass[i-1][1]=IntToStr(mass[i-1][1].ToInt()+2);
     mass[i+1][1]=IntToStr(mass[i+1][1].ToInt()+2); goto ezz2;}
     if (2<i<new_memo-2) {
     mass[i+1][1]=IntToStr(mass[i+1][1].ToInt()+2);
     mass[i+2][1]=IntToStr(mass[i+2][1].ToInt()+1);
     mass[i-2][1]=IntToStr(mass[i-2][1].ToInt()+1);
     mass[i-1][1]=IntToStr(mass[i+1][1].ToInt()+2);  }
 
}ezz2:}
 
for (int i = 0; i < new_memo; i++) {
 for (int i1 =i+1; i1 < new_memo; i1++) {
 if (mass[i1][0]=="e") {  goto rest;}
     if (mass[i][0]==mass[i1][0]) { mass[i][1]=IntToStr(mass[i][1].ToInt()+mass[i1][1].ToInt());
       mass[i1][0]="e";  }
 rest:
 }
 StringGrid1->RowCount=new_memo;
}
 
for (int i = 0; i < new_memo; i++) {
 for (int i1 =i+1; i1 < new_memo; i1++) {
  if (mass[i1][1]>mass[i][1]) {
  AnsiString sort_mass[1][2]; sort_mass[0][0]=mass[i1][0]; sort_mass[0][1]=mass[i1][1];
  mass[i1][0]=mass[i][0]; mass[i1][1]=mass[i][1];
  mass[i][0]=sort_mass[0][0]; mass[i][1]=sort_mass[0][1];
   delete sort_mass;
  }
 
 }}
 
        int cou=0;
for (int i = 0; i < new_memo; i++) {
  if (mass[i][0]!="e") {StringGrid1->Cells[0][i-cou]=mass[i][0];
  StringGrid1->Cells[1][i-cou]=mass[i][1];}  else {cou++;}
 
  }
 
 delete mass;
 delete mass_2;
}
0
Лучшие ответы (1)
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
23.09.2013, 21:17
Ответы с готовыми решениями:

Построение семантической сети
Нужна помощь. Мне дали задание для курсовой работы &quot;Построение семантической сети&quot;. Прочитав что это ориентированный граф, я поняла...

Построение семантической сети из текста
Здравствуйте! Имею перед собой задачу автоматической саммаризации текста,т.е. на входе имеем некий текст, а на выходе - его сильно сжатую...

Библиотека для семантической сети
Подскажите, пожалуйста, библиотеку для реализации семантической сети (желательно на C++ или C#).

5
 Аватар для BRcr
4043 / 2333 / 292
Регистрация: 03.02.2011
Сообщений: 5,066
Записей в блоге: 10
23.09.2013, 21:34
Цитата Сообщение от baylrock Посмотреть сообщение
Заносим текст в массив, каждый указатель которого указывает на 1 слово в памяти. Ищем совпадения в массиве с заданным словом, и если находим то определяем "вес" рядом стоящих слов. Выводим полный список этих слов и их вес.
Этим задача исчерпывается? Это и есть "Алгоритм работы семантической сети в режиме обучения"?
0
1 / 1 / 0
Регистрация: 06.03.2013
Сообщений: 21
23.09.2013, 22:56  [ТС]
По сути это и есть задача. Преподаватель точно описал что хочет видеть.)
0
 Аватар для gumi250
435 / 402 / 57
Регистрация: 06.02.2012
Сообщений: 1,384
23.09.2013, 23:48
Одно слово может встретиться в тексте несколько раз, т.е. может иметь любое число ассоциативных соседей (более 2). Поэтому я думаю нужно делать матрицу. По х и по у идут сортированные уникальные слова, а в ячейках пишется коэффициент связи между ними.
0
 Аватар для BRcr
4043 / 2333 / 292
Регистрация: 03.02.2011
Сообщений: 5,066
Записей в блоге: 10
25.09.2013, 21:53
Лучший ответ Сообщение было отмечено SatanaXIII как решение

Решение

Разбирать твой код, честно говоря, желание быстро кончилось.

Поэтому вот реализация, как я ее вижу.
Что имеем: анализатор может поглощать тексты и считать "ассоциации" слов, может все это дело запоминать и выдавать статистику по каждому из слов, парсинг текста можно немножко настраивать сепараторами, массив слов, вытащенных из текста, можно править перед анализом и т.д. На больших текстах не спотыкается.
Что можно добавить, так это мозгов. Например, не считать за ассоциации слова, находящиеся в соседнем предложении, или исключить из анализа предлоги и междометия.

Экзешник в релизе - Project1_exe.rar
Проект - Project1.rar

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
// ---------------------------------------------------------------------------
 
#ifndef Unit1H
#define Unit1H
// ---------------------------------------------------------------------------
#include <System.Classes.hpp>
#include <Vcl.Controls.hpp>
#include <Vcl.StdCtrls.hpp>
#include <Vcl.Forms.hpp>
#include <Vcl.ExtCtrls.hpp>
 
#include <map>
#include <vector>
#include <algorithm>
// ---------------------------------------------------------------------------
typedef std::map < String, int > t_word_relation;
typedef std::map < String, t_word_relation > t_words_assocs;
typedef std::vector < std::pair < String, int > > t_word_stats;
typedef std::auto_ptr < t_word_stats > t_word_stats_auptr;
// ---------------------------------------------------------------------------
class t_semantics
{
private:
    t_words_assocs words;
protected:
 
public:
    std::auto_ptr < TStringList > list;
    TSysCharSet separators;
 
    void __fastcall parse_text( String text )
    {
        text = StringReplace( text, "\"", "", TReplaceFlags( ) << rfReplaceAll );
        text = StringReplace( text, String( ( TCHAR )160 ), "", TReplaceFlags( ) << rfReplaceAll ); // 160 - неразрывный пробел
        list->Clear( );
        ExtractStrings( separators, TSysCharSet( ), text.c_str( ), list.get( ) );
        if ( list->Count < 4 )
        {
            list->Clear( );
            throw String( "too few words in text" );
        }
    }
    void __fastcall analyze( )
    {
        String word, left1, left2, right1, right2;
        int count( list->Count );
 
        words[list->Strings[0]][list->Strings[1]] += 2;
        words[list->Strings[0]][list->Strings[2]] += 1;
        words[list->Strings[1]][list->Strings[0]] += 2;
        words[list->Strings[1]][list->Strings[2]] += 2;
        words[list->Strings[1]][list->Strings[3]] += 1;
        words[list->Strings[count - 1]][list->Strings[count - 2]] += 2;
        words[list->Strings[count - 1]][list->Strings[count - 3]] += 1;
        words[list->Strings[count - 2]][list->Strings[count - 1]] += 2;
        words[list->Strings[count - 2]][list->Strings[count - 3]] += 2;
        words[list->Strings[count - 2]][list->Strings[count - 4]] += 1;
 
        count -= 2;
        for ( size_t i( 2 ); i < count; ++i )
        {
            word = list->Strings[i];
            left1 = list->Strings[i - 1];
            left2 = list->Strings[i - 2];
            right1 = list->Strings[i + 1];
            right2 = list->Strings[i + 2];
 
            words[word][left1] += 2;
            words[word][left2] += 1;
            words[word][right1] += 2;
            words[word][right2] += 1;
        }
    }
    bool word_exists( String & word )
    {
        return ( words.count( word ) == 1 );
    }
    t_word_stats_auptr get_word_stats( String & word )
    {
        t_word_stats_auptr ws( new t_word_stats( words[word].size( ) ) );
        std::copy( words[word].begin( ), words[word].end( ), ws->begin( ) );
 
        return ws;
    }
 
    __fastcall t_semantics( )
    {
        list.reset( new TStringList( ) );
        separators << ' ' << ',' << '.' << ':' << '-' << '!' << '?' << '(' << ')';
    }
    __fastcall ~t_semantics( )
    {
    }
};
// ---------------------------------------------------------------------------
class TForm1
               : public TForm
{
__published: // IDE-managed Components
    TMemo * memo_data;
    TMemo * memo_result;
    TEdit * edit_word;
    TButton * word_stats_btn;
    TButton * analyze_btn;
    void __fastcall analyze_btnClick( TObject * Sender );
    void __fastcall word_stats_btnClick( TObject * Sender );
private: // User declarations
                   public : // User declarations
    t_semantics sems;
 
    __fastcall TForm1( TComponent * Owner );
};
// ---------------------------------------------------------------------------
extern PACKAGE TForm1 * Form1;
// ---------------------------------------------------------------------------
#endif
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
// ---------------------------------------------------------------------------
 
#include <vcl.h>
#pragma hdrstop
 
#include "Unit1.h"
// ---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 * Form1;
// ---------------------------------------------------------------------------
__fastcall TForm1::TForm1( TComponent * Owner )
               : TForm( Owner )
{
 
}
// ---------------------------------------------------------------------------
void __fastcall TForm1::analyze_btnClick( TObject * Sender )
{
    try
    {
        sems.parse_text( memo_data->Text );
        sems.analyze( );
        memo_result->Lines->Add( "анализ успешен" );
    }
    catch ( String s )
    {
        ShowMessage( s );
    }
}
// ---------------------------------------------------------------------------
 
void __fastcall TForm1::word_stats_btnClick( TObject * Sender )
{
    String word( edit_word->Text );
    TStrings * result( memo_result->Lines );
    t_word_stats_auptr ws;
 
    if ( sems.word_exists( word ) )
    {
        ws = sems.get_word_stats( word );
 
        result->Clear( );
        result->Add( "Связи слова \"" + word + "\":" );
 
        for ( t_word_stats::iterator it( ws->begin( ) ), end( ws->end( ) ); it != end; ++it )
        {
            result->Add( it->first + " - " + IntToStr( it->second ) );
        }
    }
}
// ---------------------------------------------------------------------------
Миниатюры
Построение семантической сети - программа для поиска ассоциаций заданному слову в тексте  
3
1 / 1 / 0
Регистрация: 06.03.2013
Сообщений: 21
26.09.2013, 01:47  [ТС]
Спасибо большое. Куча новых примочек для меня открыли)) Буду учить!!!
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
26.09.2013, 01:47
Помогаю со студенческими работами здесь

Нужна программа для поиска слова в тексте. с++
ЛЮди, помогите. Нужно написать программу, которая производит поиск введенного пользователем слова в тексте. Текст берется из файла....

Программа для поиска в тексте номеров телефона
Пожалуйста дорогие и умные программисты, помогите юзверю написать программу на C++: ввести с клавиатуры последовательность символов,...

Программа для поиска слова в тексте и определения строки
Ребята, помогите пожалуйста с задачей Нужно написать программу, которая считывает указанный текстовый файл и заданное пользователем...

Что нужно делать для оптимизации поиска по слову?
Какие именно нужны действия, чтобы на запрос &quot;словотакоето&quot; выпадал нужный сайт (был как можно выше). Может быть статья где-то есть на эту...


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

Или воспользуйтесь поиском по форуму:
6
Ответ Создать тему
Новые блоги и статьи
Оттенки серого
Argus19 18.03.2026
Оттенки серого Нашёл в интернете 3 прекрасных модуля: Модуль класса открытия диалога открытия/ сохранения файла на Win32 API; Модуль класса быстрого перекодирования цветного изображения в оттенки. . .
SDL3 для Desktop (MinGW): Рисуем цветные прямоугольники с помощью рисовальщика SDL3 на Си и C++
8Observer8 17.03.2026
Содержание блога Финальные проекты на Си и на C++: finish-rectangles-sdl3-c. zip finish-rectangles-sdl3-cpp. zip
Символические и жёсткие ссылки в Linux.
algri14 15.03.2026
Существует два типа ссылок — символические и жёсткие. Ссылка в Linux — это запись в каталоге, которая может указывать либо на inode «файла-ИСТОЧНИКА», тогда это будет «жёсткая ссылка» (hard link),. . .
[Owen Logic] Поддержание уровня воды в резервуаре количеством включённых насосов: моделирование и выбор регулятора
ФедосеевПавел 14.03.2026
Поддержание уровня воды в резервуаре количеством включённых насосов: моделирование и выбор регулятора ВВЕДЕНИЕ Выполняя задание на управление насосной группой заполнения резервуара,. . .
делаю науч статью по влиянию грибов на сукцессию
anaschu 13.03.2026
прикрепляю статью
SDL3 для Desktop (MinGW): Создаём пустое окно с нуля для 2D-графики на SDL3, Си и C++
8Observer8 10.03.2026
Содержание блога Финальные проекты на Си и на C++: hello-sdl3-c. zip hello-sdl3-cpp. zip Результат:
Установка CMake и MinGW 13.1 для сборки С и C++ приложений из консоли и из Qt Creator в EXE
8Observer8 10.03.2026
Содержание блога MinGW - это коллекция инструментов для сборки приложений в EXE. CMake - это система сборки приложений. Здесь описаны базовые шаги для старта программирования с помощью CMake и. . .
Как дизайн сайта влияет на конверсию: 7 решений, которые реально повышают заявки
Neotwalker 08.03.2026
Многие до сих пор воспринимают дизайн сайта как “красивую оболочку”. На практике всё иначе: дизайн напрямую влияет на то, оставит человек заявку или уйдёт через несколько секунд. Даже если у вас. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru