проверка постфикса со слишком большим количеством операторов - PullRequest
1 голос
/ 30 июня 2019

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

Я только добавил сюда код, который я считаю необходимым.Если бы код мог быть относительно похожим, это было бы здорово.

edit: теперь просто говорится, что ничего не может быть оценено

def process(testline,count):
    k=[]

    for i in range(0,len(testline),1): 
        if(testline[i].isdigit() == True): 
            k.append(float(testline[i]))

        else:
            try:
                x = j.pop()
                y = j.pop()
            except IndexError:
                break

        if (testline[i]=='*'): 
            ans = x * y
            k.append(ans)

        elif (testline[i]=='+'):
            ans = x + y
            k.append(ans)

        elif (testline[i]=='-'):
            ans = x - y
            k.append(ans)

        elif (testline[i]=='/'):
            ans = x / y
            k.append(ans)

        else:
            print("Line",count,"is not able to be evaluated")
            return

    if len(k) != 1:
        print("Line",count,"is not able to be evaluated")
    else:
        print ('Line',count,'result is',k[0])
        return

    print('Line',count,'result is',k[0])

В данный момент вывод:

    Line 1 is not able to be evaluated
    Line 2 is not able to be evaluated
    Line 3 is not able to be evaluated
    Line 4 is not able to be evaluated

Ввод:

    295+*3-
    61*7-4*
    61*79-15*
    6a*7-b*
    623-+*-1

Ответы [ 3 ]

0 голосов
/ 30 июня 2019

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

def process(testline,count):

    k=[]

    for i in range(0,len(testline),1):
        if(testline[i].isdigit() == True):
            k.append(float(testline[i]))

        elif (testline[i]=='*'):
            if len(k) < 2:
                print("Line", count, "is not able to be evaluated. not enough operands")
                return
            x = k.pop()
            y = k.pop()
            ans = x * y
            k.append(ans)

        elif (testline[i]=='+'):
            if len(k) < 2:
                print("Line", count, "is not able to be evaluated. not enough operands")
                return
            x = k.pop()
            y = k.pop()
            ans = x + y
            k.append(ans)

        elif (testline[i]=='-'):
            if len(k) < 2:
                print("Line", count, "is not able to be evaluated. not enough operands")
                return
            x = k.pop()
            y = k.pop()
            ans = y - x    # << reversed operands
            k.append(ans)

        elif (testline[i]=='/'):
            if len(k) < 2:
                print("Line", count, "is not able to be evaluated. not enough operands")
                return
            x = k.pop()
            y = k.pop()
            ans = y / x   # << reversed operands
            k.append(ans)

        else:
            print("Line",count,"is not able to be evaluated")
            return

    if len(k) != 1:
        print("Line",count,"is not able to be evaluated")
        return

    print('Line',count,'result is',k[0])

С этим тестовым кодом:

lines = [
    '295+*3-',
    '61*7-4*',
    '61*79-15*',
    '6a*7-b*',
    '(-1)*2',
    '623-+*-1',
]

for i in range(len(lines)):
    process(lines[i], i + 1)

Результирующий вывод:

('Line', 1, 'result is', 25.0)
('Line', 2, 'result is', -4.0)
('Line', 3, 'is not able to be evaluated')
('Line', 4, 'is not able to be evaluated')
('Line', 5, 'is not able to be evaluated')
('Line', 6, 'is not able to be evaluated. not enough operands')
0 голосов
/ 30 июня 2019

Вот моя версия, которая очень похожа на секунду @ Tomrikoo, но дает полный ответ и решает несколько дополнительных проблем с исходным кодом.Этот код печатает либо результат, либо ошибку во всех случаях и имеет дело с конечным состоянием как в случае правильного ответа, так и в случае недопустимого условия стека (более одного элемента в стеке).Кроме того, я изменил порядок применения операндов, чтобы они были правильными (я предполагаю, что '42 / 'должен выдавать 2, а не 0,5, как все мои калькуляторы HP):

def process(testline, count):

    operations = {
        '+': lambda x, y: y + x,
        '-': lambda x, y: y - x,
        '*': lambda x, y: y * x,
        '/': lambda x, y: y / x,
    }

    k = []

    for c in testline:

        if c.isdigit():
            k.append(float(c))

        elif c in operations:
            if len(k) < 2:
                print("Line {}: bad expression '{}' (not enough operands)".format(count, testline))
                return
            k.append(operations[c](k.pop(), k.pop()))

        else:
            print("Line {}: unexpected character '{}' in expression '{}'".format(count, c, testline))
            return

    if len(k) != 1:
        print("Line {}: bad expression '{}' (too many operands)".format(count, testline))
    else:
        print("Line {}: Result: '{}' = {}".format(count, testline, k[0]))


lines = [
    '295+*3-',
    '61*7-4*',
    '61*79-15*',
    '6a*7-b*',
    '(-1)*2',
    '623-+*-1',
]

for i in range(len(lines)):
    process(lines[i], i + 1)

Вывод:

Line 1: Result: '295+*3-' = 25.0
Line 2: Result: '61*7-4*' = -4.0
Line 3: bad expression '61*79-15*' (too many operands)
Line 4: unexpected character 'a' in expression '6a*7-b*'
Line 5: unexpected character '(' in expression '(-1)*2'
Line 6: bad expression '623-+*-1' (not enough operands)
0 голосов
/ 30 июня 2019

Вы можете переместить ваши pop s в начало итерации и окружить их try/except, чтобы убедиться, что вы можете выдать:

for i in range(0,len(testline),1): 
    if(testline[i].isdigit() == True): 
        k.append(float(testline[i]))

    else:
        try:
            x = k.pop()
            y = k.pop()
        except IndexError:
            break

        if (testline[i]=='*'): 
            ans = x * y
            k.append(ans)

        elif (testline[i]=='+'):
            ans = x + y
            k.append(ans)

        elif (testline[i]=='-'):
            ans = x - y
            k.append(ans)

        elif (testline[i]=='/'):
            ans = x / y
            k.append(ans)

        else:
            print("Line",count,"is not able to be evaluated")
            return

Чтобы сделать его более надежным и не нужно добавлять лишние appends Я сделаю:

operators = {'*': lambda x ,y: x * y,
             '/': lambda x, y: x / y,
             '+': lambda x, y: x + y,
             '-': lambda x, y: x - y}

for c in testline:
    if c.isdigit(): 
        k.append(float(c))

    elif c in operators:
        try:
            x = k.pop()
            y = k.pop()
        except IndexError:
            break
        ans = operators[c](x, y)
        k.append(ans)

    else:
        print("Line",count,"is not able to be evaluated")
        return

РЕДАКТИРОВАТЬ: еще проще:

operators = {'*': lambda x ,y: x * y,
             '/': lambda x, y: x / y,
             '+': lambda x, y: x + y,
             '-': lambda x, y: x - y}

for c in testline:
    if c.isdigit(): 
        k.append(float(c))

    else:
        try:
            x = k.pop()
            y = k.pop()
            ans = operators[c](x, y)
            k.append(ans)
        except IndexError:  # Couldn't pop... (empty stack)
            break
        except KeyError:  # char is not a digit and not an operator
            print("Line",count,"is not able to be evaluated")
            return
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...