Помогите найти ошибку в решении 24й задачи ЕГЭ информатика PYTHON
Мой код:
with open("24_17641.txt") as f:
s = f.readline()
ans = 0
s = s.replace('**', ' ')
s = s.replace('++', ' ')
s = s.replace('+*', ' ')
s = s.replace('*+', ' ')
s = s.replace(' *', ' ')
s = s.replace('* ', ' ')
s = s.replace(' +', ' ')
s = s.replace('+ ', ' ')
s = s.replace('0*', '!*')
s = s.replace('0+', '!+')
s = s.replace(' 0', ' ')
s = s.replace('!', '0')
a = s.split(" ")
for i in a:
if i != '' and eval(i) == 0:
ans = max(ans, len(i))
print(ans)
содержимое 24_17641.txt:
добавьте сюда содержимое файла
Условие задачи:
Текстовый файл состоит из десятичных цифр,
знаков «+» и «*» (сложения и умножения).
Определите максимальное количество символов в непрерывной последовательности,
являющейся корректным арифметическим выражением с целыми неотрицательными
числами (без знака), значение которого равно нулю.
В этом выражении никакие два знака арифметических операций не стоят рядом,
порядок действий определяется по правилам математики.
В записи чисел отсутствуют незначащие (ведущие) нули.
В ответе укажите количество символов.
Ответы (3 шт):
import os
print("-" * 60 + "\nПоиск в файле выражения, равного 0, максимальной длины:\n" + "-" * 60)
def is_valid_expression(v_input_string):
# Проверяем корректность арифметического выражения
if not v_input_string or v_input_string[0] in '+*' or v_input_string[-1] in '+*':
return False
# Проверяем отсутствие двух операторов подряд
v_length = len(v_input_string)
for v_index in range(v_length-1):
if v_input_string[v_index] in '+*' and v_input_string[v_index+1] in '+*':
return False
# Проверяем отсутствие ведущих нулей в числах
v_current_number = ''
for v_char in v_input_string:
if v_char.isdigit():
v_current_number += v_char
else:
if v_current_number.startswith('0') and len(v_current_number) > 1:
return False
v_current_number = ''
if v_current_number.startswith('0') and len(v_current_number) > 1:
return False
try:
# Проверяем, что выражение равно 0 и целое
v_result = eval(v_input_string)
return isinstance(v_result, int) and v_result == 0
except:
return False
def find_max_zero_expression(v_filename):
# Читаем файл
with open(v_filename, 'r') as v_file:
v_text = v_file.read().strip()
v_max_length = 0
v_text_length = len(v_text)
# Перебираем все подстроки
for v_start in range(v_text_length):
for v_end in range(v_start, v_text_length):
v_substring = v_text[v_start:v_end+1]
if is_valid_expression(v_substring):
v_max_length = max(v_max_length, len(v_substring))
return v_max_length
# Запуск программы
v_input_filename = 'input.txt'
# Содержимое файла: 2+3+0*1+2+4+5*6+7+3+6*2+2+2*0*3*4
if not os.path.exists(v_input_filename):
print(f"Файл {v_input_filename} не найден!")
else:
print("Результат:", find_max_zero_expression(v_input_filename))
print("\nНажмите любую клавишу для продолжения...")
os.system("pause > nul" if os.name == "nt" else "read > /dev/null")
Такое:
def SearchZeroExpr(t):
s = t.find('0')
e = s + 1 if s > -1 else -1
sn, en, se, co, di, t = -1, -1, True, '+', 0, t + '++1'
for i in range(len(t)):
c = t[i]
if se:
if c > '+':
if en - sn > e - s:
s, e = sn, en
sn, di, sz, sm, se, sd = i + di, 0, i, i, False, False
zm = zd = c == '0'
else:
if sm < 0:
if c > '+':
sd, sm, sz = False, i, i
zm = zd = c == '0'
else:
se = True
else:
if sd:
if c > '+':
zd = c == '0'
sd, zm = False, zm or zd
else:
se = True
else:
if c == '*':
sd = True
if zm:
en = i
elif co == '0' and sz == sm:
sz = i - 1
elif c == '+':
if zm:
sm, en = -1, i
elif sz > sm:
sn, sm, en = sz, -1, i
else:
se = True
if co == '0':
di, en = -2, i - 1
elif zd:
se, en = True, i
co = c
# print(t[s : e])
return e - s
print(SearchZeroExpr(open("9rWpROaef.txt").read()))
Ответ (данные из предыдущего поста):
169
0+32373*0*60611+0*0*29472+0+49966*47103*0*0*0+0+0+0+0*54026*0+22544*0*0*0+0+0+0*0*0*0*0*0+0+0+0*0*29624+0+0+60153*0+0+0*52823*0*0*0*0*0*0*0+0+0*0+0+0+0*17505+0+0*0*0*0+0
Алгоритм решения, основанный на анализе условий задачи:
- Искомая последовательность - это сумма или произведений, в которых есть хотя бы один нулевой сомножитель, или нулей.
- Искомая последовательность начинается с цифры.
- Искомая последовательность заканчивается перед знаком перед ненулевым слагаемым или перед нарушением требований к выражению.
- Последовательности не пересекаются, если только среди сомножителей не найдётся оканчивающийся на ноль. Самый левый такой ноль может быть началом новой последовательности.
Можете помочь найти ошибку именно в моем коде?
Не уверен, что ваш подход в целом вообще способен решить задачу, но укажу на явные ошибки.
- Следующий фрагмент нужно поторять многократно, пока искомые подстроки не буду обнаруживаться:
s = s.replace(' *', ' ')
s = s.replace('* ', ' ')
s = s.replace(' +', ' ')
s = s.replace('+ ', ' ')
- Здесь
s = s.replace('0*', '!*')
s = s.replace('0+', '!+')
s = s.replace(' 0', ' ')
s = s.replace('!', '0')
вы, очевидно, хотите избавиться от лидирующих нулей, но у вас это получится только в начале выражения и то только при условии повторения s = s.replace(' 0', ' ') до исчезновения искомой подстроки, а середина у вас останется, и это нужно будет детектировать как несоответствие условиям корректности выражения в if i != '' and eval(i) == 0 and i не содержит последовательности 'з0ц' (где з - это знак, ц - это цифра), а такую проверку сделать без регулярок непросто.
- Вы упускаете подпоследовательности, например для очередной i
1230*456*78+0+1(не 0) вы не проверяет подстроку0*456*78+0.
На мой взгляд, всё гораздо проще...
import re
with open(r'C:\Users\Downloads\9rWpROaef.txt', 'r', encoding='utf-8') as f:
line = f.readline()
В этом выражении никакие два знака арифметических операций не стоят рядом—
следовательно, делим содержимое файла на подстроки регуляркой:
sub_lines = re.split(r'(?<=\d)[+*]{2,}(?=\d+)', line)
Определите максимальное количество символов в непрерывной последовательности ...—
значит мы отстортируем список по убыванию длинны строк:
sub_lines = sorted(sub_lines, key=len, reverse=True)
В записи чисел отсутствуют незначащие (ведущие) нули.—
это выглядит как утверждение, на всякий случай, отбракуем такие строки:
valid_lines = (
l for l in sub_lines
if not re.search(r'(^0\d)|((?<=[+*]{1})0\d)', l)
)
значение которого равно нулю—
пробежимся в цикле до первого выполнения условия:
for line in valid_lines:
if eval(line) == 0:
print(f'{line} = 0\n длинна искомой строки: {len(line)}')
break
Output:
(.venv) PS D:\BookMemoryOrenburgRegion>
0*60284+0+0+16828*0*0*0*0+0*8888*0*76525*0+0*0+0*0*0*0*0*51124+0*0*0*0*0+0*0*276
70+0*0*0*0+0+0+0*77075*0+90261*0*0*0*31466*0+53090*0*0+0+0+0+0*0 = 0
длинна искомой строки: 144
(.venv) PS D:\BookMemoryOrenburgRegion>