Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > Общие вопросы C/C++
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 18.02.2012, 15:41   #1
LordAlex91
Новичок
Джуниор
 
Регистрация: 18.02.2012
Сообщений: 4
По умолчанию Построение бинарного дерева

Здравствуйте! Не знаю где искать помощи, решил обратиться сюда, надеюсь поможете =)

Мне препод в универе дал задание, звучит оно примерно так: "Имеется текстовый файл с текстом из книги Война и Мир. Нужно построить бинарное дерево из слов входящих в этот файл. Добавление элемента в дерево зависит от количества вхождений данного слова в файл."

Надеюсь суть понятна.
Я почти сделал эту программу. Сначала сделал бинарное дерево чтобы подсчитать кол-во вхождений каждого слова и отсортировать его с помощью strcmp. Но потом, когда делаю второе дерево из элементов первого дерева то у меня возникает переполнение стека. Сделал ограничение до 5000 и все работает, но там в дереве еще остаются более 20000 слов. Бинарное дерево я строю рекурсивными функциями.

Расскажу саму программу.

Bunch - класс одного элемента дерева. Он содержит ссылки на левый и правый элемент такого же класса (дети элемента).

Bunch.value - кол-во вхождений слова в текст
Bunch.name[40] - само слово

Цитата:
//Bunch.h

namespace AreaBunch{

class Bunch{
public:
int value;
char name[30];
Bunch* left_child;
Bunch* right_child;

Bunch();
};

};
Цитата:
//Bunch.cpp

#include "Bunch.h"

namespace AreaBunch{

Bunch :: Bunch(){
left_child = 0;
right_child = 0;
value = 0;
};

};
Собственно это всё, что я вынес в отдельные файлы. Теперь расскажу про исходник с функцией main()
Я создам новое сообщение ниже с кодом этой функцией, не получается сюда
LordAlex91 вне форума Ответить с цитированием
Старый 18.02.2012, 15:43   #2
LordAlex91
Новичок
Джуниор
 
Регистрация: 18.02.2012
Сообщений: 4
По умолчанию

Вот сам код этой функции. Почему то отступы удалились =(
Цитата:
#include "Bunch.h"

#include <conio.h>
#include <iostream>
#include <fstream>
#include <string>

using AreaBunch :: Bunch;

void MakeTree(Bunch* root, char* inName)
{
if ((root) && (root -> value) == 0) {
for (int i = 0; i < strlen(inName); i++)
root -> name[i] = inName[i];
root -> name[strlen(inName)] = '\0';
root -> value = 1;
} else
if (strcmp(root -> name, inName) == 0){ //совпадение
root -> value = root -> value + 1;
}
else
if (strcmp(root -> name, inName) == 1) //name > inName
{
if (!root -> left_child)
root -> left_child = new Bunch;

MakeTree(root -> left_child, inName);
}
else
if (strcmp(root -> name, inName) == -1) //name < inName
{
if (!root -> right_child)
root -> right_child = new Bunch;

MakeTree(root -> right_child, inName);
};
};

void MakeTree2(int& value, char* name, Bunch* new_root){
if ((new_root) && (new_root -> value == 0))
{
new_root -> value = value;
for (int i = 0; i < strlen(name); i++)
new_root -> name[i] = name[i];
new_root -> name[strlen(name)] = '\0';
}
else
if (value < new_root -> value)
{
if (!new_root -> left_child)
new_root -> left_child = new Bunch;
MakeTree2(value, name, new_root -> left_child);
} else
if (value >= new_root -> value) {
if (!new_root -> right_child)
new_root -> right_child = new Bunch;
MakeTree2(value, name, new_root -> right_child);
};
};

void CreateTree2(Bunch* new_root){
int read_value;
char read_name[30];

FILE* new_output = fopen("output2.txt", "w+");
FILE* input = fopen("output.txt", "r");
int counter = 0;

while (!feof(input))
{
if (counter > 5000) break;
fscanf(input,"%s %d", &read_name, &read_value);
std :: cout << counter++ << std :: endl;
MakeTree2(read_value, read_name, new_root);
};

fclose(input);
fclose(new_output);

};

void PrintTree(Bunch* root, FILE* f_pointer){
if (root){
PrintTree(root -> left_child,f_pointer);
fprintf(f_pointer, "%s %d\n", root -> name, root -> value);
PrintTree(root -> right_child,f_pointer);
};

};

int main()
{
Bunch* root = new Bunch;
root -> value = 5;
root -> name[0] = 'в';
root -> name[1] = 'ы';
root -> name[2] = '\0';
//Создали корень дерева

int counter = 0;

FILE* output = fopen("output.txt","w+");
FILE* file_p = fopen("Book_rus.txt","r");
if ((file_p == NULL) || (output == NULL))
{
std :: cout << "Can't open file" << std :: endl;
getch();
return 1;
};

char fword[30];
char fgword[30];
char sym;
int fgword_index;
while (!feof(file_p)){
fscanf(file_p, "%s", &fword);
fgword_index = 0;
for (int i = 0; i < strlen(fword); i++) //фильтруем слово на плохие символы
{
sym = tolower(fword[i]);
if ((fword[i] != '!') && (fword[i] != '?') && (fword[i] != ')') && (fword[i] != '(') && (fword[i] != '\'') && (fword[i] != '"') && (fword[i] != '.') && (fword[i] != ',') && (fword[i] != '“') && (fword[i] != ';') && (fword[i] != '„') && (fword[i] != '-') && (fword[i] != '=') && (fword[i] != '/') && (fword[i] != '[') && (fword[i] != '«') && (fword[i] != '»') && (fword[i] != '…')){
fgword[fgword_index] = sym;
fgword_index++;
};

if ((sym == -105) || ((sym > 47) && (sym < 58)) || (sym == 'x') || ((sym > 96) && (sym < 123)) || (((sym > -65) && (sym < -32)))) {
fgword_index = 0;
break;
};
};

fgword[fgword_index] = '\0';

if (strlen(fgword) > 1)
MakeTree(root, fgword);
};

fclose(file_p);

PrintTree(root,output);

fclose(output);

Bunch* root2 = new Bunch;
CreateTree2(root2);

FILE* output2 = fopen("output2.txt", "w+");
PrintTree(root2, output2);

fclose(output2);

getch();

return 0;
};
LordAlex91 вне форума Ответить с цитированием
Старый 18.02.2012, 15:49   #3
LordAlex91
Новичок
Джуниор
 
Регистрация: 18.02.2012
Сообщений: 4
По умолчанию

Функция MakeTree(Bunch* root, char* inName) - она добавляет (или увеливает счетчик вхождений если слово уже было в дереве) элемент в дерево у которого корень является root.

Я не знаю как пробежаться по первому дерево и параллельно добавлять элементы во второе дерево. Я сделал проще, первое дерево вывел в файл и написал функцию CreateTree2(Bunch* new_root). Она читает каждое слово и вызывает функцию MakeTree2(int& value, char* name, Bunch* new_root) которая считывает каждое слово из файла и добавляет его во второе дерево (с корнем root2) элементы.
Но вот тут как раз проблема, после 5000го слова у меня возникает переполнение стека, и я не знаю что делать


Прикрепил вывод деревьев в файлы

Output.txt - это вывод первого дерева
Output2.txt - это второе неполное дерево

http://ifolder.ru/28784966 - это сама книжка
Вложения
Тип файла: txt output.txt (359.3 Кб, 157 просмотров)
Тип файла: txt output2.txt (59.1 Кб, 120 просмотров)

Последний раз редактировалось LordAlex91; 18.02.2012 в 15:55.
LordAlex91 вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Высота бинарного дерева dido171 Помощь студентам 4 02.12.2014 13:30
Конструктор дерева (не бинарного) murzilka6002 Общие вопросы C/C++ 3 12.11.2011 23:25
построение бинарного дерева по инфиксной записи Екатерина Семенова Помощь студентам 1 23.05.2011 20:45
Высота бинарного дерева m9yt Общие вопросы C/C++ 5 13.03.2010 22:17