Давайте вновь напишем небольшой компонент поисковой системы.
Формат ввода
Сначала вводится поисковый запрос.
Затем вводятся имена файлов, среди которых следует произвести поиск.
Формат вывода
Выведите все имена файлов, в которых есть поисковая строка без учета регистра и повторяющихся пробельных символов.
Если ни в одном файле информация не была найдена, выведите «404. Not Found«.
Примечание
Система поиска должна обрабатывать строки "a b", "a b" и "a\nb" как одинаковые.
Пример
Ввод
# Пользовательский ввод:
Мама мыла РАМУ
first.txt
second.txt
# Содержимое файла first.txt
В этом файле говорится о том что МАМА
мылА
Раму
# Содержимое файла second.txt
А в этом не говорится
Вывод
first.txtВвод
# Пользовательский ввод:
Python
only_one_file.txt
# Содержимое файла only_one_file.txt
Тут нет никаких змей
Вывод
404. Not FoundРешение
В задании несколько «ловушек».
Первое, нужно понимать, что могут встретиться конструкции когда между пробелами окажется ‘ ‘ или ‘\n‘ и их надо корректно отработать.
Второе, при чтении по строкам важно отрезать лидирующие и конечные пробелы с помощью метода strip().
Третье. Нельзя забывать и о том, что содержимое файлов и строку поиска надо привести к одному регистру, а вот имена файлов трогать нельзя — там могут быть буквы в любом регистре.
Четвертое. Если вы знаете как работает поиск, то понимаете, что он ищет слова в любом порядке и допускает наличие любых других слов между искомыми. Так вот. В этой задаче это не так. Слова должны быть ровно в том порядке что даны и наличие между ними других слов недопустимо.
В остальном достаточно заменить все вхождения ‘ ’ на пробел, а потом избавиться от знаков перевода строки и парных пробелов.
Посмотреть код
Решение
from sys import stdin
search_for, *file_names = [string.strip() for string in stdin]
found = False
for file_name in file_names:
with open(file_name, encoding='UTF-8') as file:
data = ' '.join(file.read().replace(' ', ' ').lower().split())
## replace(' ', ' ') на самом деле это replace(' ', ' ')
if search_for.lower() in data:
print(file_name)
found = True
if not found:
print('404. Not Found')
В чём смысл replace(‘ ‘, ‘ ‘). ?
replace(‘ ‘, ‘ ‘) на самом деле это replace(‘ ’, ‘ ‘)
просто веб этот символ меняет на пробел
Здравствуйте, помогите понять почему не проходит проверку № 3 «WA»
from sys import stdin
search_query = input()
normal_search_query = search_query.lower()
Flag = False
for file_name in stdin.read().split():
with open(file_name, encoding=«UTF-8») as file_in:
line = file_in.read()
normal_line = » «.join(line.split()).lower()
result = all(word in normal_line for word in normal_search_query)
if result:
print(file_name)
Flag = True
if not Flag:
print(«404. Not Found»)
на мой взгляд основная проблема в этой строке:
по сути вы ищете буквы подстроки, а не подстроку.
from sys import stdin search_query = input() normal_search_query = search_query.lower() Flag = False for file_name in stdin.read().split(): with open(file_name, encoding="UTF-8") as file_in: line = file_in.read() normal_line = " ".join(line.split()).lower() if normal_search_query in normal_line: print(file_name) Flag = True if not Flag: print("404. Not Found")Не могу понять почему вот такой вариант падает на 4 проверке
import re
from sys import stdin
p = input().lower().replace(‘ ‘, »)
f = 1
for line in stdin:
with open(line.rstrip(«\n»), encoding=«UTF-8») as file:
data = file.read().lower()
text = re.sub(r»\s», «», data)
if p in text:
print(line[:-1])
f = 0
if f == 1:
print(‘404. Not Found’)
Код бы, конечно, вставить как код стоило. Там есть виджет специальный при написании комментария.
Чтобы не продираться сквозь отсутствующее форматирование и вебовские автозамены.
Основная проблема в том, что не пробел с точки зрения regexp.
Я думаю, что если бы вы прочитали текст на странице, ваши вопросы скорее всего отпали бы. Там упоминаются основные проблемы этой задачи.
А вообще зря вы полезли в regexp. Штука крутая, но требует определенного сдвига мозга набекрень. Если вы только учитесь программировать, то лучше этим голову пока не забивать.
import re from sys import stdin p = input().strip().lower() found = False for line in stdin: file_name = line.strip() # убираем \r, \n, пробелы вокруг with open(file_name, encoding="UTF-8") as file: data = file.read().lower().replace(" ", " ") # убираем HTML пробел text = " ".join(re.split(r"\s+", data)) if p in text: print(file_name) found = True if not found: print("404. Not Found")По поводу вставленного кода извиняюсь, он вставился нормально, не подумал что переформатируется при отправке. Использовать regexp был совет в одной из предыдущих задач, я решил что для этой задачи подходящее решение. re.sub(r»\s», «», data) вроде бы должно было удалить любые пробелы, в том числе переносы строк и табуляцию, если даже он не удаляет   я пробовал сначала заменить replace(« », » «) потом использовать re.sub(r»\s», «», data). Вроде бы должна была остаться сплошная строка в которой можно искать подстроку, но четвертая проверка почему то не проходит. Приходится именно сплитовать, а потом объединять что бы получить вроде бы такую же сплошную строку.
Нужно еще убирать сдвоенные пробелы. В оригинальной строке может быть словосочетание разделенное двойным и более пробелом. Сплит с последующей склейкой как раз решает эту проблему.
re.sub(r’\s’… убирает любое количество пробелов. Дело в чем то другом, не понятно в чем )
Хорошо, вам виднее,
Помимо этой проблемы (задваивающиеся пробелы), в вашем решении будет ошибка, если вдруг строка будет заканчиваться ‘\r\n’ или если там совсем не будет знака перевода строки.
Вы можете поиграть в игру найди отличия между тремя решениями которые работают и вашим.
Это очень хорошо помогает понять программирование.
Ниже, если вдруг вы все же хотите, чтобы за вас думал я, исправленные ошибки В ВАШЕМ решении.
Надо понимать, что нормализация строки p сделана недостаточно надежно. Возможно эта строка выглядит у вас не так, я не имею возможности судить точно, потому что не видел вашего кода полностью.
import re from sys import stdin p = input().lower().replace(' ', ' ') f = 1 for line in stdin: with open(line.rstrip('\n'), encoding="UTF-8") as file: data = file.read().lower().replace(" ", " ") text = re.sub(r"\s+", " ", data) if p in text: print(line.strip()) f = 0 if f == 1: print("404. Not Found")Ну и повторюсь. Вместо освоения библиотек наподобии re вам стоит сосредоточится на основах программирования и попытаться решить задачи без импортов до тех пор, пока это не будет явно оговорено в условии задачи или раздела. Это позволит структурировать мышление и не делать таких ошибок.
Спасибо за помощь. Все варианты сравнил и все таки нашел в чем была у меня ошибка. Оказывается проблема вовсе не в строках поиска, а в названии файла. Я для его печати использовал срез «print(line[:-1])», убирая последний перенос появляющийся при вводе через stdin, а в четвертой проверке похоже в названии файла где то лишний пробел и необходимо использовать strip() чтобы результат совпал. Вот мое итоговое решение:
import re from sys import stdin p = input().lower().replace(' ', '') f = 1 for line in stdin: with open(line.rstrip('\n'), encoding="UTF-8") as file: data = file.read().lower() text = re.sub(r"\s", "", data) if p in text: print(line.strip()) f = 0 if f == 1: print("404. Not Found")Вам повезло, что яндексы не додумались в тесты положить что-нибудь аналогичное
a = «постойте же ребята» и b = «постойте жеребята»
в вашем случае обе строки поиска будут одинаковые.
В целом, как я и говорил, ошибки у вас было две — неправильная работа с пробелами и обрезание строки, если в конце строки не будет знака переноса.