Удалить из данной строки все повторные вхождения символов

      Комментарии к записи Удалить из данной строки все повторные вхождения символов отключены

Главная Форумы Программирование Помощь с решением задач на Prolog Задачи на строки и файлы Удалить из данной строки все повторные вхождения символов

В этой теме 4 ответа, 2 участника, последнее обновление  Васильев Владимир Сергеевич 2 года/лет, 1 месяц назад.

  • Автор
    Сообщения
  • #2190

    203
    Участник

    Здравствуйте. Помогите решить задачу по обработке строк на Prolog:

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

    Заранее спасибо.
    У меня есть наработки:

    domains
      charArray=char*
      str=string
      strl=str*
    predicates
      remall(charArray,str,str)
      task(str,str)
      nondeterm run
    clauses
      remall(_,"",""). 
      remall(C,S,R):- 
        frontchar(S,C,RS), 
        remall(C,RS,R),!.
      remall(C,S,R):- 
        frontchar(S,Q,RS), 
        remall(C,RS,RR), 
        frontchar(R,Q,RR).
    
      task("","").
      task(S,R):- 
        frontchar(S,A,RS), 
        remall(A,RS,RRS), 
        task(RRS,RR), 
        frontchar(R,A,RR).
    
      run:- 
        file_str("D:/Work/input.txt",S), 
        write(S), nl, 
        file_str("D:/Work/output.txt", S).
    
    goal
      run.

  • #2192

    Предикат удаления повторных вхождений символов должен работать следующим образом:

    1. если исходная строка пуста — результатом является пустая строка;
    2. исходная строка разбивается на первый символ (FirstSymbol) и остальные символы (StringTail);
    3. удаляются все вхождения символа FirstSymbol из StringTail — в результате формируется StringTailWithoutSymbol;
    4. StringTailWithoutSymbol обрабатывается рекурсивно, в результате формируется Tail;
    5. в качестве результата возвращается строка, составленная из FirstSymbol и Tail.

    Вы можете обрабатывать непосредственно строки, но удобнее обрабатывать списки. Я предлагаю воспользоваться готовыми предикатами для Преобразование строки в список символов и наоборот. После этого можно воспользоваться готовой функцией delete для Удаление элементов из списка.

    В Ваш код я не вникал, т.к. он оформлен с нарушением Соглашения о кодировании на Prolog — мне очень сложно его читать и, тем более, понимать.

  • #2193

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

    goal
      file_str("D:/Work/input.txt", InitialString), 
      string_to_list(InitialString, InitialList),
      remove_repeated(InitialList, ListWithoutRepeated),
      list_to_string(ListWithoutRepeated, StringWithoutRepeated),
      write(StringWithoutRepeated), nl.

    Тут содержимое файла считывается в строку, строка преобразуется в список, из списка удаляются повторяющиеся символы, результат преобразуется в строку, которая выводится на экран. Осталось описать функцию удаление повторов из списка по алгоритму, приведенному выше:

    remove_repeated([], []):-!. 
      % если исходный список не содержит элементов - результатом является пустой список
    remove_repeated([Head|Tail], [Head|TailWithoutRepeated]):- 
      % исходный список разделяется на первый элемент и остальные
      % первый элемент безусловно помещается в начало списка-результата
      delete(Tail, Head, TailWithoutHead), 
      % при помощи готовой функции delete из списка Tail удаляются все вхождения Head
      remove_repeated(TailWithoutHead, TailWithoutRepeated).
      % остальные элементы формируются рекурсивно

    Альтернативную реализацию этой функции можно посмотреть в теме «Преобразовать список во множество«.

  • #2194

    203
    Участник

    Спасибо большое за ответ. Но я что-то не могу понять как собрать это в рабочую программу

  • #2195

    Весь код, что я скинул размещаете в разделе clauses, а в разделе predicates описываете самостоятельно прототипы функций — т.е. указываете аргументы какого типа должна принимать функция. Для функции преобразования строки в список прототипы уже есть — смотрите внимательнее.

    Пробуйте, прикрепляйте исходный код своих попыток.

Для ответа в этой теме необходимо авторизоваться.