singlepost

Помогите доделать задачу (Паскаль) << На главную или назад  

Первое слово необходимо преобразовать во второе, используя наименьшее количество следующих действий:
1.удалений символа;
2.замен символа на любой другой.
Ваша программа должна
запросить исходное слово (до 20 символов), которое будет преобразовываться;
запросить слово, которое нужно получить;
для найденного самого короткого преобразования выполненного по правилам сообщить:
число удалений;
число замен;
для контроля слово, образовавшееся после выполнения всех удалений и слово-результат,
или сообщить, что преобразование невозможно.

Пример. Исходные данные: корова, свора. Ответ: удалений 1, замен 3, после удаления – коова, итог –свора.

2 случая я рассмотрела….с 3им проблемы…(там, где звёздочки, нужно вставить ещё несколько условий)

Program P3;
const
n=20;
var
a,b:string[n];
i,j,k:integer;
del1,fin:string[n];
del,ch:integer;
begin
writeln ('Vvedite nachalnoe slovo',a);
read(a);
writeln ('Vvedite konechnoe slovo',b);
read(b);
if length(a)<length(b) then
writeln ('Preobrazovanie nevozmozhno')
else
begin
if a=b then
ch:=0;
del1:=a;
fin:=b;
del:=0;
begin
for i:=1 to length(a) do
begin
if a[i]<>b[i] then
ch:=ch+1;
end;
end;
end;
if length(a)>length(b) then
del:=length(a)-length(b);
**************************************************************
writeln('Delete – ',del,', Change – ',ch,', After delete – ',del1,', Final – ',fin);
end.

71 ответов в теме “Помогите доделать задачу (Паскаль)”

  1. 30
    Денис Лисов ответил:

    На Паскале – нет, я недостаточно им владею. C или Python – могу, но не сейчас.

  2. 29
    Tanya Bass ответил:

    Вообщем так я и не решила….А не могли бы Вы написать мне правильный код?…А то обидно, что так и не узнала правильного решения…
    Хоть на будущее буду знать….

  3. 28
    Денис Лисов ответил:

    Неверно по двум причинам. Первое, фрагмент
    repeat
    for i:=0 to length(a) do
    begin
    if a[i]<>b[i] then
    delete(a,i,1);
    end;
    until length(a)>=length(b);
    будет делать не то, что ты имеешь в виду. Он может удалить больше символов, чем требуется.
    Вторая, это не то, что нужно для оптимального решения. Вот скажем, рассмотрим преобразование
    aabccd -> aaecc
    Оно делается за одно удаление (d) и одну замену. А вот если ты удалишь первую несовпадающую букву – b – то оно потребует две замены вместо одной, что неоптимально.

  4. 27
    Денис Лисов ответил:

    Tanya ✖♥ Bass, проблема в том, какие именно символы удалять из строки a. Фактически, то, как делать 2 и 3 оптимально выше я и описал. Дополню только, что надо еще запоминать путь (т. е. выбранный вариант – 1 или 2) для восстановления результата удаления.

  5. 26
    Tanya Bass ответил:

    Денис "Марсианин" Лисов,
    вот посмотрите…Я считаю, что это выглядит примерно так…Но здесь есть какая-то ошибка, которую я никак не могу найти…
    Program P3;
    uses
    crt;
    var
    a,b:string;
    i,j,k:integer;
    del1,fin:string;
    del,ch:integer;
    flag:boolean;
    begin
    writeln ('Vvedite nachalnoe slovo',a);
    read(a);
    writeln ('Vvedite konechnoe slovo',b);
    read(b);
    if (length(a)>=20) or (length(b)>=20) then
    flag:=false;
    if length(a)<length(b) then
    writeln ('Preobrazovanie nevozmozhno')
    else
    begin
    if a=b then
    ch:=0;
    del1:=a;
    fin:=b;
    del:=0;
    begin
    for i:=1 to length(a) do
    begin
    if a[i]<>b[i] then
    ch:=ch+1;
    end;
    end;
    end;
    if length(a)>length(b) then
    del:=length(a)-length(b);
    repeat
    for i:=0 to length(a) do
    begin
    if a[i]<>b[i] then
    delete(a,i,1);
    end;
    until length(a)>=length(b);
    del1:=a;
    fori:=1 to length(a) do
    begin
    if a[i]<>b[i] then
    ch:=ch+1;
    end;
    writeln('Delete – ',del,', Change – ',ch,', After delete – ',del1,', Final – ',fin);
    end.

  6. 25
    Tanya Bass ответил:

    так….у меня в программе написаны все варианты решения кроме того, где length(a)>length(b)..Причё количество удалений найти очень легко, del:=Length(a)-length(b)..
    Далее у меня была вот такая мысль:
    1. Сравнить строки а и b
    2. Удалить несовпадающие символы и строки a, причём делать это пока length(a) не станет равно length(b)
    3. Сосчитать кол-во несовпадений в полученных строках (теперь уже равной длины)
    4.Вывести строку a и результат 3-го пункта

    а вот как это реализовать у меня не получается…

  7. 24
    Владимир Гордеев ответил:

    хм. Попробую реализовать. Утро вечера мудренее.

  8. 23
    Денис Лисов ответил:

    Итоговое решение требует времени порядка n*k, где длина входной строки n+k, целевой – n.

  9. 22
    Денис Лисов ответил:

    И по времени тоже не прокатит, даже для 20 символов. Рост времени – быстрее экспоненты.

  10. 21
    Денис Лисов ответил:

    Как нам путем преобразования получить нужную строку? Есть всего два варианта:
    1. Если первый символ исходной строки удаляется, то задача сводится к задаче получить нужную строку из исходной строки без первого символа и решается за такое же число замен – рекурсия.
    2. Если первый символ исходной строки сохраняется, то задача сводится к задаче получить нужную строку без первого символа из исходной строки без первого символа и требует либо столько же замен, либо на одну больше, в зависимости от того, совпадают ли первые символы. Опять рекурсия.

    При этом требуется учесть несколько специальных случаев, наобходимых для завершения рекурсии:
    a. Если длины строк равны, то вариант 1 невозможен и остается только вариант 2.
    b. Если требуется получить строку длины 0, то это делается за 0 замен вне зависимости от длины исходной строки.

    Пока эта рекурсия будет идти очень медленно. Почему? Потому что множество вариантов будет рассчитываться неоднократно. Нужно оптимизировать.

    Заметим, что нам в ходе решения требуются решения задачи:
    За сколько замен (плюс сколько-то удалений) можно превратить последние n+k символов входной строки в последние n символов целевой строки?
    При этом мы ищем решение с заранее известными n и n+k (длины целевой и входной строк), а рекурсия ссылается на ту же задачу для n'=n, k'=k-1 (если k' >=0) и n'=n-1, k'=k (если n' >=0).
    Следовательно, нам достаточно будет посчитать решения этой задачи для k и n от 0 до начальных значений. Начиная счет от 0, мы тем самым превращаем нашу задачу в последовательное заполнение массива по известному алгоритму вплоть до получения требуемого значения.

  11. 20
    Денис Лисов ответил:

    Алгоритм неверный.
    Контрпример:
    acccbb -> aabb
    Должно быть 2 del 1 swaps. А программа выдает?

  12. 19
    Денис Лисов ответил:

    google "динамическое программирование". Или могу здесь обрисовать идею решения задачи.

  13. 18
    Владимир Гордеев ответил:

    обрисуй здесь пожалуйста.

  14. 17
    Денис Лисов ответил:

    Корректность сходу проверить не могу, но алгоритм крайне медленный.

  15. 16
    Владимир Гордеев ответил:

    > (до 20 символов)

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

  16. 15
    Владимир Гордеев ответил:

    Чёрт, я не учёл, что можно удалять с середины. Тогда программа значительно усложняется.

    //nopaste.info/d26e6d7659.html

    рекурсия во все поля!

  17. 14
    Владимир Гордеев ответил:

    Может опять где-то оплашал, лучше посмотрите. Указанные контр-примеры проходят.

  18. 13
    Tanya Bass ответил:

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

  19. 12
    Денис Лисов ответил:

    Попробуй найти примеры динамического программирования и понять, как это делается…

  20. 11
    Денис Лисов ответил:

    Тут нужно либо перебрать все варианты вырезания букв – но это может быть очень долго – либо применить какую-то хитрую идею. Динамическое программирование – это идея.

  21. 10
    Tanya Bass ответил:

    Я в программировании новичок)))
    Так что не особо знаю различные подходы к решению задач…

  22. 9
    Tanya Bass ответил:

    Денис "Марсианин" Лисов, да, действительно, программа работает не очень правильно….
    в данный момент перерабатываю…))

  23. 8
    Денис Лисов ответил:

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

  24. 7
    Денис Лисов ответил:

    Все хорошо, только вот алгоритм неверный, как мне кажется.

    Парочка контрпримеров:
    aaaaa -> bbb
    Должно быть 2 del 3 swaps, а программа что выдает?
    aaccbb -> aabb
    Должно быть 2 del 0 swaps, а программа что выдает?

  25. 6
    Владимир Гордеев ответил:

    Я имел ввиду послушать.

    Я вообще до некоторого времени думал что басисток не бывает =).

    Даже спеллчекер говорит что не знает слов "басистка" "басисток".

  26. 5
    Tanya Bass ответил:

    Басистки бывааают)))
    И барабанщицы тоже))

  27. 4
    Владимир Гордеев ответил:

    Есть чем похвастаться?

  28. 3
    Tanya Bass ответил:

    Если Вы о стаже игры (не только на басу) – есть))
    А если о том, чего бы послушать, то в данный момент записанных вещей нет(

  29. 2
    Tanya Bass ответил:

    Большое спасибо)
    Да, правда)

  30. 1
    Владимир Гордеев ответил:

    Держи

    //nopaste.info/ed449ec85f.html

    А ты что, правда на басу играешь?

Клуб программистов работает уже ой-ой-ой сколько, а если поточнее, то с 2007 года.