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