Поиск распределяемой последовательности в строке по порядку - PullRequest
0 голосов
/ 14 января 2019

Есть ли способ поиска последовательности по порядку (которая не является непрерывной во входных данных) в строке в одной команде или коротком блоке?

Я приведу пример проблемы:

Я генерирую строку из raw_input в форме (+ or - or void)(number or void)X^2 (+ or -) (+ or - or void)X (+ or -) (+ or - or void)(number), и я хочу назначить флаг для (-+)aX^2 +- (-+)bX +- (+-)c и флаг только для c и флаг только для b ... только b и c, только a и c и т. Д. В любом порядке ввода (abc, cba, ac, cb, etc) путем определения поиска по символам "x^2", "x" "число" и присвоения каждому порядку флага ...

Можно ли это сделать без написания 300+ строк с тоннами if с и elif с? (Я разочаровался в строке 107).

Я пробовал долгий мучительный путь:

def sorting_abc():
    polinput = raw_input("insert a pol.: ")  # input as string
    a = 0
    b = 0
    c = 0
    temp = [] * 5

    splinput = polinput.split() #splitted string input
    lensplin = len(splinput)  #Length of splinput
    temp = splinput

    flag_1var = bool(lensplin == 1)
    flag_2var = bool(lensplin == 3)
    flag_3var = bool(lensplin == 5)
    flag_minusplus = bool(temp[1] == '-' and temp[3] == '+')
    flag_plusminus = bool(temp[1] == '+' and temp[3] == '-')
    flag_minusminus = bool(temp[1] == '-' and temp[3] == '-')
    flag_plusplus = bool(temp[1] == '+' and temp[3] == '+')
    flag_2var_minus = bool(splinput <= 3 and temp[1] == '-')
    flag_2var_plus = bool(splinput <= 3 and temp[1] == '+')

    if (flag_1var):
        p1 = tamp[0]
        p1i = p1.find('x^2')
        a = p1[:p1i:]
        if (a == ''):
            a = 1
        if (a == '-'):
            a = -1
        a = int(a)

    if (flag_2var):
        p1 = temp[0]
        p2 = temp[1]
        p3 = temp[2]
        if ('x^2' in p1):
            p1i = p1.find('x^2')
            a = p1[:p1i:]
            if (a == ''):
                a = 1
            if (a == '-'):
                a = -1
            c = p3
            if (p3 == '-'):
                c -= int(c)
        if ('x^2' in p3):
            p3i = p3.find('x^2')
            a = p3[:p3i:]
            if (a == ''):
                a = 1
            if (p2 == '-'):
                a -= int(a)
            c = p1

    if (flag_3var):
        p1 = temp[0]
        p2 = temp[1]
        p3 = temp[2]
        p4 = temp[3]
        p5 = temp[4]
        if ('x^2' in p1):
            p1i = p1.find('x^2')
            a = p1[:p1i:]
            if (a == ''):
                a = 1
            if (a == '-'):
                a = -1
            if ('x' in p3):
                p3i = p3.find('x')
                b = p3[:p3i:]
                if (b == ''):
                    b = 1
                if (p2 == '-'):
                    b -= int(b)
                c = p5
                if (p4 == '-'):
                    c -= int(c)
            if ('x' in p5):
                p5i = p5.find('x')
                b = p5[:p5i:]
                if (b == ''):
                    b = 1
                if (p4 == '-'):
                    b -= int(b)
                if (p2 == '-'):
                    c -= int(c)
                c = p3
        elif ('x^2' in p3):
            p3i = p3.find('x^2')
            a = p3[:p3i:]
            if (a == ''):

Есть ли шанс значительно сократить это?

Ответы [ 2 ]

0 голосов
/ 14 января 2019

Вы можете сделать это с помощью регулярных выражений , если хотите. Преимущество такого подхода состоит в том, что вы будете знать, совпадает ли ваш ввод немедленно, и каковы все элементы, когда вы запрашиваете объект сопоставления.

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

Результатом будет словарь с индексом экспоненты (0 для постоянного члена), со значением общего коэффициента aa. Приведенное здесь регулярное выражение основано на шаблоне сопоставления чисел, взятых из этого ответа до этого вопроса :

import re
from collections import defaultdict

string = '-12.5e-1 x^3 + -5 x^2 --0.5x +-0.75x^3 +6'

number = r'[-+]?(?:(?:\d*\.\d+)|(?:\d+\.?))(?:[Ee][+-]?\d+)?'
pattern = re.compile(fr'\s*([+-])\s*({number})\s*(x(\^\d+)?)?')

coefficients = defaultdict(int)
# prepend a + to avoid special-casing the first term
string = '+' + string.rstrip()
while string:
    match = pattern.match(string)
    if not match:
        raise ValueError(f'Invalid input starting with {string}')
    sign = 1 if match.group(1) == '+' else -1
    coefficient = sign * float(match.group(2))
    if match.group(3):
        exp = match.group(4)
        exp = 1 if exp is None else int(exp[1:])
    else:
        exp = 0
    coefficients[exp] += coefficient
    string = string[match.end():]

Для примера string, получившиеся coefficients равны

defaultdict(<class 'int'>, {0: 6.0, 1: 0.5, 2: -5.0, 3: -2.0})

Вот ссылка UDEOne: https://ideone.com/TwtY2e

0 голосов
/ 14 января 2019

Я бы подошел к этому так:

  1. удалить все пробелы из вашей входной строки.
  2. применить 'все прописные буквы' или 'все строчные буквы' к вашей входной строке.
  3. разбить вашу строку на список, используя символы + или - (оба) в качестве разделителей. Для этого, Google 'разбивает строки с помощью регулярных выражений' или отметьте это post .
  4. используя цикл, для каждого из элементов списка удалите скобки, если они существуют.
  5. используя цикл, для каждого из элементов списка проверьте, содержат ли они X^2, X или нет (используя X в верхнем или нижнем регистре в зависимости от вашего предыдущего выбора).

Вы можете объединить 4. и 5. в одном цикле, если хотите.

Это должно дать вам необходимый ответ с относительно коротким, гибким, многократно используемым кодом. Надеюсь, это поможет.

Примечание: редактирование выполнено после просмотра примера ввода.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...