字符串相减 手把手教你如何用Python编程实现九章算法约分术

Python编程基础

4.1图解九章

古代称整数为全数(简称为全),称分数为分。任一分数都是把一个单位分成若干等份,取其中几份的结果,若单位的份数较少,即分母较小,则说此分数较粗;若单位的份数较多,即分母较大,则说此分数较细。约分术,即分数约简的法则,也就是一个分数由细到粗的过程。约简前和约简后的这两个分数虽然粗细不同,但是实质是一样的,如图4-1所示。

首行缩进2字符显示3字符_字符串相减_字符数组a复制到字符数组b

图4-1约简由细到粗

提示

上图由图解九章源码中的“图解约分术.py”自动绘制而成,我们可运行脚本文件,查看动态的绘制过程。脚本的运行方式参见第4章脚本模式。

问题一今有十八分之十二,问约之得几何?

答曰:三分之二。

问题二又有九十一分之四十九,问约之得几何?

答曰:十三分之七。

约分术曰:可半者半之(“可半者”:分子、分母都是偶数);(“半之”:可以2约简);不可半者(“不可半者”:分子、分母不全是偶数),副置分母、子之数(“副置”:摆或放在别处;古代用算筹计算,布列算式时,使用算筹摆成算式),以少减多(由较多(大)的数减去较少(小)的数),更相减损(辗转相减),求其等也(两数辗转相减,若两方所余的数相等,则称所余的数为“等数”)。以等数约之(以等数约简分数)。

— 卷一 方田

以问题二举例,如图4-2所示。

首行缩进2字符显示3字符_字符数组a复制到字符数组b_字符串相减

图4-2问题二举例

“不可半者,副置分母、子之数”:分子49不为偶数,分母91不为偶数,所以将两数分列一处;

“以少减多,更相减损,求其等也”:先由91 – 49,余42;再由49 – 42,余7;再由42 – 7,余35;35 -7,余28;连续相减,直至余7;结果左右两边余数相等。这相等的余数7就是91与49的等数。

“以等数约之”:用等数7对

约分,得

4.2约分术.py 源码

字符数组a复制到字符数组b_首行缩进2字符显示3字符_字符串相减

4.3脚本模式(Script mode)

到目前为止,我们都是在IDLE中以交互模式(interactive mode)运行Python,也就是说直接输入指令和Python解释器交互。交互模式简单、直接,便于初学,但是如果需要运行更多的代码,这种模式则会显得笨拙。

解决这个问题的方法是将代码保存到名为“脚本(script)”的一个文件中,然后以脚本模式(script mode)运行Python解释器,执行这个脚本。通常,Python脚本文件名的后缀为.py,如约分术.py。

以下是创建一个脚本的步骤。

1.在IDLE窗口的顶部单击“File”菜单(文件菜单),然后选择“New File”(新文件)。出现一个空白窗口,我们可以在其中输入程序代码,如图4-3所示,图4-4是交互式框架窗口。

字符数组a复制到字符数组b_首行缩进2字符显示3字符_字符串相减

图4-3文件编辑窗口

首行缩进2字符显示3字符_字符串相减_字符数组a复制到字符数组b

图4-4交互式框架窗口

两个窗口看起来很像,但是记住一点:交互式框架窗口(interactive shell window)有“>>>”提示符,而文件编辑器窗口(file editor window)没有。

2.在新的文件编辑窗口中输入上节“约分术.py”中的源码(source code)。它包含了程序运行时Python将执行的指令。

3.文件编辑窗口将用不同的颜色显示不同类型的指令。在完成代码输入后,窗口如图4-5所示。文件编辑窗口的右下角提示闪烁的光标的位置,图4-5显示光标在25行0列。

字符串相减_字符数组a复制到字符数组b_首行缩进2字符显示3字符

图4-5约分术脚本文件

4.一旦完成源码输入,我们就可以选择【File-】→【Save as】保存文件,或者按键盘快捷键CTRL+S来保存文件。如图4-6所示,在打开的“另存为”窗口的“文件名”文本框中输入“约分术.py”,然后单击“保存”按钮。

字符数组a复制到字符数组b_字符串相减_首行缩进2字符显示3字符

图4-6文件保存窗口

提示

我们在输入代码时,应该经常保存文件。这样,如果计算机崩溃或者意外从IDLE退出,就不会丢失太多的工作。

4.4程序剖析

程序共分4部分。第一部分获取分母、分子,用两个变量来表示一个分数;第二部分实现“可半者半之”;第三部分实现“不可半者,副置分母、子之数,以少减多,更相减损,求其等也。”;第四部分实现“以等数约之”,并在屏幕上显示出结果。

4.4.1第一部分

# 获取分母、分子
print(‘请输入分数:’)
fz,fm = input().split('/')
fz=int(fz)
fm=int(fm)

1.print()函数

print()函数将括号内的值显示到屏幕上,这个值可以是任何类型的。括号内也可以是表达式,例如:

>>> print(12*14)
168

print()函数会把括号内表达式所求的值显示到屏幕上。

代码行print(‘请输入分数:’)表示将字符串‘请输入分数:’显示到屏幕上。

提示

引号不会打印在屏幕上,它们只是表示字符串的起止,不是字符串的一部分。

2.input()函数

input()函数等待用户在键盘上输入一些文本,并按下回车键。input()函数返回值为一个字符串,即用户输入的文本。例如:

>>> input()
12/18
'12/18'

用户输入12/18,input()函数返回值为一个字符串’12/18’。

3.split()函数

split()函数是一个字符串函数,通过指定的分隔符对字符串进行切片。我们可以在IDLE中输入以下内容,看看split()函数如何进行切片的。

>>> str='约分术'
>>> str.split()
['约', '分', '术']
>>>

这个例子中split()函数的括号内为空,默认以“空格”为分隔符。str.split()将str变量中的字符串'约分术'以空格为分隔符进行切分,返回结果为['约', '分', '术' ],这是一个列表,这个列表中包含了'约'、'分'、'术'这三个元素。列表这种数据类型会在第6章详细讲解。

语句fz,fm = input().split('/'),表示用户输入的文本,以分隔符’/’进行分隔切片,切片结果分别赋值于fz、fm两个变量。例如,用户输入12/18,input()函数返回值为一个字符串’12/18’,这个字符串以分隔符’/’进行分隔,返回一个列表[‘12’,’18’],这个列表中第1个值’12’赋值于变量fz(fz是分子的汉语拼音fenzi的缩写),第2个值’18’赋值于变量fm(fm是分母的汉语拼音fenmu的缩写)。一条赋值语句可以同时给多个变量赋值,第6章会再次讲解这一点。

4.int()函数

int()函数将括号内的值转换成整数,int(fz)表示把变量fz的值转换成整数,如果fz是字符串’12’,那么int(fz)的返回值为整数12。

代码fz=int(fz)表示将int(fz)返回的值12赋值于变量fz,替换fz原有的值。

代码fm=int(fm)同上。

4.4.2第二部分

首行缩进2字符显示3字符_字符数组a复制到字符数组b_字符串相减

1.程序的基本控制结构

程序有3种基本的控制结构:顺序结构、选择结构和循环结构。所有的程序都是由这3种基本结构组合而成的。

2.while循环语句

while语句是Python的一种循环语句,可以让一个代码块一遍又一遍地执行。while 语句总是包含以下4个部分。

注意

while子句必须缩进,缩进可以选择两个空格、4个空格或一个tab,无论选择哪一种,while子句中每一条语句的缩进必须一致、必须对齐,否则,会提示语法错误,

while循环语句的循环在两种情况下会终止:

提示

while循环语句的循环必须要终止,否则,程序就会陷入到无限的循环之中,永远不会结束。

3.比较运算符

“比较运算符”比较两个值,比较的结果为一个布尔值。表4-1 列出了比较运算符。

表4-1比较运算符

运算符

含义

==

等于

!=

不等于

<

小于

>

大于

=

大于等于

这些运算符根据提供给它们的值,进行比较,得到的结果为布尔值True 或 False。假设fm=18,在IDLE中表达式fm%2 == 0的值是什么?(赋值语句fm=18将值18赋予变量fm,算术运算符%为取除法运算的余数,即18 ÷ 2的余数)

>>> fm = 18
>>> fm%2
0
>>> fm%2 == 0
True

如果两边的值一样,==(等于)的求值为 True。如果两边的值不同,则!=(不等于)的求值为 True。==和!=运算符实际上可以用于所有数据类型的值。

>>> 'hello' == 'hello'
True
>>> 'hello' == 'Hello'
False
>>> 'guang' != 'cong'
True
>>> 12 == 12.0
True
>>> 12 == '12'
False

整型或浮点型的值永远不会与字符串相等。表达式12 == '12'求值为False,因为,Python 认为整数 12 与字符串'12'是不同的。但是整型和浮点型的值却有可能是相等的,例如表达式12 == 12.0求值为True。

、=运算符仅用于整型和浮点型值。

注意

= 是赋值运算符,将一个值赋予一个变量。而==是比较运算符,比较两个值是否相等。

4.布尔运算符

3个布尔运算符and、or 和 not用于比较布尔值。像比较运算符一样,布尔运算符的表达式求值为一个布尔值。

and 和 or 运算符总是需要两个布尔值(或表达式),所以它们被称为是“二元”运算符。如果两个布尔值都为 True,and 运算符的表达式求值为 True,否则求值为 False。

>>> True and True
True
>>> True and False
False
>>> False and True
False
>>> False and False
False

只要有一个布尔值为真,or 运算符则将表达式求值为 True。如果都是 False,所求值为False。

>>> True or True
True
>>> True or False
True
>>> False or True
True
>>> False or False
False

和 and、or不同,not运算符只作用于一个布尔值(或表达式)。not运算符求值为相反的布尔值。

>>> not True
False
>>> not not not not True
True

5.混合布尔和比较运算符

既然比较运算符的求值为布尔值,那么,比较运算符就可以和布尔运算符一起,在表达式中组合使用。

表达式fm%2 == 0 and fz%2 == 0的求值步骤如下:

假设fm=18,fz=12,可在IDLE中查看表达式fm%2 == 0 and fz%2 == 0的结果:

>>> fm=18
>>> fz=12
>>> fm%2 == 0
True
>>> fz%2 == 0
True
>>> fm%2 == 0 and fz%2 == 0
True

6.整除运算符

前面说过字符串相减,“ / ”除法运算符求值为浮点数,如3/2结果是1.5,3/3结果是1.0,如果要取这个结果的整数部分,可以用第3章里田术的方法,也就是调用int()函数来截取浮点数的整数部分,如int(1.5) →1,int(1.0) →1。在Python中有一个更简便的算术运算符,就是整除运算符“//”,整除运算符返回除法运算的商,如3//2结果是1,3//3结果是1,整除运算符的结果始终是整数。

提示

整除运算符“//”、取模运算符“%”,一个是取除法运算的商,一个是取除法运算的余数,例如375÷100商为3余75,375//100 →3,3750 →75。这两个算术运算符在Python符号体系中是合法有效的,但在数学符号体系中是不合法的。

4.4.3第三部分

字符数组a复制到字符数组b_字符串相减_首行缩进2字符显示3字符

图4-7第三部分代码

这部分代码包含了三种基本结构:顺序结构、选择结构和循环结构。

变量fm_yu为分母一列的余数,变量fz_yu为分子一列的余数。赋值语句fm_yu = fm将fm_yu 的初始值设为fm;赋值语句fz_yu = fz将fz_yu的初始值设为fz,以此实现“副置分母、子之数”。

while循环语句的条件fm_yu != fz_yu用于判断两列的余数是否不相等。如果不相等,就执行while子句里的代码;如果相等,就不执行while子句里的代码。这里的while子句是一个if…else语句,if…else语句是一个选择结构,是一个条件语句。

1.if…else语句

if语句是一个选择结构,在英文中,if 语句念起来可能是:“如果条件为真,则执行子句中的代码。”

if 语句包含以下部分:

if 子句后面有时候会跟着 else 语句。只有 if 语句的条件为 False 时,else子句才会执行。在英语中,if…else 语句读起来可能是:“如果条件为真,则执行这段代码(if子句)。否则,执行那段代码(else 子句)”。else 语句不包含条件,else 语句包含以下几部分:

注意

if子句必须缩进,缩进可以选择两个空格、4个空格或一个tab,无论选择哪一种,if子句中每一条语句的缩进必须一致、必须对齐,否则,会提示语法错误。else子句也是同样。

以下是第三部分代码中的语句:

while(fm_yu != fz_yu):                
    if(fm_yu > fz_yu):
        fm_yu = fm_yu - fz_yu
    else:
        fz_yu = fz_yu - fm_yu

上面那个if…else语句的意思就是如果分母余数fm_yu大于分子余数fz_yu,则用fm_yu减去fz_yu,所得的值赋值于fm_yu,即分母余数的新值为相减所得的数;否则,用fz_yu减去fm_yu,所得的值赋值于fz_yu,即分子余数的新值为相减所得的数,以此实现“以少减多”。这段if…else语句会循环执行,直到while语句的条件fm_yu != fz_yu为False,也就是分母余数fm_yu等于分子余数fz_yu的时候,循环终止,最终实现“更相减损,求其等也”。

deng_shu = fm_yu
print(‘等数为’,deng_shu)

第三部分最后使用赋值语句deng_shu = fm_yu将分母一列和分子一列相等的余数赋值给变量deng_shu(等数),并调用print()函数把等数打印到屏幕上。我们可以看到,这里的print()函数有两个参数,第1个参数是一个字符串‘等数为’,第2个参数是一个整数deng_shu。这个print()函数可以把两个参数的值按顺序打印到屏幕上,两个值在屏幕上用空格分隔。

4.4.4第四部分

# 以等数约之
print('约之得'+str(fm//deng_shu)+'分之'+str(fz//deng_shu))

这部分调用了一个print()函数,函数的参数是一个表达式,这个表达式使用字符串连接符+将4个字符串'约之得'、str(fm//deng_shu)、'分之'、str(fz//deng_shu)连接成一个新的字符串,其中调用了str()函数将fm//deng_shu、fz//deng_shu整除所得的整数转换成字符串。

假设fm=9,fz =6,deng_shu=3,表达式的求值过程如下:

'约之得'+str(fm//deng_shu)+'分之'+str(fz//deng_shu)→'约之得'+str(9//3)+'分之'+str(6//3)  →'约之得'+str(3)+'分之'+str(2) →  '约之得'+’3’+'分之'+’2’→'约之得3分之2’

4.5运行结果

现在,我们可以运行“约分术.py”来解决约分术的问题一和问题二。用鼠标右键单击“约分术.py”文件字符串相减,选择菜单【Edit with IDLE】→【Edit with IDLE 3.6(32 -bit)】,在打开的文件编辑窗口中选择菜单【Run】→【Run module】,或者按F5快捷键。

在“请输入分数:”后输入问题一:12/18(十八分之十二),按回车键,运行结果如图4-8所示。

字符数组a复制到字符数组b_首行缩进2字符显示3字符_字符串相减

图4-8问题一运行结果

再次运行“约分术.py”,在“请输入分数:”后输入问题二:49/91(九十一分之四十九),按回车键,运行结果如图4-9所示。

首行缩进2字符显示3字符_字符串相减_字符数组a复制到字符数组b

图4-9问题二运行结果

从上面示例中我们可以看到用户需要输入的、以及显示的结果都是阿拉伯数字,而不是汉字数字,这个问题会在稍后的章节中解决。

4.6练一练

将第3章里田术的自定义函数改写成“里田术.py”的脚本文件,我们需要修改以下内容。

1.去除函数定义的第一行函数头,增加语句,通过print()和input()这两个函数提示用户输入,从而获取guang、cong的值。

2.去除return语句,使用print()函数把结果打印到屏幕上。

修改完成后运行脚本文件,解决里田术的问题一、问题二,查看运行结果。

———END———
限 时 特 惠:本站每日持续更新海量各大内部创业教程,一年会员只需128元,全站资源免费下载点击查看详情
站 长 微 信:jiumai99

滚动至顶部