这个作业属于哪个课程 | https://edu.cnblogs.com/campus/fzzcxy/SE |
---|---|
这个作业要求在哪里 | https://edu.cnblogs.com/campus/fzzcxy/SE/homework/10283 |
这个作业的目标 | 1、用汉字实现编程 2、新建一个github仓库,并把作业推送到该仓库 3、写一篇随笔 |
作业正文 | 如下 |
其他参考文献 | https://blog.csdn.net/MilkHathaway/article/details/78859058 |
github仓库地址 | https://github.com/crush-w/crush |
前期准备
- 拿到题目后,为了便于理解,先从一个样例入手,进行了中文与编程语句的转换,如下:
- 准备开始写代码,首先选择语言,鉴于大三上学期接触最多的语言是python,在这里我选择用python完成该编程。
第一次编写:思考与分析
- 首先要解决输入问题,python中使用input进行输入,input一次输入一行。为了提取每一个词语,使用split函数,以空格作为分隔符完成词语的分离
- 在第一次编写时,我只提取了图中框出来的①~⑩个词语,分别代入相应的定义函数中去处理。
- def get_type:处理“整数”,即变量类型,实现类型可变。
- 字典dic_num:把所有中文数字转化成阿拉伯数字,仅限0~10
- def get_lastnum:完成算数运算,判断加减法
- def judge:“大于”的处理,提取需要输出的字符串
- def get_change:将完成一系列处理后的值从阿拉伯数字再转为中文数字
- def main:主函数,完成输入及词语的分离,代入指定的定义函数
第一次编写:完整代码
dic_num = {
'零':0,
'一':1,
'二':2,
'三':3,
'四':4,
'五':5,
'六':6,
'七':7,
'八':8,
'九':9,
'十':10
}
def get_type(ty_pe,x):
if ty_pe == '整数':
x = int(x)
elif ty_pe == '浮点数':
x = float(x)
return x
def get_lastnum(n,sym,num):
if sym == '增加':
n = n+num
elif sym == '减少':
n = n-num
return n
def get_change(n):
for key in dic_num:
if n == dic_num[key]:
return key
def judge(n,jd_sym,jd_num,word1,word2):
word1=word1.strip('“”') #去除双引号
word2=word2.strip('“”')
if jd_sym == '大于':
if n > jd_num:
print(word1)
else:
print(word2)
def main():
s1 = input()
s2 = input()
s3 = input()
s4 = input()
s5 = input()
ty_pe=s1.split(' ')[0]#获取变量类型
num=s1.split(' ')[3] #提取原始数据值
t = dic_num[num] #通过字典实现数字转化
t = get_type(ty_pe,t) #类型转化
sym2=s2.split(' ')[1] #拆分提取运算符号
num2=s2.split(' ')[2] #拆分提取运算数字
t2 = dic_num[num2] #数字转化
t = get_lastnum(t,sym2,t2) #进行运算
sym3=s3.split(' ')[1]#拆分提取运算符号
num3=s3.split(' ')[2] #拆分提取运算数字
t3 = dic_num[num3] #数字转化
t = get_lastnum(t,sym3,t3) #进行运算
jd_sym = s5.split(' ')[2] #提取判断符号
jd_num=s5.split(' ')[3] #提取判断数字
jd_num = dic_num[jd_num] #数字转化
word1=s5.split(' ')[6] #获得句子1
word2=s5.split(' ')[9] #获得句子2
print(get_change(t)) #将阿拉伯数字转化为汉字
judge(t,jd_sym,jd_num,word1,word2) #判断
if __name__=='__main__':
main()
第一次编写:样例运行
第二次编写:思考与分析
基于第一次编写的思路,首先给五条(默认固定5条句子)语句定性:赋值语句,运算语句、判断语句及输出语句。
- 赋值语句:
- def get_str:分离输入语句中的各个词语,存入列表
- def get_def:处理赋值语句
- def judge_type:判断是否有关于变量类型的词语,判断是否是赋值语句
- def get_num:将汉字数字转化为阿拉伯数字
- def get_type:对转化后的阿拉伯数字进行类型转换
- 在主函数中,判断赋值语句的个数从而确定变量的个数,后续处理分为两种情况:一个变量和两个变量
- 一个变量:
- 运算语句(def get_lastnum):调用def get_num实现数字转换后,判断加减法,进行算术运算
- 判断语句(def compare1):实现数字转换,提取需输出的字符串存入列表、判断“大于”后输出
- 输出语句(def print_num):把需要输出的数字,从阿拉伯数字转化为汉字数字
- 主函数:通过正则表达式,对输出语句进行识别,实现输出语句和判断语句的顺序可调换
- 两个变量:
- 运算语句:在主函数中,对运算对象进行一个识别,判断参与运算的是变量1还是变量2,后把相应变量传入get_lastnum函数进行运算
- 判断语句:
- 主函数中,基于对运算语句的处理再对判断语句中的两个变量进行区分(比较量、运算量),排列组合后有8种结果,分别列举。
- def compare2:实现汉数字转阿拉伯数字,识别“大于”后通过改变f来判断后续的运算是否进行
- 输出语句:与一个变量相同
第二次编写:完整代码
import re
dic_num = {
'零':0,
'一':1,
'二':2,
'三':3,
'四':4,
'五':5,
'六':6,
'七':7,
'八':8,
'九':9,
'十':10
}
#分离每一行中的每一个变量
def get_str(s1):
s2=[]
s2=s1.split(' ')
return s2
#通过字典实现数字转化(中文数字——>阿拉伯数字)
def get_num(num):
n = dic_num[num]
return n
#判断赋值语句(通过整数,浮点数等变量类型进行识别)
def judge_type(ty_pe):
result = re.match('[整数浮点数]',ty_pe)
if result is not None:
return 1
else:
return 0
#变量类型转化
def get_type(ty_pe,x):
if ty_pe == '整数':
x = int(x)
elif ty_pe == '浮点数':
x = float(x)
return x
#识别赋值语句,实现汉字转数字、类型转化
def get_def(arr):
f = 0
for a in arr:
#print(a)
if judge_type(a) == 1:
f = judge_type(a)
ty_pe = a
if f == 1:
result = re.match('[零一二三四五六七八九十]',a)
if result is not None:
x = get_num(a) #汉字转数字
x = get_type(ty_pe,x) #类型转化
return x
else:
return None
#算术运算(仅限加减)
def get_lastnum(n,arr):
for a in arr:
result = re.match('[零一二三四五六七八九十]',a)
if result is not None:
num = get_num(a) #汉字转数字
for a in arr:
if a == '增加':
n = n+num
elif a == '减少':
n = n-num
return n;
#通过字典实现数字转化数字转化(阿拉伯数字——>中文)
def print_num(n):
for key in dic_num:
if n == dic_num[key]:
return key
#一个变量:返回指定字符串
def compare1(arr,n):
word = [[],[]]
i=0
#取得判断数
for a in arr:
result = re.match('[零一二三四五六七八九十]',a)
if result is not None:
num = get_num(a) #汉字转数字
for a in arr:
result1 = re.match('“(.*?)”',a)
if result1 is not None:
a1=a.strip('“”') #去双引号
word[i]=a1
i=i+1
for a in arr:
if a == '大于':
if n > num:
print(word[0])
else:
print(word[1])
#两个变量、实现比较,返回算术运算后的结果
def compare2(arr,n,x): #n:比较数 x:改变数
num = [[],[]]
i=0
f=0
for a in arr:
result = re.match('[零一二三四五六七八九十]',a)
if result is not None:
num[i] = get_num(a) #汉字转数字
i=i+1
for a in arr:
if a == '大于':
if n > num[0]:
f = 1
for a in arr:
if f == 1:
if a == '增加':
n = x + num[1]
return n
elif a == '减少':
n = x - num[1]
return n
else:
return None
def main():
i = 0
#输入
s1 = input()
arr1 = get_str(s1)
s2 = input()
arr2 = get_str(s2)
s3 = input()
arr3 = get_str(s3)
s4 = input()
arr4 = get_str(s4)
s5 = input()
arr5 = get_str(s5)
#调用函数判断赋值语句,并存储
x1=get_def(arr1)
x2=get_def(arr2)
x3=get_def(arr3)
x4=get_def(arr4)
x5=get_def(arr5)
#判断有几个变量
for x in (x1,x2):
if x is not None:
i = i+1
#一个变量
if i == 1:
#运算
n = get_lastnum(x1,arr2)
n = get_lastnum(n,arr3)
#输出
pattern = '^看'
if re.match(pattern,s4) is not None:
print(print_num(n))
compare1(arr5,n)
elif re.match(pattern,s5) is not None:
compare1(arr4,n)
print(print_num(n))
#两个变量
elif i == 2:
#运算,识别是变量1改变,还是变量2改变,后进行比较输出输出
if arr3[0] == arr1[1]:
n = get_lastnum(x1,arr3)
if (arr4[1] == arr1[1]) & (arr4[5] == arr1[1]):
n1 = compare2(arr4,n,n)
print(print_num(n1))
elif (arr4[1] == arr1[1]) & (arr4[5] == arr2[1]):
n1 = compare2(arr4,n,x2)
print(print_num(n1))
elif (arr4[1] == arr2[1]) & (arr4[5] == arr1[1]):
n1 = compare2(arr4,x2,n)
print(print_num(n1))
elif (arr4[1] == arr2[1]) & (arr4[5] == arr2[1]):
n1 = compare2(arr4,x2,x2)
print(print_num(n1))
elif arr3[0] == arr2[1]:
n = get_lastnum(x2,arr3)
if (arr4[1] == arr1[1]) & (arr4[5] == arr1[1]):
n1 = compare2(arr4,x1,x1)
print(print_num(n1))
elif (arr4[1] == arr1[1]) & (arr4[5] == arr2[1]):
n1 = compare2(arr4,x1,n)
print(print_num(n1))
elif (arr4[1] == arr2[1]) & (arr4[5] == arr1[1]):
n1 = compare2(arr4,n,x1)
print(print_num(n1))
elif (arr4[1] == arr2[1]) & (arr4[5] == arr2[1]):
n1 = compare2(arr4,n,n)
print(print_num(n1))
if __name__=='__main__':
main()
第二次编写:运行样例
第三次编写(优化)
- 优化功能:修改get_num、print_num,实现-99~99的输入与输出,修改def compare1,补充了判断“小于”的功能。
第三次编写:部分代码
def get_num(number):
#print(number)
num = [[],[],[],[]]
i = 0
f = 0 #标记负数
#分离中文数字中的每一个字
for s in number:
num[i] = s
i=i+1
#判断负数
if num[0] == '负':
f = 1
del num[0]
result1 = re.match('^[u4e00-u9fa5]{2,}$',number)#判断两个字以上
result2 = re.match('^[u4e00-u9fa5]{3,}$',number)#判断三个字以上
result3 = re.match('^[u4e00-u9fa5]{4,}$',number)#判断四个字以上
if f == 1:
if result2 is not None :
if (num[0] == '十') :
n = dic_num[num[0]]+dic_num[num[1]] #-11~-19
elif (num[0] == num[1]) | (result3 is not None):
n = dic_num[num[0]]*10+dic_num[num[2]] #eg:-21、-88
else:
n = dic_num[num[0]]*10 #eg:-20
else:
n = dic_num[num[0]] #-1~-10
else:
if result1 is not None :
if (num[0] == '十') :
n = dic_num[num[0]]+dic_num[num[1]] #11~19
elif (num[0] == num[1]) | (result2 is not None):
n = dic_num[num[0]]*10+dic_num[num[2]] #eg:21、99
else:
n = dic_num[num[0]]*10 #eg:20
else:
n = dic_num[number] #0~10
#通过标志位,还原负数
if f == 1:
n = -n
#print(n)
return n
def print_num(n):
#print(n)
f=0 #判断正负的标志位
#当n<0,改为正数处理
if n<0:
n = -n
f = 1
if n >10:
n1 = int(n/10) #得十位
n2 = n%10 #得个位
for num in dic_num:
if (n1 == dic_num[num]) & (n2 == dic_num[num]):
s1 = num
s2 = num
elif n1 == dic_num[num]:
s1 = num
elif n2 == dic_num[num]:
s2 = num
if n1 == 1:
key = '十'+s2 #10~20
elif n2 == 0:
key = s1+'十' #拼接数字 20、30...
else:
key = s1+'十'+s2 #拼接数字 21、31...
else:
for num in dic_num:
if n == dic_num[num]:
key = num
if f == 1:
key = '负'+key
return key
第三次编写:样例运行
小结
第一次 | 第二次 | 第二次 | |
---|---|---|---|
代码行数(带有备注) | 50~70 | 180~200 | 250~270 |
分析时长 | 1h左右 | 2h左右 | 2h左右 |
编写时长 | 2h左右 | 6h左右 | 4h左右 |
优势 | 代码简短易懂 | 1.实现1~2个变量 2.一个变量:输出语句和判断语句的顺序可交换 3.两个变量:实现运算语句和输出语句变量改变的8种可能 | 1.实现了-99~99的输入输出 2.可判断“小于” |
- 缺陷:
- 1、只能处理-99~99的数字
- 2、运算仅限于增加减少
- 3、 暂时只能处理1~2个变量