Python3:中间数字字符串到右数字字符串
Python3: Midnumeral Strings to Rightnumeral Strings
我的尝试:
m = str(input())
# m = list(m)
w = ""
r = ""
num = [int(i) for i in m.split() if i.isdigit()]
for c in range(0,len(m)-1):
if m[len(m)-1]:
for num in w:
if num.isnumeric():
w.remove(num)
num.join(r)
elif m[c].isalpha():
r.join(m[c])
elif m[c].isnumeric() and (len(w)==0 or w[c]=='('):
w.join(m[c])
elif len(num)!=0:
try:
if int(m[c])>int(w[c]):
w.join(m[c])
else:
n = [int(i) for i in w.split() if i.isdigit()]
if len(n)!=0:
r = ''.join([str(elem) for elem in w])
except:
continue
elif m[c]==')':
for number in m:
if number.isnumeric():
w+=number
elif number=='(':
m.remove('(')
m.remove(')')
break
elif (w[c]=='(') or ((int(w[c]))<(int(m[c]))) or (w=""): # In this statement it gives an invalid syntax error
w = m[c]
else:
break
print(r)
我想知道为什么在第 34 行(elif 语句)出现无效语法。
另外,想知道有没有更好的办法解决这个问题。
谢谢
问题:
中间数字字符串到右数字字符串
中间数字字符串是一个字符串,在字母之间包含一个数字。例如,a1b2c 是中间数字字符串。中间数字字符串可以包含字母 a 到 z、数字 1 到 9 以及左右括号。
右数字串是一个可以由中间数字串组成的字符串:
(i) 中间数字串中除左括号和右括号外的所有字符都出现在右数字串中。
(ii) 中间数字串中字母“a”和“b”之间的数字“n”将以特定方式出现在右边数字串中字母“a”和“b”的右侧。
(iii)中间数字串转换为右数字串的过程中,使用了等待流。
给定一个中间数字字符串“m”,它可以转换为右数字字符串“r”,如下所示:
i. 逐个字符处理中数字串‘m’.
ii. 当看到一个字母时,将其添加到右边的数字字符串“r”中。
iii. 当看到数字 'n' 且等待流为空或最近添加到等待流的字符是左括号时,然后将 'n' 添加到等待流
iv.如果看到一个数字'n'并且等待流中有一些数字那么,如果等待流中最近添加的数字小于'n'那么将'n'添加到等待流,否则从最近到最不最近处理等待流:-从等待流中删除数字并将其添加到'r'
重复第(i)部分,直到等待流中可用的最近值小于'n'或者等待流左括号最近的字符或者等待流变为空
v. 将‘n’添加到等待流
vi. 如果看到左括号,则将其添加到等待流
vii. 当看到右括号时,从等待流中删除从最近到最不最近的所有数字,并将其添加到 r 直到看到左括号。舍弃左右括号
viii. 当到达中间数字 'm' 字符串的末尾时,从等待流中删除从最近到最不最近的所有数字,并将其添加到右侧数字字符串 'r '
例如
a1b2c 将是 abc21
a2b1c 将是 ab2c1
(a1b)2c 将是 ab1c2
a1b4(c5d2e)7f 将是 abcd5e2f741
注意:中间数字中的所有字符将不同,只给出有效输入
输入格式
第一行包含中间数字字符串,m
输出格式
第一行应包含正确的数字字符串,r
.1 语法错误
很简单,缺少一个'='符号,所以把它改成这个
elif (w[c]=='(') or ((int(w[c]))<(int(m[c]))) or (w==""):
w = m[c]
else:
break
.2 代码改进和最佳实践
我建议您为此 post Code Review 上的答案,因为这是为了这个。错误很少,没有遵循最佳做法。
例如,这个错误块:
try:
if int(m[c])>int(w[c]):
w.join(m[c])
else:
n = [int(i) for i in w.split() if i.isdigit()]
if len(n)!=0:
r = ''.join([str(elem) for elem in w])
except:
continue
except 捕获了太多类型的错误,最好是:
try:
if int(m[c])>int(w[c]):
w.join(m[c])
else:
n = [int(i) for i in w.split() if i.isdigit()]
if len(n)!=0:
r = ''.join([str(elem) for elem in w])
except ValueError:
continue
查看 Should I always specify an exception type in except
statements? 了解更多相关信息。该 try 块中的 'logic' 也太多了。但为了简单起见,没关系。
编辑
考虑
请注意,我使用了不同的集合组合 ( accepted_numbers, accepted_chars, left_parenthesis, right_parenthesis)
而不是其他列表,这是因为集合在用于查找时速度超快,更多信息 --> Time complexity of python set operations?。而且也很清楚你想用它们做什么。
变量 r
是在算法期间将其用作 List
和 Then 的更好决定一个字符串,那是因为它更容易操作。
我什至没有使用 1 try except
块,这是因为,很清楚要做什么,我的意思是我们提前知道了,所以你可以用一个if else
块,除了我上面提到的关于 Try 块的内容外,另一个重要方面是如果发现和异常(在这段代码中它甚至无关紧要)会减慢代码速度,请看这里 try-except vs If in Python
您 post 编辑的算法问题使用并要求 Stack 作为集合,您可以在中看到它的实现process_waiting_stream()
函数
以 LIFO (last in, first out) 的方式。
process_waiting_stream()
回答测试一个案例
m = '(a1b)2c' # test string Added on the top as requested in the exercise
import string # If you don't want to import string, just hard code the letters
m = m
r = []
# ----- CONSTANTS
accepted_numbers = {str(i) for i in range(1, 10)} # 1 to 9
accepted_chars = {*string.ascii_lowercase}
left_parenthesis = '('
right_parenthesis = ')'
parenthesis = {left_parenthesis, right_parenthesis}
midnumeral_string = accepted_numbers | accepted_chars | parenthesis
# ---- NOTE: Run a quick check is Input is Correct |!(a1b)2c or (a1b)0c is not good
for char in m:
if char in midnumeral_string:
pass
else:
print('Input String is not a Midnumeral string')
continue
# ---------------------------
WAITING_STREAM = []
r = [] # Use a list, not a string, easier to work with :)
def process_waiting_stream():
global WAITING_STREAM
if WAITING_STREAM:
WAITING_STREAM.reverse() # LIFO from most recent to least recent
while True:
if not WAITING_STREAM:
break
item = WAITING_STREAM[0]
if item == left_parenthesis:
break
elif item in accepted_numbers:
item = WAITING_STREAM.pop(0)
r.append(item)
WAITING_STREAM.reverse()
def checK_stream(): # NOTE: We check this in case there is only '(' and not a num
return any([item in accepted_numbers for item in WAITING_STREAM])
for char in m:
if WAITING_STREAM:
recently_added = WAITING_STREAM[-1]
if char in accepted_chars:
r.append(char)
elif char in accepted_numbers:
if not WAITING_STREAM or recently_added == left_parenthesis:
WAITING_STREAM.append(char)
elif checK_stream():
if (recently_added not in parenthesis
and recently_added not in accepted_chars) and int(recently_added) < int(char):
WAITING_STREAM.append(char)
else:
process_waiting_stream()
WAITING_STREAM.append(char)
else:
WAITING_STREAM.append(char)
elif char == left_parenthesis:
WAITING_STREAM.append(char)
elif char == right_parenthesis:
process_waiting_stream()
for item in WAITING_STREAM:
if item == left_parenthesis:
left_para = WAITING_STREAM.index(left_parenthesis)
WAITING_STREAM.pop(left_para)
break
process_waiting_stream()
r = ''.join(r)
print(r)
答案 2
测试所有案例
import string # If you don't want to import string, just hard code the letters
def rightnumeral_string(m):
# ----- CONSTANTS
accepted_numbers = {str(i) for i in range(1, 10)} # 1 to 9
accepted_chars = {*string.ascii_lowercase}
left_parenthesis = '('
right_parenthesis = ')'
parenthesis = {left_parenthesis, right_parenthesis}
midnumeral_string = accepted_numbers | accepted_chars | parenthesis
# ---- NOTE: Run a quick check is Input is Correct |!(a1b)2c or (a1b)0c is not good
for char in m:
if char in midnumeral_string:
pass
else:
print('Input String is not a Midnumeral string')
continue
# ---------------------------
WAITING_STREAM = []
r = [] # Use a list, not a string, easier to work with :)
def process_waiting_stream():
nonlocal WAITING_STREAM
if WAITING_STREAM:
WAITING_STREAM.reverse() # LIFO from most recent to least recent
while True:
if not WAITING_STREAM:
break
item = WAITING_STREAM[0]
if item == left_parenthesis:
break
elif item in accepted_numbers:
item = WAITING_STREAM.pop(0)
r.append(item)
WAITING_STREAM.reverse()
def checK_stream(): # NOTE: We check this in case there is only '(' and not a num
return any([item in accepted_numbers for item in WAITING_STREAM])
# ------ Iterate Through each Character (number included) in the string
for char in m:
if WAITING_STREAM:
recently_added = WAITING_STREAM[-1]
if char in accepted_chars:
r.append(char)
elif char in accepted_numbers:
if not WAITING_STREAM or recently_added == left_parenthesis:
WAITING_STREAM.append(char)
elif checK_stream(): # Check if there are currently nums in stream
if (recently_added not in parenthesis
and recently_added not in accepted_chars) and int(recently_added) < int(char):
WAITING_STREAM.append(char)
else:
process_waiting_stream()
WAITING_STREAM.append(char)
else:
WAITING_STREAM.append(char)
elif char == left_parenthesis:
WAITING_STREAM.append(char)
elif char == right_parenthesis:
process_waiting_stream()
# Last Step is to Remove left_parenthesis
for item in WAITING_STREAM:
if item == left_parenthesis:
left_para = WAITING_STREAM.index(left_parenthesis)
WAITING_STREAM.pop(left_para)
break
process_waiting_stream()
r = ''.join(r)
return r
print(rightnumeral_string('a1b2c'))
print(rightnumeral_string('a2b1c'))
print(rightnumeral_string('(a1b)2c'))
print(rightnumeral_string('a1b4(c5d2e)7f'))
# Checking if the Answer Are correct
assert rightnumeral_string('a1b2c') == 'abc21'
assert rightnumeral_string('a2b1c') == 'ab2c1'
assert rightnumeral_string('(a1b)2c') == 'ab1c2'
assert rightnumeral_string('a1b4(c5d2e)7f') == 'abcd5e2f741'
文档
- string
- Iterating each character in a string using Python
- What is the use of “assert” in Python?
我的尝试:
m = str(input())
# m = list(m)
w = ""
r = ""
num = [int(i) for i in m.split() if i.isdigit()]
for c in range(0,len(m)-1):
if m[len(m)-1]:
for num in w:
if num.isnumeric():
w.remove(num)
num.join(r)
elif m[c].isalpha():
r.join(m[c])
elif m[c].isnumeric() and (len(w)==0 or w[c]=='('):
w.join(m[c])
elif len(num)!=0:
try:
if int(m[c])>int(w[c]):
w.join(m[c])
else:
n = [int(i) for i in w.split() if i.isdigit()]
if len(n)!=0:
r = ''.join([str(elem) for elem in w])
except:
continue
elif m[c]==')':
for number in m:
if number.isnumeric():
w+=number
elif number=='(':
m.remove('(')
m.remove(')')
break
elif (w[c]=='(') or ((int(w[c]))<(int(m[c]))) or (w=""): # In this statement it gives an invalid syntax error
w = m[c]
else:
break
print(r)
我想知道为什么在第 34 行(elif 语句)出现无效语法。 另外,想知道有没有更好的办法解决这个问题。
谢谢
问题:
中间数字字符串到右数字字符串
中间数字字符串是一个字符串,在字母之间包含一个数字。例如,a1b2c 是中间数字字符串。中间数字字符串可以包含字母 a 到 z、数字 1 到 9 以及左右括号。
右数字串是一个可以由中间数字串组成的字符串: (i) 中间数字串中除左括号和右括号外的所有字符都出现在右数字串中。 (ii) 中间数字串中字母“a”和“b”之间的数字“n”将以特定方式出现在右边数字串中字母“a”和“b”的右侧。 (iii)中间数字串转换为右数字串的过程中,使用了等待流。
给定一个中间数字字符串“m”,它可以转换为右数字字符串“r”,如下所示:
i. 逐个字符处理中数字串‘m’.
ii. 当看到一个字母时,将其添加到右边的数字字符串“r”中。
iii. 当看到数字 'n' 且等待流为空或最近添加到等待流的字符是左括号时,然后将 'n' 添加到等待流
iv.如果看到一个数字'n'并且等待流中有一些数字那么,如果等待流中最近添加的数字小于'n'那么将'n'添加到等待流,否则从最近到最不最近处理等待流:-从等待流中删除数字并将其添加到'r'
重复第(i)部分,直到等待流中可用的最近值小于'n'或者等待流左括号最近的字符或者等待流变为空
v. 将‘n’添加到等待流
vi. 如果看到左括号,则将其添加到等待流
vii. 当看到右括号时,从等待流中删除从最近到最不最近的所有数字,并将其添加到 r 直到看到左括号。舍弃左右括号
viii. 当到达中间数字 'm' 字符串的末尾时,从等待流中删除从最近到最不最近的所有数字,并将其添加到右侧数字字符串 'r '
例如
a1b2c 将是 abc21
a2b1c 将是 ab2c1
(a1b)2c 将是 ab1c2
a1b4(c5d2e)7f 将是 abcd5e2f741
注意:中间数字中的所有字符将不同,只给出有效输入
输入格式
第一行包含中间数字字符串,m
输出格式
第一行应包含正确的数字字符串,r
.1 语法错误
很简单,缺少一个'='符号,所以把它改成这个
elif (w[c]=='(') or ((int(w[c]))<(int(m[c]))) or (w==""):
w = m[c]
else:
break
.2 代码改进和最佳实践
我建议您为此 post Code Review 上的答案,因为这是为了这个。错误很少,没有遵循最佳做法。
例如,这个错误块:
try:
if int(m[c])>int(w[c]):
w.join(m[c])
else:
n = [int(i) for i in w.split() if i.isdigit()]
if len(n)!=0:
r = ''.join([str(elem) for elem in w])
except:
continue
except 捕获了太多类型的错误,最好是:
try:
if int(m[c])>int(w[c]):
w.join(m[c])
else:
n = [int(i) for i in w.split() if i.isdigit()]
if len(n)!=0:
r = ''.join([str(elem) for elem in w])
except ValueError:
continue
查看 Should I always specify an exception type in except
statements? 了解更多相关信息。该 try 块中的 'logic' 也太多了。但为了简单起见,没关系。
编辑
考虑
请注意,我使用了不同的集合组合
( accepted_numbers, accepted_chars, left_parenthesis, right_parenthesis)
而不是其他列表,这是因为集合在用于查找时速度超快,更多信息 --> Time complexity of python set operations?。而且也很清楚你想用它们做什么。变量
r
是在算法期间将其用作List
和 Then 的更好决定一个字符串,那是因为它更容易操作。我什至没有使用 1
try except
块,这是因为,很清楚要做什么,我的意思是我们提前知道了,所以你可以用一个if else
块,除了我上面提到的关于 Try 块的内容外,另一个重要方面是如果发现和异常(在这段代码中它甚至无关紧要)会减慢代码速度,请看这里 try-except vs If in Python您 post 编辑的算法问题使用并要求 Stack 作为集合,您可以在中看到它的实现
process_waiting_stream()
函数 以 LIFO (last in, first out) 的方式。
process_waiting_stream()
回答测试一个案例
m = '(a1b)2c' # test string Added on the top as requested in the exercise
import string # If you don't want to import string, just hard code the letters
m = m
r = []
# ----- CONSTANTS
accepted_numbers = {str(i) for i in range(1, 10)} # 1 to 9
accepted_chars = {*string.ascii_lowercase}
left_parenthesis = '('
right_parenthesis = ')'
parenthesis = {left_parenthesis, right_parenthesis}
midnumeral_string = accepted_numbers | accepted_chars | parenthesis
# ---- NOTE: Run a quick check is Input is Correct |!(a1b)2c or (a1b)0c is not good
for char in m:
if char in midnumeral_string:
pass
else:
print('Input String is not a Midnumeral string')
continue
# ---------------------------
WAITING_STREAM = []
r = [] # Use a list, not a string, easier to work with :)
def process_waiting_stream():
global WAITING_STREAM
if WAITING_STREAM:
WAITING_STREAM.reverse() # LIFO from most recent to least recent
while True:
if not WAITING_STREAM:
break
item = WAITING_STREAM[0]
if item == left_parenthesis:
break
elif item in accepted_numbers:
item = WAITING_STREAM.pop(0)
r.append(item)
WAITING_STREAM.reverse()
def checK_stream(): # NOTE: We check this in case there is only '(' and not a num
return any([item in accepted_numbers for item in WAITING_STREAM])
for char in m:
if WAITING_STREAM:
recently_added = WAITING_STREAM[-1]
if char in accepted_chars:
r.append(char)
elif char in accepted_numbers:
if not WAITING_STREAM or recently_added == left_parenthesis:
WAITING_STREAM.append(char)
elif checK_stream():
if (recently_added not in parenthesis
and recently_added not in accepted_chars) and int(recently_added) < int(char):
WAITING_STREAM.append(char)
else:
process_waiting_stream()
WAITING_STREAM.append(char)
else:
WAITING_STREAM.append(char)
elif char == left_parenthesis:
WAITING_STREAM.append(char)
elif char == right_parenthesis:
process_waiting_stream()
for item in WAITING_STREAM:
if item == left_parenthesis:
left_para = WAITING_STREAM.index(left_parenthesis)
WAITING_STREAM.pop(left_para)
break
process_waiting_stream()
r = ''.join(r)
print(r)
答案 2
测试所有案例
import string # If you don't want to import string, just hard code the letters
def rightnumeral_string(m):
# ----- CONSTANTS
accepted_numbers = {str(i) for i in range(1, 10)} # 1 to 9
accepted_chars = {*string.ascii_lowercase}
left_parenthesis = '('
right_parenthesis = ')'
parenthesis = {left_parenthesis, right_parenthesis}
midnumeral_string = accepted_numbers | accepted_chars | parenthesis
# ---- NOTE: Run a quick check is Input is Correct |!(a1b)2c or (a1b)0c is not good
for char in m:
if char in midnumeral_string:
pass
else:
print('Input String is not a Midnumeral string')
continue
# ---------------------------
WAITING_STREAM = []
r = [] # Use a list, not a string, easier to work with :)
def process_waiting_stream():
nonlocal WAITING_STREAM
if WAITING_STREAM:
WAITING_STREAM.reverse() # LIFO from most recent to least recent
while True:
if not WAITING_STREAM:
break
item = WAITING_STREAM[0]
if item == left_parenthesis:
break
elif item in accepted_numbers:
item = WAITING_STREAM.pop(0)
r.append(item)
WAITING_STREAM.reverse()
def checK_stream(): # NOTE: We check this in case there is only '(' and not a num
return any([item in accepted_numbers for item in WAITING_STREAM])
# ------ Iterate Through each Character (number included) in the string
for char in m:
if WAITING_STREAM:
recently_added = WAITING_STREAM[-1]
if char in accepted_chars:
r.append(char)
elif char in accepted_numbers:
if not WAITING_STREAM or recently_added == left_parenthesis:
WAITING_STREAM.append(char)
elif checK_stream(): # Check if there are currently nums in stream
if (recently_added not in parenthesis
and recently_added not in accepted_chars) and int(recently_added) < int(char):
WAITING_STREAM.append(char)
else:
process_waiting_stream()
WAITING_STREAM.append(char)
else:
WAITING_STREAM.append(char)
elif char == left_parenthesis:
WAITING_STREAM.append(char)
elif char == right_parenthesis:
process_waiting_stream()
# Last Step is to Remove left_parenthesis
for item in WAITING_STREAM:
if item == left_parenthesis:
left_para = WAITING_STREAM.index(left_parenthesis)
WAITING_STREAM.pop(left_para)
break
process_waiting_stream()
r = ''.join(r)
return r
print(rightnumeral_string('a1b2c'))
print(rightnumeral_string('a2b1c'))
print(rightnumeral_string('(a1b)2c'))
print(rightnumeral_string('a1b4(c5d2e)7f'))
# Checking if the Answer Are correct
assert rightnumeral_string('a1b2c') == 'abc21'
assert rightnumeral_string('a2b1c') == 'ab2c1'
assert rightnumeral_string('(a1b)2c') == 'ab1c2'
assert rightnumeral_string('a1b4(c5d2e)7f') == 'abcd5e2f741'
文档
- string
- Iterating each character in a string using Python
- What is the use of “assert” in Python?