-1

I'm trying to augment a lengthy string that can contain multiple number of digits (0,1,2,3,4,5,6,?) Consider a string "000000000004?0??100001??2?0?10000000". I'm trying to replace all the question marks (?) by the neighbouring largest digit. The comparison should be done from both left character and right character to the question mark (?).

Input String: "000000000004?0??100001??2?0?10000000" Output String: "000000000004401110000122220110000000"

I wrote a function that ends up replacing them during the first iteration of the loop itself which results in replacing the ? by the highest number i.e, 4 in this case. Check the code snippet below.

Wrong Output: "000000000004404410000144240410000000"

def method_augment(aug_str):
    global pos_of_sec_char, sec_char, preced_char
    flag_marks_string_end = 0
    list_predef = ['0', '1', '2', '3', '4', '5', '6']
    len_aug_str = len(aug_str)
    for m in range(0, (len_aug_str - 1)):
        if aug_str[m] == '?':
            pos_of_first_ques = m
            if m != 0:
                preced_char = aug_str[m - 1]
                # print("preced char:", preced_char)
                for n in range((pos_of_first_ques + 1), (len_aug_str - 1)): 
                    if aug_str[n] in list_predef:
                        pos_of_sec_char = n
                        sec_char = aug_str[n]
                        print(sec_char)
                        if preced_char > sec_char:
                            aug_str = aug_str.replace(aug_str[pos_of_first_ques], preced_char)
                            del preced_char, sec_char, pos_of_first_ques, m
                        else:
                            aug_str = aug_str.replace(aug_str[pos_of_first_ques], sec_char)
                            del preced_char, sec_char, pos_of_first_ques
                        break
                    else:
                        flag_marks_string_end += 1

            else:
                for q in range((pos_of_first_ques + 1), (len_aug_str - 1)):
                    if aug_str[q] in list_predef:
                        pos_of_sec_char = q
                        sec_char = aug_str[q]
                        aug_str = aug_str.replace(aug_str[pos_of_first_ques], sec_char)
                        break
            # if preced_char > sec_char:
            #     aug_str = aug_str.replace(aug_str[m], preced_char)
            # else:
            #     aug_str = aug_str.replace(aug_str[m], sec_char)

        else:
            continue

    return aug_str


Input String: "000000000004?0??100001??2?0?10000000"

Expected Output String: "000000000004401110000122220110000000"

Actual Output String: "000000000004404410000144240410000000"

There are multiple strings like this with different combinations of digit and ?. I hope I have explained it well. Please help. Thanks.

4

3 回答 3

0

您的程序听起来过于复杂。我什至没有试图理解。你能读懂并理解这个吗?

import re


def method_augment(text: str) -> str:
    while "?" in text:
        text = replacesingle("0" + text + "0")[1:-1]   # consider starting and ending question marks
    return text


def replacesingle(text: str) -> str:
    match = re.search("\\d\\?+\\d", text)
    span = match.span(0)
    partialtext = text[span[0]:span[1]]
    left = int(partialtext[0])
    right = int(partialtext[-1])
    larger = left if left > right else right
    number_of_question_marks = len(partialtext) - 2
    text = text[:span[0] + 1] + str(larger) * number_of_question_marks + text[span[1] - 1:]
    return text


assert(method_augment("000000000004?0??100001??2?0?10000000") == "000000000004401110000122220110000000")
assert (method_augment("??123??1??") == "1112333111")
于 2019-04-07T12:57:34.900 回答
0

Here is a way to do it, with some tests:

def replace_with_largest(s):
    out = []
    last_left = None
    next_right = None
    for i, c in enumerate(s):
        if c in '0123456789':
            out.append(c)
            last_left = c
            next_right = None # now the next digit to the right is unknown
            continue

        # Now we have a '?'.
        # We need the next digit to the right
        if next_right is None:
            for j in range(i+1, len(s)):
                if s[j] != '?':
                    next_right = s[j]
                    break
            else:
                # No more digit right of here, we'll use the last one on the left
                next_right = last_left

        out.append(max(last_left, next_right) if last_left is not None else next_right)    

    return ''.join(out)

The tests, some strings and the expected output:

tests = [("000000000004?0??100001??2?0?10000000", "000000000004401110000122220110000000"),
         ("??123??1", "11123331"),
         ("123???", "123333")]


for test in tests:
    print(test[0], replace_with_largest(test[0]), replace_with_largest(test[0]) == test[1])

000000000004?0??100001??2?0?10000000 000000000004401110000122220110000000 True
??123??1 11123331 True
123??? 123333 True
于 2019-04-07T12:59:41.650 回答
0

我不确定这有多有效,但是您可以拆分列表,以便保留?s 的所有连续值并作为单独的元素一起保留,用前导和尾随字符填充该列表,与max数字或?s (并且也使访问索引更加方便),例如:

import re

def augment(text):    
    w = [' ', *[el for el in re.split(r'(\?+)', text) if el], ' ']
    for i in range(1, len(w) - 1):
        w[i] = w[i].replace('?', max(w[i - 1][-1], w[i + 1][0]))
    return ''.join(w[1:-1]).strip() or None

然后使用它,例如:

cases = [
    '000000000004?0??100001??2?0?10000000',
    '?????????9',
    '9????????0',
    '0????????9',
    '?0???????9',
    '123???????',
    '12?????321',
    '??????????',
]

for case in cases:
    print(case, '->', augment(case))

这给了你:

000000000004?0??100001??2?0?10000000 -> 000000000004401110000122220110000000
?????????9 -> 9999999999
9????????0 -> 9999999990
0????????9 -> 0999999999
?0???????9 -> 0099999999
123??????? -> 1233333333
12?????321 -> 1233333321
?????????? -> None
于 2019-04-07T13:39:11.737 回答