LINUX.ORG.RU

Задачка достаточно сложная :)

 , ,


0

1

Задача:

Предположим, что даны две последовательности букв.

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

Как можно понять сразу для частично вырожденного случая, например - «peal» и «leap» нам просто достаточно поменять местами вершину и дно стека. Но это ведь жульничество так или нет?

А возможен ли здесь универсальный метод решения задачи?!

И да, листинги на Си очень приветствуются :D

★★★★★

А можно для тупых, поподробнее? Звёздочка обозначает помещение в стек — чего? Предшествующей буквы? А извлечение из стека?

fat-II
()
Ответ на: комментарий от fat-II

Он сам откуда знает? Человеку нужно решение задачи, которую ему задали в его учебном заведении. Еще и код хочет готовый.

bhfq ★★★★★
()
Ответ на: комментарий от bhfq

Вообще-то я занимаюсь самообразованием, дорогие мои!

Twissel ★★★★★
() автор топика
Ответ на: комментарий от fat-II

Да. Извлечение - буква без последующей звездочки.

Задача из Седжвика, помечена как «высокого уровня сложности».

Twissel ★★★★★
() автор топика

Какойто непонятный задача. Что такое последовательность стековых операций? A так понял, что есть последовательности {a} и {b} и некий возможный набор операций над ними. Надо определить можно ли при помощи произвольного количества этих операций получить из {a} {b}. Вот в операциях и суть неопределенность. Что можно, а что нельзя?

«peal» и «leap» нам просто достаточно поменять местами вершину и дно стека

Как по мне так тут стек - лишнее. Комбинаторика. {peal} это вариант перестановки {leap}. Если поменять местами дно и вершину стека это стековая операция - озвучь все.

naszar
()
Последнее исправление: naszar (всего исправлений: 1)

то?

есть входная последовательность букв

и две операции и команда(по терминатору строки)

* - помещение очередной буквы из инпута в стек.

= - перенос очередной буквы из инпута в аутпут.

. - перенос из стека в аутпут содержимого стека поэлементо пока есть чё popить(эта операция есть всегда последняя операция в управляющей строке)

Вопрос дана входная последовательность и выходная последовательность , ваша программа должна сгенирировать «управляющую строку » переводящую входную в выходную или показать по какой причине такая строка не существует.

qulinxao ★★☆
()
Ответ на: комментарий от naszar

По книге у нас есть две стековые операции: push и pop, также мы можем перемещать указатель стека на произвольное число элементов из которых он состоит. Вроде все.

То, что этот алгоритм с комбинаторным уклоном я и сам догадываюсь, но математически выразить не могу :)

Twissel ★★★★★
() автор топика
Ответ на: то? от qulinxao

Где-то туда :) Спасибо, за участие. Мне всегда приятно видеть умных людей.

Twissel ★★★★★
() автор топика
Ответ на: комментарий от Twissel

дык это задача на сортировку вагонов когда есть только 1 тупик и 1 прямой путь

т.е картинка

путь идущий прямо и у него есть поворот в середине в тупик и выезд из тупика.

по условию выезжать(из тупика) может только 1 состав ибо толкач в самом начале в тупике и выталкивает только 1 раз для приехавшего поезда.

решение очевидно

qulinxao ★★☆
()
Ответ на: комментарий от Twissel

мы можем перемещать указатель стека на произвольное число элементов из которых он состоит

Прости, если я кажусь тупым, но такая операция + pop позволяет получить произвольный элемент «стека». Т.е. узнать есть ли решение для двух данных последовательностей можно просто отсортировав их и сравнив?

naszar
()

например - «peal» и «leap» нам просто достаточно поменять местами вершину и дно стека

Это ж как так поменять? И какой стек: нормальный LIFO?

1. делаем последовательно push:

char *str = "peal";
while(*str) push(*str++);
// все, в стеке p,e,a,l

2. Чтобы делать произвольные махинации со стеком, нам придется добавить операции "пропуска" элементов стека (либо завести дополнительный стек), а также для простоты сделать стек двунаправленной очередью:

char newstr[5] = {0}; 
newstr[0] = pop(); // в стеке p,e,a
char tmp = pop();  // tmp = a, в стеке p,e
newstr[1] = pop(); // в стеке p, newstr = "le"
newstr[2] = tmp;   // newstr = "lea"
newstr[3] = pop(); // стек пустой, newstr = "leap"

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от Eddy_Em

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

naszar
()
Ответ на: комментарий от Eddy_Em

Эдуард, возможно я покажусь Вам наркоманом, но вчера действительно я сделал это предположение так, будто мы можем вытолкнуть из стопки произвольный элемент. А не только тот, который на верхушке «стопки».

Каюсь. Да.

Twissel ★★★★★
() автор топика
Последнее исправление: Twissel (всего исправлений: 1)
Ответ на: комментарий от Twissel

Но нельзя решить задачу не поняв условия. У тебя по описанию выходит массив. Решение это просто индекс элемента из {b} в {a}?

naszar
()
Ответ на: то? от qulinxao

А какой смысл иметь '*' и '=', когда есть '.'? Чтобы иметь возможность копировать стек поэлементно? Но последовательность же не изменится. Нужны «регистры» в которых можно переставлять символы, и вопрос только в том, сколько регистров.

naszar
()
Ответ на: комментарий от Twissel

последнего уровня сложности

Принеси мне то, не знаю что? А ты точно всю задачу переписал, и что всетаки значит «стековая операция»? Просто пушем и попом можно скопировать часть стека, или весь стек в другой стек. Последовательность символов ты никак не поменяешь. Может они имеют ввиду что {b} это подпоследовательность {a}?

naszar
()
Ответ на: комментарий от Twissel

В общем, примерно это уже описано здесь

Так там тупик дает возможность доступа к произвольному элементу. Чтобы получить n-й элемент на вершине, нужно сложить n-1 в тупик. Единственно может можно это дело как-то оптимизировать. И есть ограничение:

так, что каждый вагон может лишь один раз заехать с пути 1 в тупик, а затем один раз выехать из тупика на путь 2

А у тебя такого ограничения нет.

naszar
()
Ответ на: комментарий от qulinxao

А как менять элементы местами? В задачке про поезд есть тупик. А тут как?

naszar
()
Последнее исправление: naszar (всего исправлений: 1)

Прочитал тред, не понял qulinxao правильно изложил твою задачу или нет?

добавить звездочку

Одну?

Kuzy ★★★
()
Ответ на: комментарий от Kuzy

не понял qulinxao правильно изложил твою задачу или нет?

peal -> leap - не получится.

Kuzy ★★★
()
Ответ на: комментарий от Kuzy

Поскольку формулировка туманная, будем считать, что правильно.

Twissel ★★★★★
() автор топика
Ответ на: комментарий от Twissel

Тогда не дезинформируй людей и не пиши "стек".

А с двунаправленным списком любые манипуляции можно влегкую делать.

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от Twissel

По сути оптимизация перебора.

Если я правильно понял то есть 2 операции (a и b), каждая из них рождает перестановку строки. Требуется найти цепочку перестановок S0 в Sn.

  1. Создаём множество перестановок {S0} (пока там только одна перестановка S0) и пустое пока множество {U}
  2. Применяем ко всем элементам множества {S0} операции a и b, результатом становится множество {S1}
  3. Если среди элементов {S1} есть Sn значит цепочка операций найдена (порядок операций естественно нужно хранить). Всё.
  4. Считаем число элементов {U}
  5. Добавляем {S1} в {U}
  6. Считаем число элементов {U}, если оно не изменилось - задача не имеет решения. Всё
  7. Повторяем начиная с п2 для {S1}

Лень вникать в условия задачи, это первый способ который пришёл в голову.

ya-betmen ★★★★★
()
Последнее исправление: ya-betmen (всего исправлений: 1)
Ответ на: комментарий от Eddy_Em

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

Twissel ★★★★★
() автор топика
Ответ на: комментарий от Twissel

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

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от Twissel

Там используется несколько стеков!

Скажем, в задаче ханойской башни стека три. И задача полностью решается (но за очень большое время). Чем больше промежуточных стеков, тем шустрей можно выполнить произвольную перестановку элементов.

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от Eddy_Em

Правильно. Ведь ограничения на количество стеков в задаче нет.

Все сходится :)

Twissel ★★★★★
() автор топика
Ответ на: комментарий от Twissel

Предлагаю такой алгоритм (undestructive_pop — прочитать вершину стека, не опустошая):

1. на вход задаем исходное слово и нужное.

2. побуквенно просматриваем исходное слово:

2а. если буква исходного совпадает с первой незаполненной нужного, заполняем, переходим дальше; 2б. если стек пуст, делаем push текущей буквы, переходим дальше; 2в. если undestructive_pop не совпадает с нужной, делаем push; 2г. иначе делаем pop;

3. проверяем, заполнили ли мы полностью требуемое слово. Если заполнили — возвращаем TRUE, иначе — FALSE.

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от Twissel

Это для одного стека. Могу сейчас попробовать код набросать.

Для нескольких стеков уже задача посложней — бери алгоритм ханойской башни.

Eddy_Em ☆☆☆☆☆
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.