![]() |
1. Заголовок темы должен быть информативным. В противном случае тема удаляется ...
2. Все тексты программ должны помещаться в теги [code=pas] ... [/code].
3. Прежде чем задавать вопрос, см. "FAQ", если там не нашли ответа, воспользуйтесь ПОИСКОМ, возможно такую задачу уже решали!
4. Не предлагайте свои решения на других языках, кроме Паскаля (исключение - только с согласия модератора).
5. НЕ используйте форум для личного общения, все что не относится к обсуждению темы - на PM!
6. Одна тема - один вопрос (задача)
7. Проверяйте программы перед тем, как разместить их на форуме!!!
8. Спрашивайте и отвечайте четко и по существу!!!
![]() ![]() |
![]() |
Даша |
![]()
Сообщение
#1
|
Новичок ![]() Группа: Пользователи Сообщений: 20 Пол: Женский Репутация: ![]() ![]() ![]() |
Добрый день! Помогите пожалуйста со следующей задачей:
Дан текстовый файл, состоящий из слов, разделенных пробелами и запятыми. Слова по строкам не переносятся. Необходимо упорядочить слова в алфавитном порядке с указанием строк, в которых они встречаются. Реализовать всё надо с помощью деревьев. |
volvo |
![]()
Сообщение
#2
|
Гость ![]() |
Цитата Добрый день! Помогите пожалуйста со следующей задачей: И Вам день добрый. Обязательно поможем, как только будут выложены Ваши соображения насчет того, как решать эту задачу. Потому что "помочь" и "сделать все за меня" - несколько разные вещи.Что именно пробовали сделать? Что не получилось, в чем именно затруднение? Как вообще осуществляется работа с файлами и/или деревьями - понимаете? Построить дерево (неважно чего, просто построить дерево и обойти его) сможете? |
Даша |
![]()
Сообщение
#3
|
Новичок ![]() Группа: Пользователи Сообщений: 20 Пол: Женский Репутация: ![]() ![]() ![]() |
Затруднение как раз с деревьями. Как в данной задаче использовать дерево? Для чего? Прошу хотя бы это объяснить. Построить дерево особых затруднений думаю не вызовет, а вот с обходом проблемы.
|
TarasBer |
![]()
Сообщение
#4
|
![]() Злостный любитель ![]() ![]() ![]() ![]() ![]() Группа: Пользователи Сообщений: 1 755 Пол: Мужской Репутация: ![]() ![]() ![]() |
Ну в данном случае может помочь дерево, у которого каждый узел имеет 256 потомков (по количеству вариантов, которые может принимать символ).
http://ru.wikipedia.org/wiki/Префиксное_дерево Например, для набора слов "стол, стул, табуретка", дерево будет иметь вид Код .-с-т-о-л | `-у-л `-т-а-б-у-р-е-т-к-а Добавление слова в такое дерево делается очень просто,
обход (рекурсивный) тоже очень просто.
-------------------- |
volvo |
![]()
Сообщение
#5
|
Гость ![]() |
Не нужно здесь префиксное дерево, не надо забивать людям мозги. Обычное бинарное дерево поиска, в крайнем случае - AVL (или любое другое сбалансированное дерево) прекрасно выполнят работу.
Обход для вывода содержимого дерева по возрастанию - симметричный: левое поддерево/корень/правое поддерево. Если хранить в дереве не только слово, а структуру (слово + указатель на список целых, или указатель на дерево - если все на деревьях), а процедуру добавления чуть-чуть изменить, и при повторном вхождении слова добавлять в список (дерево) еще одно значение: номер текущей строки файла, то потом одним симметричным обходом прекрасно все выведется - упорядоченный список слов, и для каждого из них - список номеров строк в которых оно встречается.... Доп. информация - здесь, попробуй реализовать, что непонятно - обращайся. Задача довольно простая, хотя и интересная. |
TarasBer |
![]()
Сообщение
#6
|
![]() Злостный любитель ![]() ![]() ![]() ![]() ![]() Группа: Пользователи Сообщений: 1 755 Пол: Мужской Репутация: ![]() ![]() ![]() |
> Не нужно здесь префиксное дерево, не надо забивать людям мозги.
Для строк префиксное проще, чем бинарное, потому что оно очень естественно гармонирует со структурой строки. (и алгоритмическая сложность меньше на логарифм) > Обычное бинарное дерево поиска, в крайнем случае - AVL (или любое другое сбалансированное дерево Да, любое другое, например, красно-чёрное, ну, чтобы не забивать людям мозги. (кто не знает из читающих тему - красно-чёрное дерево это лютая жесть). -------------------- |
volvo |
![]()
Сообщение
#7
|
Гость ![]() |
Даша, в качестве иллюстрации работоспособности:
Running "f:\programs\pascal\2010_12_10_dasha_2.exe " , программа тестировалась на файле: Цитата begin, end, start, finish, test start begin do this, test end test ![]() |
TarasBer |
![]()
Сообщение
#8
|
![]() Злостный любитель ![]() ![]() ![]() ![]() ![]() Группа: Пользователи Сообщений: 1 755 Пол: Мужской Репутация: ![]() ![]() ![]() |
Префиксное дерево строк + данные о номере строки в узлах дерева = основная часть программы укладывается в 20 строк.
Ну чё, volvo, у кого длинее? Так и будем гнать друг на друга, чьё дерево круче? -------------------- |
Даша |
![]()
Сообщение
#9
|
Новичок ![]() Группа: Пользователи Сообщений: 20 Пол: Женский Репутация: ![]() ![]() ![]() |
Ого.. Не думала что эта задача вызовет жаркий спор
![]() TarasBer и volvo: огромное спасибо что откликнулись). Да, мне как раз нужно бинарное дерево, ибо изучаем сейчас их, а значит и задачу надо сделать с помощью бинарных деревьев. Сейчас буду пытаться всё это реализовать ![]() Добавлено через 6 мин. Не успела начать писать, как сразу же появился вопрос.. Бинарное дерево строк как должно выглядеть? Что будет корнем, а что потомками? Если можно то на примере. |
volvo |
![]()
Сообщение
#10
|
Гость ![]() |
По ссылке, которую я привел, ходила? Там приведено описание бинарного дерева. Для твоей задачи я бы сделал так:
const(в принципе, в программе, результаты работы которой я показывал выше, я так и сделал) Если тебя интересует именно дерево строк - const, дерево будет хранить строки... Но это ничего не даст, потому что надо кроме строк хранить еще информацию... |
TarasBer |
![]()
Сообщение
#11
|
![]() Злостный любитель ![]() ![]() ![]() ![]() ![]() Группа: Пользователи Сообщений: 1 755 Пол: Мужской Репутация: ![]() ![]() ![]() |
> T = record
s: string[StrLen]; tree: TIntTree; { Это - тип "дерево целых" } end; Эээ, а почему не хватит структуры из строки и числа? -------------------- |
volvo |
![]()
Сообщение
#12
|
Гость ![]() |
Потому что слово может встречаться не в одной строке, а в нескольких (дубликаты, однако). И где я буду хранить номера строк? В одной переменной?
|
Даша |
![]()
Сообщение
#13
|
Новичок ![]() Группа: Пользователи Сообщений: 20 Пол: Женский Репутация: ![]() ![]() ![]() |
Пока что написала только это:
interface То есть описание типов, подсказанное volvo, и процедуру инициализации дерева. Но не очень понимаю структуру этого дерева.. Получается что в итоге мы создаем дерево из записей, в которых поле S это строка (в данном случае слово), и поле tree - это уже другое бинарное дерево, но уже из целых чисел, в которых хранятся номера строк для этого слова? Сообщение отредактировано: Даша - 12.12.2010 14:35 |
volvo |
![]()
Сообщение
#14
|
Гость ![]() |
Цитата Получается что в итоге мы создаем дерево из записей, в которых поле S это строка (в данном случае слово), и поле tree - это уже другое бинарное дерево, но уже из целых чисел, в которых хранятся номера строк для этого слова? Да, именно так. А что, это как-то противоречит заданию? По-моему, как раз наоборот, это именно то, чего просили в задании. Или это НЕ то, что хочет видеть преподаватель? Тогда извини, мне плевать, что он хочет видеть, я написал, как эту задачу решал бы я. За один проход вывести все дерево и для каждого его узла - все номера строк, в которых присутствует текущее слово (а потом ровно так же, за один проход, удалить всю выделенную под дерево память) - это, наверное, слишком просто? Нужна программа на пару тысяч строк? Это не ко мне.Цитата процедуру инициализации дерева ты еще не сделала. Когда заносишь слово в дерево TTree, нужно отдельно обрабатывать тот случай, который закомментирован: если слово уже присутствует в дереве. Это важно. Это первое замечание.Второе: зачем понадобилось выносить CreateNode из процедуры Insert и делать ее мало того, что внешней, так еще и открытой извне? CreateNode - чисто служебная процедура. никакого отношения к ней никто кроме Insert-а не имеет, она должна быть локальной внутри Insert. Чем меньше функций у тебя видимы извне - тем спокойнее. Каждый должен заниматься своей работой: Insert получил на вход строку? Получил. Все, на выходе - строка будет добавлена к дереву, либо к целочисленному дереву, соответствующему этой строке, будет добавлено еще одно значение: текущая позиция в файле. Больше CreateNode нигде не используется. Третье: не имей такой привычки убирать сигнатуру у функции в секции Implementation, и оставлять только имя. Потом, при попытке перейти на более современный компилятор, эта привычка тебе аукнется. И четвертое: зачем тебе здесь вообще модуль? Это все прекрасно делается одним файлом, без разбиения на модули. Поверь, 130 строк - не тот размер программы, чтобы ее начинать дробить на куски. Дробление начинается, когда количество строк зашкаливает за тысячу. |
Даша |
![]()
Сообщение
#15
|
Новичок ![]() Группа: Пользователи Сообщений: 20 Пол: Женский Репутация: ![]() ![]() ![]() |
Цитата А что, это как-то противоречит заданию? Нет нет. Я просто спросила чтобы убедиться правильно ли поняла. А так всё то что нужно ![]() Цитата Зачем понадобилось выносить CreateNode из процедуры Insert и делать ее мало того, что внешней, так еще и открытой извне? Почему то показалось, что она еще понадобится где нибудь. Сейчас занесу обратно. Цитата не имей такой привычки убирать сигнатуру у функции в секции Implementation, и оставлять только имя. Исправлюсь =) Цитата зачем тебе здесь вообще модуль? А вот это уже преподаватель просит, использовать модуль. Цитата нужно отдельно обрабатывать тот случай, который закомментирован: если слово уже присутствует в дереве. Это нужно перед тем как занести слово в дерево, сравнить его со всеми словами, которые там присутствуют? И еще, подскажите пожалуйста, как выбирать слова из файла? Посимвольно проходить файл и записывать символы в строку до тех пор, пока не встретится ',' или ' '? И как номер строки запомнить? c помощью цикла while и счетчика? Сообщение отредактировано: Даша - 12.12.2010 16:13 |
volvo |
![]()
Сообщение
#16
|
Гость ![]() |
Даша, смотри... Я могу, конечно отвечать на твои вопросы, но боюсь, по мере моих ответов, вопросов у тебя будет все больше
![]() Только сразу предупреждаю: (Показать/Скрыть)
Пока отвечаю на те вопросы, которые ты задала... Цитата Это нужно перед тем как занести слово в дерево, сравнить его со всеми словами, которые там присутствуют? Понимаешь в чем дело... Сама процедура Insert написана так, что она проверяет, встречается ли слово уже в дереве. Согласисьif info.s < str then { ... } , и вот если мы добрались до ветки else - то значит, строка в дереве уже присутствует. И все, что осталось - это добавить номер файловой строки в поле tree: else в переменной CurrLine хранится номер строки, которая была считана из файла, и в которой было найдено слово, заносящееся в дерево... Цитата как выбирать слова из файла? Посимвольно проходить файл и записывать символы в строку до тех пор, пока не встретится ',' или ' '? Я сделал по-другому. Построчно читал файл (очень удобно, прочел строку, увеличил счетчик строк - красота ![]() |
Даша |
![]()
Сообщение
#17
|
Новичок ![]() Группа: Пользователи Сообщений: 20 Пол: Женский Репутация: ![]() ![]() ![]() |
Цитата Сама процедура Insert написана так, что она проверяет, встречается ли слово уже в дереве. Согласись Согласна ![]() Цитата Разбиение на слова. Все способы. Большое спасибо за ссылку! Думаю, остальное смогу доделать сама ![]() |
Даша |
![]()
Сообщение
#18
|
Новичок ![]() Группа: Пользователи Сообщений: 20 Пол: Женский Репутация: ![]() ![]() ![]() |
Непонятна функция GetWords.. Ведь она же принимает значения типа byte, каким же образом тут слово вычленяется?
P.S. Это единственное, что осталось непонятным в данной задаче.. Добавление слов и номеров строк в дерево, а затем обход - понятно. А вот как выбирать слова - неясно.. Сообщение отредактировано: Даша - 13.12.2010 17:58 |
volvo |
![]()
Сообщение
#19
|
Гость ![]() |
Я не использовал саму функцию. Я использовал только способ, которым она реализована. Внутри GetWords есть строка
w[n] := copy(s, back, i-back);- это и есть выделение очередного слова из строки. Цитата она же принимает значения типа byte Не принимает, а возвращает это во-первых. Во вторых, возвращать значения можно и через параметры, что эта функция и делает: через параметр W возвращаются слова, количество слов - результат работы функции GetWords. |
Даша |
![]()
Сообщение
#20
|
Новичок ![]() Группа: Пользователи Сообщений: 20 Пол: Женский Репутация: ![]() ![]() ![]() |
Цитата Построчно читал файл Совсем не получается это реализовать.. Непонятно, как перейти к следующей строке файла.. |
![]() ![]() |
![]() |
Текстовая версия | 20.07.2025 3:02 |