终于把转调器做出来了,上个学期还觉得这是个遥不可及的事物,因为涉及到一些括号、字符空格的处理,便觉得非常头疼,但这次一点点把逻辑整出来,渐渐得可以实现了。
一、转调的逻辑实现
(一)困难罗列:
难题当然有很多啦,这里按照解决难度分成三类:
难度C:
难度等级 | 问题 |
---|---|
C | 1、转调括号的中英文差异; 2、处理无效的#; |
B | 1、如何将#1视为一个整体进行转调 2、空格的有效、无效判断问题; 3、用什么方式对音符进行替换 |
A | 1、括号多余、缺失问题; 2、转调后括号处理问题; |
还有很多细节问题,就不一一罗列了(也忘得差不多了) 。
(二)解决逻辑
下面用字母+数字表示具体问题,如C1表示转调括号的中英文差异
对于C1,用字符串的replace函数,统一将中文括号【】()转成英文括号就ok了。
对于C2,如果#后面的下一个字符是数字1-7(如果下一个字符是空格,则继续推后,以此类推),则#有效,保留在字符串中,如果后面不是数字1-7,则删掉。
对于B1,由于输入的是字符串,先用程序将#1切成一片,然后将整个字符串转成列表,列表中的每一个元素有这些类型:括号的一半、空格、#数字、数字、无意义字符,方便接下来处理
对于B2,对空格的处理要分为转调前的处理和转调后处理,具体解决看代码(其实是忘了)
对于B3,这里有几个方案:
方案一:括号里面的和括号外面的分别写两个函数进行处理,如12(23)2,12一个函数处理,然后检测到括号,调用函数处理,最后处理2的转调,但感觉很困难,在识别括号范围就是个难题,如果出现括号之中又出现括号,又调用一次函数,这样会造成递归,想想还是算了(可以实现,但我不能)
方案二:用索引的方法,给出字符串,在小括号里面的索引是-1,大括号里是1,遇到‘(’和‘】’就-1,遇到‘)’和‘【’就+1,没遇到括号就保持0,如12(12)【23】的索引值是00-1-1-101110,然后根据索引值给原字符串(这时转成列表了)进行括号的转变,变成12(1)(2)【2】【3】(括号已经被删掉),可以转调了,这里又有个问题,就是有时会出现((2))这样的列表元素,所以我们无视括号,将2进行转调,然后将转调结果补上两小括号。之后的事情又是对括号的处理了。
对于A1,处理规则每个人都不同,我这里重视左括号,轻视右括号,即有多余的左括号补上右括号,有多余的右括号就删掉右括号,实际处理更加复杂,详情看代码。
对于A2,就是接着B3来的,B3会出现这样的结果(2)(3),为了美观,我们要将其转成(23),为了偷懒,这部完全可以不做,但有时会出现(【2】)这样的东西,混淆视听,这里的处理方法还是索引的方法。
总的来说,解决思路就是用find和re方法找到位置,增删补改,然后在字符串和列表中反复横跳,来处理转调前后括号的遗留问题,其实都是非常基础的。
三、代码实现
本来想用下class方法的,可惜……
#change.py
import re
syllable = ['(1)','(#1)','(2)','(#2)','(3)','(4)','(#4)','(5)',\
'(#5)','(6)','(#6)','(7)','1','#1','2','#2','3','4',\
'#4','5','#5','6','#6','7','[1]','[#1]','[2]','[#2]'\
,'[3]','[4]','[#4]','[5]','[#5]','[6]','[#6]','[7]']
####################################
#
#预处理,将输入转换成可识别的状态
#
###################################
def Pretreatment(talk):
#将中文括号转换成英文
talk = talk.replace('(','(')
talk = talk.replace('【','[')
talk = talk.replace(')',')')
talk = talk.replace('】',']')
#将错误的括号转成正确的
index1 = 0
index2 = 0
while((talk.find('(',index1) != -1) or (talk.find(')',index2) != -1)):
index1_temp = talk.find('(',index1)
index2_temp = talk.find(')',index2)
#print(index1_temp,index2_temp)
if index1_temp<index2_temp:#左括号位置比右括号前
if index1_temp == -1:#如果左括号不存在
talk = talk[0:index2_temp] + talk[(index2_temp+1):len(talk)]
else:#一对标准的括号
index1 = index1_temp + 1
index2 = index2_temp + 1
elif index1_temp>index2_temp:
if index2_temp == -1:#右括号不存在
talk = talk + ')'
index2 = len(talk) -1
index1 = index1 + 1
else:#右括号在左括号前面
talk = talk[0:index2_temp] + talk[(index2_temp+1):len(talk)]
index1 = index1_temp - 1
while(talk.find('()',0) != -1):
talk = talk.replace('()','')
#处理中括号
index1 = 0
index2 = 0
while((talk.find('[',index1) != -1) or