看到一个要求输出 “杨辉三角形” 的题目:百度知道
循着给出的链接,又找到了百度文库,看了一篇又一篇文章、程序,感觉好像是一个赛着一个的罗嗦。
难道,这网上是在进行 “程序赛笨” 吗?
杨辉三角形,大家都知道,排列形状如下:
1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10 10 5 1
1 6 15 20 15 6 1
… … … …
可以看出,各个元素的数值,就是上一行的两个相邻元素之和。
(按照这个规律,最左边和最右边,还应该各有一列零。当然,零就不显示了。)
杨辉三角形的数值变化规律,还真是很简单的!
有人总结的规律,则要高深的多,不仅要用到二维数组,而且用上了排列组合的公式!
呵呵,如果这么想,编程,还能简单得了吗?
如果按照杨辉三角形本身的规律,就可以如下计算。
先定义一个 20 个 0 的字数据空间,杨辉三角形中每一行的数据,都在这个空间中计算。
空间中两两相邻的字数据,就可分别称为一个个【左数据】、【右数据】。
从左边开始,把左右两个数据相加,再保存在右数据的位置,然后再继续向右计算,直到得到的和为零,这一行的数据,就计算结束了。。
每一行,都这样计算,算出来的结果,可以当场输出。想要输出多少行,就这样算多少遍。
经过推算,到了第 19 行,其最大的元素,就超过了 65535。
大于 65535 的数字,用 16 位机来计算和显示,难度就明显加大了。
所以,这个杨辉三角形,行数,还是不要超出 18 了。
做而论道编写的输出杨辉三角形的程序如下。
;=====================================
QWE SEGMENT
TIT DB 10, 13, '------------------------------------------'
DB 10, 13, ' YangHui Triangel'
DB 10, 13, '------------------------------------------'
DB 10, 13, 'Please input the output LineNumber [1~18]: $'
X DW ?
TMP1 DW 1, 20 DUP(0) ;定义空间用于运行过程中存储临时数据
QWE ENDS
;--------------------------------
ZXC SEGMENT
ASSUME CS:ZXC, DS:QWE
BG:
MOV AX, QWE
MOV DS, AX
;--------------------------------
LEA DX, TIT
MOV AH, 9
INT 21H
CALL IN_NUM ;输入行数
;------------------------
MOV CX, X ;取来行数
CMP CX, 0
JZ QUIT ;符合范围要求?
CMP CX, 18
JA QUIT
CALL CR_LF ;回车换行
CALL CR_LF ;回车换行
M_LOP: ;CX=1~18
LEA SI, TMP1
MOV BX, 0 ;【左数据】
CALL YangHui ;输出一行
CALL CR_LF
LOOP M_LOP ;循环1~18次
;--------------------------------
QUIT: MOV AH, 4CH
INT 21H
;=====================================
YangHui: ;计算杨辉三角形一行数据
MOV AX, [SI] ;取出【右数据】
ADD AX, BX ;加上【左数据】
MOV BX, [SI] ;再取,做下次的【左数据】
MOV [SI], AX ;保存和
JZ END_YH ;为零就停止
ADD SI, 2
CALL PRINT_AX ;输出
CALL SPACE
JMP YangHui ;循环
END_YH: RET ;一行计算完毕。这个算法,是不是很简单?
;=====================================
IN_NUM: ;输入数字
MOV X, 0 ;先清零
MOV CX, 2 ;输入2位
@@: MOV AH, 7 ;输入
INT 21H
CMP AL, 13
JE @F ;转到结束
CMP AL, '0'
JB @B ;小于,不是数字
CMP AL, '9'
JA @B
MOV DL, AL
MOV AH, 2 ;显示单个字符
INT 21H
MOV AL, DL
SUB AL, '0' ;还原为数字
MOV AH, 0
XCHG AX, X ;取出老数据
SHL AX, 1
ADD X, AX
SHL AX, 1
SHL AX, 1 ;老数据乘以10
ADD X, AX ;加上新数据
LOOP @B ;继续输入
@@: RET
;=====================================
PRINT_AX:
PUSH BX
PUSH DX
MOV BX, 10
PUSH BX
@@: XOR DX, DX
DIV BX
PUSH DX
CMP AX, 0
JNZ @B
MOV AH, 2
@@: POP DX
CMP DX, 10
JE @F
ADD DL, '0'
INT 21H
JMP @B
@@: POP DX
POP BX
RET
;=====================================
CR_LF: ;显示回车换行
PUSH AX
MOV AX, 0E0DH
INT 10H
MOV AX, 0E0AH
INT 10H
POP AX
RET
;=====================================
SPACE: ;显示空格
PUSH AX
MOV AX, 0E20H
INT 10H
POP AX
RET
;=====================================
ZXC ENDS
END BG
程序,不过一百多行,就实现了:输入行数、显示指定行数的杨辉三角形。
程序运行截图如下:
最多可以显示 18 行,但是一行数据有点长,屏幕的一行显示不开。