Разделение строки и подсчет символов

      Комментарии к записи Разделение строки и подсчет символов отключены

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

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

    Nika
    Участник

    В строке имеется одна точка с запятой (;). Подсчитайте количество символов до точки с запятой и после неё.

  • #2649

    Опять приведу решение для SWI Prolog, т.к. диалект не указан. В вашем случае удобно рассматривать строку как список (в Turbo Prolog или Visual Prolog нужно предварительно преобразовать строку в список символов).
    Можно смотреть, что исходный список состоит из части до точки с запятой, списки из одного элемента (точки с запятой), части после точки с запятой. Разделить список на части можно функцией append (там же смотри функцию length, которая пригодится для вычисления длин строк при использовании Turbo Prolog) или еще более красиво – функцией divide_list:

    before_after_symbol(String, BeforeCount, AfterCount):-
      divide_list(String, [Before, ";", After]), !,
      lenght(Before, BeforeCount),
      length(After, AfterCount).

    Отсечение тут стоит, т.к. по условию точка с запятой одна – если ее убрать, то ничего особо не изменится, но divide_list будет пробовать найти другие решения.

  • #2651

    Nika
    Участник

    Если вам не трудно, можно ли объяснить решение данной задачи на Visual Prolog?

    • #2655

      Выше есть ссылка на функцию преобразования строки в список символов. Вы должны вызвать ее, а затем результат передать в before_after_symbol, код которой я привел. Все функцию по ссылкам очень подробно описаны, с чем именно у вас возникают проблемы?

  • #2670

    Nika
    Участник

    Дело в том, что задачу необходимо решить в варианте строк. Без списков. Используя такие предикаты как fronttoken, frontchar, str_len и др.
    Я не понимаю, как это сделать.

  • #2672

    Предикат frontchar выполняет примерно ту же операцию, что разделение списка на голову и хвост, но для строк:
    frontchar(String, HeadChar, TailString)
    В вашей задаче нужно отделять символы строки до тех пор, пока не попадется точка с запятой, при этом нужно накапливать или символы строки или считать длину. Кроме того, нас интересует часть строки за этим символом:

    before_after_symbol(String, "", AfterString):-
      frontchar(String, ";", AfterString), !.

    Тут записано, что если первым символом исходной строки является точка с запятой – нужно вернуть пустой список в качестве строки до символа и остаток строки – после.

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

    before_after_symbol(String, BeforeString, AfterString):-
      frontchar(String, Char, TailString), 
      before_after_symbol(TailString, BeforeStringTail, AfterString),
      frontchar(BeforeString, Char, BeforeStringTail).

    После этого останется только вызвать для полученных частей функцию str_len чтобы получить искомую длину строк:

    before_after_symbol(String, BeforeString, AfterString),
    str_len(BeforeString, BeforeLength),
    str_len(AfterString, AfterLength).

  • #2684

    Nika
    Участник

    Здесь появляется ошибка с строке

    frontchar(BeforeString, Char, BeforeStringTail).

    This flow pattern doesn’t exist frontchar(o,i,o).

    • #2685

      Ошибка говорит о том, что мы пытаемся передать на вход frontchar второй аргумент, а первый и третий являются неинициализированными (т.е. являются выходными значениями). На самом деле, в этом фрагменте кода мы хотим, чтобы только первый аргумент был выходным – в моем коде была опечатка (в имени переменной), я ее исправил. Попробуйте еще раз.

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