Без применения регулярных выражений - PascalABC.NET

Узнай цену своей работы

Формулировка задачи:

Нужна срочно помощь.Задание сделала,но преподователю не понравилось с формулировкой:-"Этого не было в нашей образовательной программе,сделай проще,убери регулярные ворожения".Программа работает.Нужно сделать проще,то есть,без применения регулярных выражений.Пожалуйста помогите.... Вот рабочая программа.
Настали тяжелые времена. Сегодня Пете нужно набрать на экзамене по информатике 100 баллов. Все задачи на экзамене Пете кажутся простыми, но он боится, что не успеет сделать одну из них за такой маленький промежуток времени, поэтому он обратился к вам за помощью. В условии даётся шаблон (строка, состоящая из строчных латинских букв, символов «?» и «*»). Известно, что символ «*» встречается в шаблоне не более одного раза. Также в условии даны n строк-запросов, и для каждой необходимо определить, подходит ли она под данный шаблон, или нет. Все было бы хорошо, но специальные символы в шаблоне в этой задаче действуют не так, как обычно! Строка подходит под шаблон, если можно в шаблоне заменить каждый из символов «?» на одну хорошую строчную латинскую букву, а символ «*» (если он есть) — на любую, в том числе пустую, строку из плохих строчных латинских букв так, чтобы результат совпал со строкой. В условии также даны буквы, считающиеся хорошими. Плохими являются все остальные буквы латинского алфавита. Входные данные В первой строке находится строка, содержащая от 1 до 26 различных строчных латинских букв. Это буквы, которые считаются в задаче хорошими. Все остальные буквы — плохие. Во второй строке находится шаблон — строка s из строчных букв латинского алфавита, символов «?» и «*» (1 ≤ |s| ≤ 105). Гарантируется, что символ «*» встречается в s не более одного раза. Во третьей строке находится целое число n (1 ≤ n ≤ 105) — количество строк-запросов. Далее следуют n строк, в каждой из них находится по одной непустой строке, состоящей из строчных латинских букв — очередная строка-запрос. Гарантируется, что сумма длин всех строк-запросов не превосходит 105. Выходные данные Выведите n строк: в i-й строке необходимо вывести «YES», если i-я строка-запрос удовлетворяет шаблону, и «NO» в противном случае. Вы можете выводить каждую из букв в любом регистре. Примеры входные данные ab a?a 2 aaa aab выходные данные YES NO

Решение задачи: «Без применения регулярных выражений»

textual
Листинг программы
var
  s: array of string; // строка
  st: string; // шаблон
  good: set of char = ['a'];
  i, it, n: integer;
 
begin
  readln(st); // хорошие буквы, заносим в множество good
  foreach var ch in st do Include(good, ch);
  
  readln(st); // шаблон
  readln(n); // количество строк для проверки
  SetLength(s, n);
  for var curr := 0 to n - 1 do readln(s[curr]); // читаем строки
  
  for var curr := 0 to n - 1 do 
  begin
    i := 1; it := 1;
    while (i <= Length(s[curr])) and (it <= Length(st)) do
    begin
      if st[it] = '?' then // следующая буква шаблона - "?", ей должна соответствовать одна из хороших букв в строке
      begin
        if s[curr][i] in good then // в строке - хорошая буква, все нормально
        begin
          inc(i);inc(it);
        end
        else 
        begin
          i := length(s[curr]) + 2; // нет, буква в строке плохая, выходим из цикла
        end;
      end
      else if st[it] = '*' then // следующий символ шаблона - '*',ей может соответствовать 0 или больше плохих букв
      begin
        // так что пропускаем плохие буквы, пока не встретится хорошая, или пока не дойдем до конца строки
        while (i < Length(s[curr])) and (s[curr][i] in (['a'..'z'] - good)) do inc(i);
        inc(it);
      end
      // просто буква - проверяем на равенство две буквы
      else 
      begin
        if s[curr][i] = st[it] then // буквы равны - все нормально
        begin
          inc(i);inc(it);
        end
        else 
        begin
          i := length(s[curr]) + 2; // нет - выходим из цикла
        end;
      end;
    end;
    // совпадение строки и шаблона - только в том случае, если индекс очередного символа
    // и там и там на 1 больше длины соответствующей строки (то есть, мы только что
    // закончили обрабатывать как строку, так и шаблон)
    if (i = length(s[curr]) + 1) and (it = length(st) + 1) then writeln('YES')
    else writeln('NO');
  end;
end.

Объяснение кода листинга программы

  1. Задачу программы можно описать как проверку соответствия строки шаблону, при этом не используя регулярные выражения.
  2. Код использует множество good для хранения хороших букв.
  3. Сначала в цикле с помощью функции Readln считываются строка шаблона и количество строк для проверки.
  4. Далее в цикле считываются сами строки для проверки.
  5. Для каждой строки в цикле происходит проверка соответствия шаблону.
  6. Если в шаблоне стоит символ ?, то программа проверяет, есть ли такая буква в текущей строке.
  7. Если в шаблоне стоит символ *, то программа пропускает плохие буквы до тех пор, пока не встретит хорошую или не достигнет конца строки.
  8. Если шаблон просто состоит из буквы, то программа сравнивает ее с буквой из строки.
  9. Если строка и шаблон совпадают, то выводится YES, иначе NO.
  10. В конце программы выводится общее количество строк, которые соответствуют шаблону.

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

7   голосов , оценка 4.286 из 5
Похожие ответы