汇编输出杨辉三角

汇编输出杨辉三角
汇编输出杨辉三角

1.2 杨辉三角性质

1、每行数字左右对称,由1开始逐渐变大,然后变小,回到1。

2、第n行的数字个数为n个。

3、第n行数字和为2^(n-1)。(2的(n-1)次方)

4、每个数字等于上一行的左右两个数字之和。可用此性质写出整个帕斯卡三角形。

5、将第2n+1行第1个数,跟第2n+2行第3个数、第2n+3行第5个数……连成一线,这些数的和是第2n个斐波那契数。将第2n行第2个数,跟第2n+1行第4个数、第2n+2行第6个数……这些数之和是第2n-1个斐波那契数。

6、第n行的第1个数为1,第二个数为1×(n-1),第三个数为1×(n-1)×(n-2)/2,第四个数为1×(n-1)×(n-2)/2×(n-3)/3…依此类推。

7.两个未知数和的n次方运算后的各项系数依次为杨辉三角的第(n+1)行。

图1-2-1 杨辉三角图 1-2-2 杨辉三角数学公式

第一章汇编语言简介

2.1 汇编语言概况

根据本次设计要求:通过汇编语言编写汇编程序要求能够在提示信息下,从计算机键盘任意输入一个数据,在输出提示信息后显示相应的杨辉三角。下面对汇编语言作简单的介绍。

汇编语言(AssemblyLanguage)是面向机器的程序设计语言。在汇编语合中,用助记符(Memoni)代替操作码,用地址符号(Symbol)或标号(Label)代替地址码。这样用符号代替机器语言的二进制码,就把机器语言变成了汇编语言。于是汇编语言亦称为符号语言。使用汇编语言编写的程序,机器不能直接识别,要由一种程序将汇编语言翻译成机器语言,这种起翻译作用的程序叫汇编程序,汇编程序是系统软件中语言处理系统软件。汇编程序把汇编语言翻译成机器语言的过程称为汇编。

汇编语言是一种功能很强的程序设计语言,也是利用计算机所有硬件特性并能直接控制硬件的语言。汇编语言,作为一门语言,对应于高级语言的编译器,需要一个“汇编器”来把汇编语言原文件汇编成机器可执行的代码。高级的汇编器如MASM,TASM等等为我们写汇编程序提供了很多类似于高级语言的特征,比如结构化、抽象等。在这样的环境中编写的汇编程序,有很大一部分是面向汇编器的伪指令,已经类同于高级语言。现在的汇编环境已经如此高级,即使全部用汇编语言来编写windows的应用程序也是可行的,但这不是汇编语言的长处。汇编语言的长处在于编写高效且需要对机器硬件精确控制的程序。

汇编语言(Assembly Language)是一种采用助记符表示的程序设计语言,即用助记符来表示指令的操作码和操作数,用符号或标号代表地址、常量或变量。助记符一般都是英文单词的缩写,便于识别和记忆。使用汇编语言编写的程序称为汇编语言源程序。汇编语言源程序不能由机器直接执行,而必须翻译成有机器代码组成的目标程序,这个翻译的过程称为汇编。把汇编语言源程序翻译成目标程序的软件称为汇编程序。

汇编语言与机器语言密切相关,它们之间有明显的对应关系。一条汇编语言指令对应一条机器语言代码,所以汇编语言和机器语言一样都是面向机器的语言。使用汇编语言进行程序设计能充分利用机器的硬件功能和结构特点,从而有效地加快程序的执行速度,减少程序占用的存储空间。所以汇编语言大量用于编写计算机系统程序、实时通信程序和实时控制程序等。

汇编语言作为最基本的编程语言之一,汇编语言虽然应用的范围不算很广,但重要性却勿庸置疑,因为它能够完成许多其它语言所无法完成的功能。就拿Linux内核来讲,虽然绝大部分代码是用C语言编写的,但仍然不可避免地在某些关键地方使用了汇编代码,其中主要是在Linux的启动部分。由于这部分代码与硬件的关系非常密切,即使是C语言也会有些力不从心,而汇编语言则能够很好扬长避短,最大限度地发挥硬件的性能。

2.2汇编语言优点及缺点

汇编语言直接同计算机的底层软件甚至硬件进行交互,它具有如下一些优点:

(1)能够直接访问与硬件相关的存储器或I/O端口;

(2)能够不受编译器的限制,对生成的二进制代码进行完全的控制;

(3)能够对关键代码进行更准确的控制,避免因线程共同访问或者硬件设备共享引起的死锁;

(4)能够根据特定的应用对代码做最佳的优化,提高运行速度;

(5)能够最大限度地发挥硬件的功能。

同时还应该认识到,汇编语言是一种层次非常低的语言,它仅仅高于直接手工编写二进制的机器指令码,因此不可避免地存在一些缺点:

(1)编写的代码非常难懂,不好维护;

(2)很容易产生bug,难于调试;

(3)只能针对特定的体系结构和处理器进行优化;

(4)开发效率很低,时间长且单调。

首先程序开始时在电脑上显示输入提示信息,提醒输入的操作数只能是1到10之间的正整数,超过这个范围或太小则显示提示信息输入的数过大。得到杨辉三角的阶数之后即调用一个算法子程序来求相应阶数的每一个数值,每求出一个数值即将其数压入堆栈中保存起来,方便以后输出数字时直接调用。算完之后,通过外层循环di计数输出每一行,与此同时又通过内层循环si计数输出一行中的每一个数,在输出数字时通过调用show子程序将数字均以十进制输出,在输出数值的时候通过showspace函数来控制数与数之间的空格及行前空格的输出,上半部分的数字输出之后将其所有数值及空格格式都存在一个预制的存储单元内,然后直接实现逆序输出,这样最终能在屏幕中打印出一个菱形的杨辉三角。

第二章子程序设计

4.1 输入子程序

输入用int 16 ah为0这一功能,从键盘读字符,字符存在al中,输入时用cmp判断令其只能输入字符’0’~‘9’每次输入的字符转化为十进制存并阔展为字存入ax中,再将ax 与初始为0的bp交换,再将ax乘以十后与bp相加,结果存在bp中,再返回输入,这样就能输入两位数。

shur proc

push cx

push bx

xor bp,bp

mov bx,10

mov cx,2

input:

mov ah,0 ;键盘输入数据存在al中

int 16h

cmp al,0dh ;以回车结束输入

jz ok

cmp al,'0' ;只允许输入0~9

jb input

cmp al,'9'

ja input

mov ah,0eh ;显示有效输入

int 10h

sub al,30h ;化ASCII为十进制

cbw ;字节扩展为字

xchg ax,bp

mul bx ;扩大10倍

add bp,ax ;加一位

loop input

ok:nop ;数值结果在BP中

pop bx ;恢复用到的寄存器

pop cx

ret

shur endp

4.2杨辉三角算法子程序

求某m行n列的数C(n, m)时采用递归的方法求出该数具体算法是:

{ C(n, m) = 1 (n < m 或 m = 0)

{ C(n, m) = C(n-1, m-1) + C(n-1, m) (n > m)

即某位置组合数等于上一行左右两数之和,先算出左肩上的数并压栈保存,再次调用C过程求出右肩上的数并压栈保存,左肩与右肩的数相加从而可以求出下一行的组合数吗,其间存在递归调用,直至求出最大的那个数才返回初始调用的call的下一个语句。

C proc

push bp

mov bp, sp

sub sp, 2 ; 预留一个存储位置

mov bx, [bp+6] ; 保存m到bx

cmp bx, [bp+4] ; 如果m > n 返回1

jz L1

cmp bx, 0 ; 如果m = 0 返回1

jz L1

mov ax, [bp+4] ; 保存n到ax

dec ax; ax = ax - 1

dec bx; bx = bx - 1

push bx

push ax

call C ; 返回上一行左边的那个数

mov [bp-2], ax ; 保存左肩膀上的数

mov ax, [bp+4] ; 以下5句同理,返回上一行右肩膀上的数

dec ax

push [bp+6]

push ax

call C

add ax, [bp-2] ; 和左肩膀上的数相加得出该组合数

jmp L2

L1:

mov ax, 1

L2:

mov sp, bp

pop bp

ret 4 ; ax返回组合数

C endp

4.3计算输出数字长度子程序

将此数不断除以十,每除一次计数加1,当al即商为0时停止返回计数值即长度。例如:计算输出数字最大长度以便分配行间行前空格时,n阶的最大数应该是最后一行中间那个数即C(n, n/2),将此数不断除以十,每除一次计数加1,当al即商为0时停止返回计数值即最大长度。

getdigit proc

push dx

mov bx, 10

xor dx, dx

next:

cmp ax, 0

jle ok2

div bl

and ax, 0ffh

inc dx

jmp next

ok2:

mov ax, dx

pop dx

ret

getdigit endp

4.4计行前数字间空格子程序

先定义一个可以接受输入ax个空格的子程序输出行前空格时,n阶杨辉三角的i行行前空格数=(n-i)*cl ,cl是最大长度,某数与下一个数字间空格数=数的最大长度cl+cl-该数的长度。具体程序如下:

call showspace ; 输出行前空格

xor si, si ; 内存循环计数si,内层循环输出一行中的每个数jmp cp2

up2:

inc si ; 更新di

cp2:

cmp si, di ; 测试循环条件,循环di次

jg done2

push si

push di

call C ; 获取该行的位于si位置的组合数,调用C(di, si) push ax ; 保存该组合数

push bx

mov bx ,dx

mov [bx], ax

inc dx

inc dx

pop bx

call show ; 输出该数

mov ax, cx

sub ax, 1

push bx

mov [bx], ax

inc dx

inc dx

pop bx

call showspace

pop ax

call getdigit ; 获取该组合数长度

mov bx, ax

mov ax, cx

sub ax, bx ;

add ax, 1

push bx

mov bx ,dx

mov [bx], ax

inc dx

inc dx

pop bx

call showspace

jmp up2 ; 更新内层循环

showspace:

push dx

mov bx, ax

mov ah, 2

mov dl, ' '

nexts:

cmp bx, 0

jle dones

int 21h

dec bx

jmp nexts

dones:

pop dx

4.5输出子程序

输出分为上半部分和下半部分,上半部分输出利用2号功能将每个数除以10将余数转化为字符倒序输出,下半部分是将算好的数以及行前行间空格数算好然后倒序输出。

上半部分:

s how proc

push dx

mov bx, 10

jz ok1

div bl

push ax

and ax, 00ffh

call show

pop dx

mov dl, dh

or dl, 30h

mov ah, 2

int 21h

ok1:

pop dx

ret

show endp

下半部分:

mov ax,da

inc al

mov bl,6

mul bl

sub dx,ax

dec dx

dec dx

mov cx,da

l11:

mov ax,cx

mov bl,6

mul bl

sub dx,ax

dec dx

dec dx

mov bx,dx

mov ax,[bx]

call showspace ; 输出行前空格push cx

l12:

inc dx

inc dx

mov bx,dx

mov ax,[bx]

call show ; 输出该数

inc dx

inc dx

mov bx,dx

call showspace ;输出数字间间隔空格inc dx

inc dx

mov bx,dx

mov ax,[bx]

call showspace;输出填充的空格loop l12

pop cx

mov ax,cx

mov bl,6

mul bl

inc dx

inc dx

sub dx,ax

dec dx

dec dx

push dx

mov ah, 2 ; 以下5句实现换行mov dl, 13

int 21h

mov dl, 10

int 21h

pop dx

loop l11

附录附录A

程序代码:

data segment

org 100h

message db 'Input N(N<=10): $' error db 0ah,0dh, 'Data out of range!$' da dw 0

dat dw 300 dup(?)

data ends

code segment

assume cs:code,ds:data

start:

mov ax,data mov ds,ax

mov dx,offset message mov ah,9

int 21h

call shur

cmp bp,10

jbe goon

mov dx,offset error mov ah,9

int 21h

jmp exit

goon:

mov ah, 2 ; 以下5句实现换行mov dl, 13

int 21h

mov dl, 10

int 21h

push bp

call yhsj

mov ax,da

inc al

mov bl,6

mul bl

sub dx,ax

dec dx

dec dx

mov cx,da

l11:

mov ax,cx

mov bl,6

mul bl

sub dx,ax

dec dx

dec dx

mov bx,dx

mov ax,[bx]

call showspace ; 输出行前空格push cx

l12:

inc dx

inc dx

mov bx,dx

mov ax,[bx]

call show ;输出该数

inc dx

inc dx

mov bx,dx

mov ax,[bx]

call showspace ;输出数字间间隔空格inc dx

inc dx

mov bx,dx

mov ax,[bx]

call showspace ;输出填充的空格loop l12

pop cx

mov ax,cx

mov bl,6

mul bl

inc dx

inc dx

sub dx,ax

dec dx

dec dx

push dx

mov ah, 2 ; 以下5句实现换行mov dl, 13

int 21h

mov dl, 10

int 21h

pop dx

loop l11

mov ah,4ch

int 21h

exit:

mov ah,4ch

int 21h

shur proc

push cx

push bx

xor bp,bp

mov bx,10

mov cx,2

input:

mov ah,0 ;键盘输入数据存在al中int 16h

cmp al,0dh ;以回车结束输入

jz ok

cmp al,'0' ;只允许输入0~9

jb input

cmp al,'9'

ja input

mov ah,0eh ;显示有效输入

int 10h

sub al,30h ;化ASCII为十进制cbw ;字节扩展为字

xchg ax,bp

mul bx ;扩大10倍

add bp,ax ;加一位

loop input

ok:nop ;数值结果在BP中

;恢复用到的寄存器

pop bx

pop cx

ret

shur endp

; 输出杨辉三角的函数,接受一个栈上的参数N

; 输出N阶杨辉三角

yhsj proc

mov bp, sp

mov ax, [bp+2] ; 保存N到ax

mov dx,offset dat

mov da, ax

shr ax, 1 ; N = N / 2

push ax

mov ax, [bp+2] ; 保存N到ax

push ax

call C; C(N, N/2)获取最后一行中间的那个值,即最大值

call getdigit ; 计算该最大值的长度,如252则返回3

mov cx, ax ; 保存最大长度到cx,用于事后格式用

xor di, di ; 外层循环计数di,外层循环输出每一行

jmp cp1

up1:

inc di; 更新di

cp1:

cmp di, [bp+2] ; 测试循环条件,循环N次

jg done1

mov ax, [bp+2] ; 以下3句计算行前空格数= (N-i)*cl,cl是最大长度

sub ax, di

mul cl

push bx

mov bx ,dx

mov [bx], ax

inc dx

inc dx

pop bx

call showspace ; 输出行前空格

xor si, si ; 内存循环计数si,内层循环输出一行中的每个数

jmp cp2

up2:

inc si; 更新di

cp2:

cmp si, di ; 测试循环条件,循环di次

jg done2

push si

push di

call C; 获取该行的位于si位置的组合数,调用C(di, si)

push ax ; 保存该组合数

push bx

mov bx ,dx

mov [bx], ax

inc dx

inc dx

pop bx

call show ; 输出该数

mov ax, cx ;以下输出数字间间隔空格,个数= N - 1

sub ax, 1

push bx

mov bx ,dx

mov [bx], ax

inc dx

inc dx

pop bx

call showspace

pop ax

call getdigit ; 获取该组合数长度

mov bx, ax

mov ax, cx

sub ax, bx ;计算需要填充的空格数= 最大长度- 该数长度+ 1

add ax, 1

push bx

mov bx ,dx

mov [bx], ax

inc dx

inc dx

pop bx

call showspace

jmp up2 ; 更新内层循环

done2: ; 内层循环结束

push dx

mov ah, 2 ; 以下5句实现换行

mov dl, 13

int 21h

mov dl, 10

int 21h

pop dx

jmp up1 ; 更新外层循环

done1: ; 外层循环结束

ret 2 ; 释放函数参数使用的栈空间

yhsj endp

; 求组合数的递归函数,接受栈上的2个参数n, m(n > m)

; 返回C(n, m),即n选m的个数

; 算法是:

; { C(n, m) = 1 (n = m 或m = 0)

; { C(n, m) = C(n-1, m-1) + C(n-1, m) (n > m) ; 即某位置组合数等于上一行左右两数之和

C proc

push bp

mov bp, sp

sub sp, 2 ; 预留一个存储位置

mov bx, [bp+6] ; 保存m到bx

cmp bx, [bp+4] ; 如果m = n 返回1 jz L1

cmp bx, 0 ; 如果m = 0 返回1

jz L1

mov ax, [bp+4] ; 保存n到ax

dec ax; ax = ax - 1

dec bx; bx = bx - 1

push bx

push ax

call C; 返回上一行左边的那个数

mov [bp-2], ax ; 保存左肩膀上的数mov ax, [bp+4] ; 以下5句同理,返回上一行右肩膀上的数

dec ax

push [bp+6]

push ax

call C

add ax, [bp-2] ; 和左肩膀上的数相加得出该组合数

jmp L2

L1:

mov ax, 1

L2:

mov sp, bp

pop bp

ret 4 ; ax返回组合数

C endp

; 递归以10进制输出ax

; 方法很简单,就是求出余数,然后ax = ax / 10

; ax = 0时退出,开始逆序输出求出的各位余数

show proc

push dx

mov bx, 10

cmp ax, 0

jz ok1

div bl

push ax

and ax, 00ffh

call show

pop dx

mov dl, dh

or dl, 30h

mov ah, 2

int 21h

ok1:

pop dx

ret

show endp

; 获取一个数的长度,ax为参数,如果ax = 252则返回3

; ax里是返回值

getdigit proc

push dx

mov bx, 10

xor dx, dx

next:

cmp ax, 0

jle ok2

div bl

and ax, 0ffh

inc dx

jmp next

ok2:

mov ax, dx

pop dx

ret

getdigit endp

; 输出ax个空格,参数ax,无返回值showspace proc

push dx

mov bx, ax

mov ah, 2

mov dl, ' ' nexts:

cmp bx, 0

jle dones

int 21h

dec bx

jmp nexts dones:

pop dx

ret showspace endp code ends

end sta

显示杨辉三角实验报告

显示杨辉三角实验报告 姓名:许严班级:计122 学号:1213023050 1.问题描述 杨辉三角如图2.4.3所示,其特点是两个腰上数值是1,其他位置上的每一个整数都是它的上一行相邻两个整数之和。问题是:对于指定的最大行数rmax,要求从第一行到第rmax逐行显示杨辉三角形的所有元素。 2.基本要求 ⑴设计输出形式,尽量反映杨辉三角的特点。 ⑵设计计算杨辉三角形各行数值的方法。 ⑶输入:rmax从键盘输入。 ⑷输出:屏幕输出杨辉三角形. 3.实现提示 ⑴存储设计 计算杨辉三角形第i行时,如果在第i-1行两侧各添加一个0,则第i行的第j个元素等于第i-1行的第j-1个元素与第j个元素的和。计算如图2.4.4所示。第i行计算完,第i-1行的数据就没有用了,依据第i行数据可计算第i+1行的数据。 1 1 1 1 2 1 1 3 3 1 1 4 6 4 1 1 5 10 10 5 1 … 图2.4.3 杨辉三角形 从上述计算中不难看出,第i行的元素从左往右依次可被求得,求解过程中也是从左往右依次使用地i-1行的数据,显然,具有先入先出的特点。所以,可借助一个队列存放计算过程中所需的数据,如图2.4.5所示。 但随着航数的增加,队列会很长。所以,可以设置一循环队列,队长不少于rmax+2,边计算边出队。 (2)算法设计 计算各行元素的算法步骤如下。 Step1:队列初始化,0、1入队。队头ftont指向0处,队尾指向1后。 Step2:i从1到rmax,循环执行下列操作,求第i行数据。 2.1 0入队。 2.2 从队首起直到队尾,每出队两元素,求和后入队。 输出时注意0不输出。

杨辉三角队列实现

网上看了许多杨辉三角队列实现的代码,结果运行时都或多或少有点小问题,为此我提供一份自己运行正确的。 程序无误,细心做一下 注意,这是做成三个文件运行的 第一个文件命名 stdafx.h #include #include #define Max 50 struct queue { int *base; int front; int rear; }; typedef struct queue *SqQueue; SqQueue InitQueue();//队列的初始化 int EnQueue(SqQueue Q,int e);//数据进队(从队尾传值) int DeQueue(SqQueue Q);//数据出队(返回队头) void YHPrint(SqQueue Q,int n);//打印杨辉三角 void jiemian();//界面函数,方便调用(个人习惯) 第二个文件命名为 stdafx.c #include "stdafx.h"

int GetQueueFirstData(SqQueue Q) { return Q->base[Q->front]; } int isEmptyQueue(SqQueue Q) { if(Q->front=Q->rear) return 1; else return 0; } SqQueue InitQueue() { SqQueue Q; Q=(SqQueue)malloc(sizeof(struct queue)); if (Q==NULL) return NULL; Q->base=(int *)malloc(Max*sizeof(int)); if(Q->base==NULL) return NULL; Q->front=Q->rear=0; return Q; } int EnQueue(SqQueue Q,int e) { if((Q->rear+1)%Max==Q->front) return 0; Q->base[Q->rear]=e; Q->rear=(Q->rear+1)%Max; return 1; } int DeQueue(SqQueue Q) { int e; if(Q->front==Q->rear) return 0; e=Q->base[Q->front]; Q->front=(Q->front+1)%Max; return e; }

程序设计基础C实验报告201303

《程序设计基础C》 实 验 报 告 教学班级:_______ 学号:__________ 姓名:___________ 课程教师:______________ 实验辅导教师:_____________ 重庆理工大学计算机学院 2012年2月

实验5 循环程序设计 教学班级:_______ 学号:__________ 姓名:___________ 实验日期:___________ 实验地点:_________(机房) 实验成绩:___________ 一、实验目的 (1) 了解C语言循环结构的使用范围。 (2) 学会正确使用逻辑运算符和逻辑表达式。 (3) 熟练掌握C语言的三种循环结构:whilc语句、do……whilc语句、for语句的特点和使用方法。 (4) 能够编写一些有实际应用意义的循环结构程序。 二、实验内容 1.基本内容 题目1:计算1-3+5-7+......-99+101的值。(提示:注意符号的变化)#include void main() { int i,t=1,s=0; /* t标识正负符号*/ for (i=1;i<101; i+=2) /*error*/ { s+=i*t; t= -t; } printf("s=%d\n",s); } ①请改错,并运行程序。 ②分别用do……while语句和while语句改写以上程序。 题目2:分析程序,运行时输入:24579(注:表示回车换行)。 #include

void main() { int c; while((c=getchar())!='\n') { switch(c-'2') { case 0: case 1: putchar(c+4); case 2: putchar(c+4);break; case 3: putchar(c+3); case 4: putchar(c+2);break; default:putchar(c); } } printf("\n"); } 题目3:下面程序的功能是打印100以内个位数为3且能被3整除的所有数,选择合适的语句填入该空格中。 #include void main() { int i,j; for(i=0;__________________ ;i++) { j=i*10+3; if(__________________) continue; printf("%4d",j); } } 题目4:编程输出:用0~4任意组成无重复数字的三位数?都是多少?每行输出10个数。 #include

队列实验

队列实验 学号:姓名: 一、实验目的: 1.掌握队列的顺序存储结构 2.掌握队列先进先出运算原则在解决实际问题中的应用 二、实验内容: 利用循环顺序队列打印杨辉三角形。杨辉三角形的特点是两个腰上的数字都为1,其它位置上的数字是其上一行中与之相邻的两个整数之和。所以在打印过程中,第i行上的元素要由第i-1行中的元素来生成。在循环队列中依次存放第i-1行上的元素,然后逐个出队并打印,同时生成第i行中间的(n-2)个元素并入队列。打印的杨辉三角形如下所示: 1 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 三、队列顺序存储结构的基本操作: 杨辉三角形输出的行数可以在程序中由输入控制。 队列的基本操作代码参考如下: #include #define TRUE 1 #define FALSE 0 #define MAXSIZE 50 /*队列的最大长度*/ typedef struct { int element[MAXSIZE]; /* 队列的元素空间*/ int front; /*头指针指示器*/ int rear; /*尾指针指示器*/ }SeqQueue;

/*初始化操作*/ void InitQueue(SeqQueue *Q) { /* 将*Q初始化为一个空的循环队列*/ Q->front=Q->rear=0; } /*入队操作*/ int EnterQueue(SeqQueue *Q, int x) { /*将元素x入队*/ if((Q->rear+1)%MAXSIZE==Q->front) /*队列已经满了*/ return(FALSE); Q->rear=(Q->rear+1)%MAXSIZE; /* 重新设置队尾指针*/ Q->element[Q->rear]=x; return(TRUE); /*操作成功*/ } /*出队操作*/ int DeleteQueue(SeqQueue *Q, int *x) { /*删除队列的队头元素,用x返回其值*/ if(Q->front==Q->rear) /*队列为空*/ return(FALSE); Q->front=(Q->front+1)%MAXSIZE; /*重新设置队头指针*/ *x=Q->element[Q->front]; return(TRUE); /*操作成功*/ } /*提取队列的队头元素,用x返回其值*/ int GetHead(SeqQueue *Q, int *x) { if(Q->front==Q->rear) /*队列为空*/ return(FALSE); *x=Q->element[Q->front]; return(TRUE); /*操作成功*/ } 四、打印杨辉三角的函数: void PrintTriangle (int N ) { int i,,n,x,temp; SeqQueue Q;

编译原理实验(递归向下语法分析法实验)附C语言源码-成功测试

实验二递归向下分析法 一、实验目和要求 根据某一文法编制调试递归下降分析程序,以便对任意输入的符号串进行分析。本次实验的目的主要是加深对递归下降分析法的理解。 二、实验内容 (1)功能描述 1、递归下降分析法的功能词法分析器的功能是利用函数之间的递归调用模拟语法树自上而下的构造过程。 2、递归下降分析法的前提改造文法:消除二义性、消除左递归、提取左因子,判断是否为LL(1)文法, 3、递归下降分析法实验设计思想及算法 为G 的每个非终结符号U 构造一个递归过程,不妨命名为U。 U 的产生式的右边指出这个过程的代码结构: 1)若是终结符号,则和向前看符号对照,若匹配则向前进一个符号;否则出错。 2)若是非终结符号,则调用与此非终结符对应的过程。当A的右部有多个产生式时,可用选择结构实现。 具体为: (1)对于每个非终结符号U->u1|u2|…|un处理的方法如下: U( ) { ch=当前符号; if(ch可能是u1字的开头) 处理u1的程序部分; else if(ch可能是u2字的开头)处理u2的程序部分; … else error() } (2)对于每个右部u1->x1x2…xn的处理架构如下: 处理x1的程序; 处理x2的程序; … 处理xn的程序; (3)如果右部为空,则不处理。 (4)对于右部中的每个符号xi ①如果xi为终结符号: if(xi= = 当前的符号) { NextChar();

return; } else 出错处理 ②如果xi为非终结符号,直接调用相应的过程xi() 说明: NextChar为前进一个字符函数。 (2)程序结构描述 程序要求: 程序输入/输出示例: 对下列文法,用递归下降分析法对任意输入的符号串进行分析: (1)E->TG (2)G->+TG|—TG (3)G->ε (4)T->FS (5)S->*FS| / FS (6)S->ε (7)F->(E) (8)F->i 输入出的格式如下: (1)E 盘建立一个文本文档" 222.txt"存储一个以#结束的符号串(包括+—*/()i#),在此位置输入符号串例如:i+i*i# (2)输出结果:i+i*i#为合法符号串备注:输入一符号串如i+i*#,要求输出为“非法的符号串” 函数调用格式、参数含义、返回值描述、函数功能;函数之间的调用关系图。 程序所用主要参数和头文件说明: #include #include #include FILE *fp; //定义一个全局文件指针变量 char ch; //定义一个全局字符变量 #define N 20 //定义一个数组大小常量 char string[N]; //定义一个用于存储算式字符串的数组 char *p; //定义一个全局字符指针变量 函数说明: 1)非终结符函数E() 函数功能描述:根据以上文法要求E->TG,所以从主函数开始调入第一个非终结符函数执行,显示调用产生式,依次嵌套调用非终结符函数T()和G(),进行递归向下分析。 void E(){printf("E--->TG..............%c\n",ch); T(); G();}

计算机实验报告

实验指导 实验一 Visual C++开发环境使用 大气科学专业实验日期 4月 18日姓名:学号 1.实验目的 (1)熟悉Visual C++集成开发环境。 (2)掌握C语言程序的书写格式和C语言程序的结构。 (3)掌握C语言上机步骤,了解C程序的运行方法。 (4)能够熟练地掌握C语言程序的调试方法和步骤 2. 实验内容 输入如下程序,实现两个数的乘积。 #include ; int main() { x=10,y=20 p=prodct(x,t) printf("The product is : ",p) int prodct(int a ,int b ) int c c=a*b return c } (1)在编辑状态下照原样键入上述程序。 (2)编译并运行上述程序,记下所给出的出错信息。 (3)再编译执行纠错后的程序。如还有错误,再编辑改正,直到不出现语法错误为止。 3.分析与讨论 (1)记下在调试过程中所发现的错误、系统给出的出错信息和对策。分析讨论成功或失败的原因。(2)总结C程序的结构和书写规则。 实验心得: 通过本次实验,我了解到C语言的特点,初步认识程序设计方法和程序设计一般步骤,掌握C语言程序编译、链接和运行过程,为我进一步学好C语言打下了基础。

实验二数据类型、运算符和表达式 大气科学专业实验日期4 月 25日姓名:刘园园学号327 1.实验目的 (1)理解常用运行符的功能、优先级和结合性。 (2)熟练掌握算术表达式的求值规则。 (3)熟练使用赋值表达式。 (4)理解自加、自减运算符和逗号运算符 (5)掌握关系表达式和逻辑表达式的求值 2.实验内容 (1)整数相除 #include<> int main() { int a=5,b=7,c=100,d,e,f; d=a/b*c; e=a*c/b; f=c/b*a; printf("d=%d , e=%d ,f=%d\n",d,e,f); return 0; } (2)自加、自减运算 #include<> int main() { int a=5,b=8; printf("a++=%d\n",a++);

队列实现杨辉三角

Main:

queue.h: typedef int ElemType; typedef struct Inode{ ElemType data; struct Inode *next; }Inode; typedef struct linkque{ Inode *front; Inode *rear; }linkque; int QueInit(linkque &); int QueIn(linkque &,ElemType); int QueOut(linkque &,ElemType &); app.cpp: #include #include #include #include "queue.h" void main(){ linkque q1,q2; int i,n; ElemType e,e1,e2,e3; printf("请输入需要的杨辉三角长度:\n"); scanf("%d",&n); QueInit(q1); QueInit(q2); for(i=1;i<=n;i++){ e3=0; while(q1.front!=q1.rear){ QueOut(q1,e1); e2=e3+e1; printf("%d\t",e2); QueIn(q2,e2); e3=e1; } if(q1.front==q1.rear){ e2=1; QueIn(q2,e2);

printf("%d",e2); printf("\n"); } while(q2.front!=q2.rear){ QueOut(q2,e); QueIn(q1,e); } } } queue.cpp: #include #include #include #include "queue.h" int QueInit(linkque &q){ q.front=(Inode *)malloc (sizeof(Inode)); q.rear=q.front; if(!q.front){ printf("溢出"); return (0); } q.front->next=NULL; return (1); } int QueIn(linkque &q,ElemType e){ Inode *p; p=(Inode *)malloc (sizeof(Inode)); if(!p) return (0); p->data=e; p->next=NULL; q.rear->next=p; q.rear=p; return (1); } int QueOut(linkque &q,ElemType &e){ Inode *p;

04.递归算法讲解

1.用递归法计算n! 【讲解】 递归是算法设计中的一种基本而重要的算法。递归方法即通过函数或过程调用自身将问题转化为本质相同但规模较小的子问题,是分治策略的具体体现。 递归方法具有易于描述、证明简单等优点,在动态规划、贪心算法、回溯法等诸多算法中都有着极为广泛的应用,是许多复杂算法的基础。 递归概述 一个函数在它的函数体内调用它自身称为递归(recursion)调用。是一个过程或函数在其定义或说明中直接或间接调用自身的一种方法,通常把一个大型复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解。递归策略只需少量的程序就可描述出解题过程所需要的多次重复计算,大大地减少了程序的代码量。递归的能力在于用有限的语句来定义对象的无限集合。用递归思想写出的程序往往十分简洁易懂。一般来说,递归需要有边界条件、递归前进段和递归返回段。当边界条件不满足时,递归前进;当边界条件满足时,递归返回。 使用递归要注意以下几点: (1)递归就是在过程或函数里调用自身; (2)在使用递增归策略时,必须有一个明确的递归结束条件,称为递归出口。 例如有函数r如下: int r(int a) { b=r(a?1); return b; } 这个函数是一个递归函数,但是运行该函数将无休止地调用其自身,这显然是不正确的。为了防止递归调用无终止地进行,必须在函数内有终止递归调用的手段。常用的办法是加条件判断,满足某种条件后就不再作递归调用,然后逐层返回。 构造递归方法的关键在于建立递归关系。这里的递归关系可以是递归描述的,也可以是递推描述的。 例4-1 用递归法计算n!。 n!的计算是一个典型的递归问题。使用递归方法来描述程序,十分简单且易于理解。 (1)描述递归关系 递归关系是这样的一种关系。设{U 1,U 2 ,U 3 ,…,U n ,…}是一个序列,如果从某一项k开始, U n 和它之前的若干项之间存在一种只与n有关的关系,这便称为递归关系。 注意到,当n≥1时,n!=n*(n?1)!(n=0时,0!=1),这就是一种递归关系。对于特定的k!,它只与k与(k?1)!有关。 (2)确定递归边界 在步骤1的递归关系中,对大于k的U n 的求解将最终归结为对U k 的求解。这里的U k 称 为递归边界(或递归出口)。在本例中,递归边界为k=0,即0!=1。对于任意给定的N!,程序将最终求解到0!。 确定递归边界十分重要,如果没有确定递归边界,将导致程序无限递归而引起死循环。例如以下程序: #include int f(int x) { return(f(x?1));}

实验报告1

南京工程学院 实验报告 程序设计语言-JA V A 开课院系:经济管理学院 实验:() 班级:K信管101 学生姓名:顾永晨 学号:240103824

JAVA语言课程实验报告

一、实验目的及要求 熟悉JDK环境,掌握Jcreator的使用方法,理解Java 应用程序的运行原理和方法。 二、实验设备(环境)及要求 JDK;Jcreator;Windows 操作系统 三、实验内容与步骤 1、编辑、编译、运行以下程序,说出程序的功能。改变变量n的初值,观察运行结果有何变化。 public class Sum10_for { public static void main(String args[]) { int i=1,n=10,s=0; System.out.print("Sum("+n+") = "); for (i=1;i

继续执行do……while语句因为e不为0 DeQueue(); 删除队首元素,并将queue[2]赋值s front=3 GetHead(); 取队首元素,e= queue[front]=queue[3]=1 if(e!=0) printf("%6d",e); e!=0 打印e 即1 EnQueue(); 在队尾添加元素s+e 此时queue[rear]=queue[0]=2 rear=1 继续执行do……while语句因为e不为0 DeQueue(); 删除队首元素,并将queue[3]赋值s front=4 GetHead(); 取队首元素,e= queue[front]=queue[4]=0 if(e!=0) printf("%6d",e); e==0 不执行printf()语句 EnQueue(); 在队尾添加元素s+e 此时queue[rear]=queue[1]=1 rear=2 此时e==0跳出do……while语句 即打印第一行完毕输出: 1 1 UpQueue(); 在队尾添加元素0 即queue[rear]=queue[2]=0 rear=3 队列为: 2 1 0 1 0 1 puts("");//每行后回车换行rear front

杨辉三角的各种算法实现

/* Name: 杨辉三角算法集锦 Copyright: 始发于goal00001111的专栏;允许自由转载,但必须注明作者和出处Author: goal00001111 Date: 27-11-08 19:04 Description: 分别使用了二维数组,一维数组,队列,二项式公式,组合公式推论和递归方法等9种算法 算法思路详见代码注释——注释很详细,呵呵 */ #include #include using namespace std; const int MAXROW = 40; void PrintBlank(int n); int Com(int n, int m); int Try(int row, int cel); void Fun_1(int row); void Fun_2(int row); void Fun_3(int row); void Fun_4(int row); void Fun_5(int row); void Fun_6(int row); void Fun_7(int row); void Fun_8(int row); void Fun_9(int row); int main() { int row; cin >> row; Fun_1(row); cout << endl; Fun_2(row); cout << endl; Fun_3(row); cout << endl; Fun_4(row); cout << endl; Fun_5(row);

cout << endl; Fun_6(row); cout << endl; Fun_7(row); cout << endl; Fun_8(row); cout << endl; Fun_9(row); system("pause"); return 0; } //输出n个空格 void PrintBlank(int n) { for (int i=0; i

计算机实验报告

实验指导 实验一 Visual C++6.0开发环境使用 大气科学专业实验日期 4月 18日姓名:学号1.实验目的 (1)熟悉Visual C++6.0集成开发环境。 (2)掌握C语言程序的书写格式和C语言程序的结构。 (3)掌握C语言上机步骤,了解C程序的运行方法。 (4)能够熟练地掌握C语言程序的调试方法和步骤 2. 实验内容 输入如下程序,实现两个数的乘积。 #include (stdio.h); int main() { x=10,y=20 p=prodct(x,t) printf("The product is : ",p) int prodct(int a ,int b ) int c c=a*b return c } (1)在编辑状态下照原样键入上述程序。

(2)编译并运行上述程序,记下所给出的出错信息。 (3)再编译执行纠错后的程序。如还有错误,再编辑改正,直到不出现语法错误为止。

3.分析与讨论 (1)记下在调试过程中所发现的错误、系统给出的出错信息和对策。分析讨论成功或失败的原因。(2)总结C程序的结构和书写规则。 实验心得: 通过本次实验,我了解到C语言的特点,初步认识程序设计方法和程序设计一般步骤,掌握C语言程序编译、链接和运行过程,为我进一步学好C语言打下了基础。

实验二数据类型、运算符和表达式 大气科学专业实验日期4 月 25日姓名:刘园园学号20151301327 1.实验目的 (1)理解常用运行符的功能、优先级和结合性。 (2)熟练掌握算术表达式的求值规则。 (3)熟练使用赋值表达式。 (4)理解自加、自减运算符和逗号运算符 (5)掌握关系表达式和逻辑表达式的求值 2.实验内容 (1)整数相除 #include int main() { int a=5,b=7,c=100,d,e,f; d=a/b*c; e=a*c/b; f=c/b*a; printf("d=%d , e=%d ,f=%d\n",d,e,f); return 0; } (2)自加、自减运算 #include int main() { int a=5,b=8; printf("a++=%d\n",a++); printf("a=%d\n",a); printf("++b=%d\n",++b); printf("b=%d\n",b); return 0; }

实验二 栈与队列操作实验题目

实验二栈与队列操作 实验目的: (1)理解栈与队列的结构特征和运算特征,以便在实际问题背景下灵活运用。 (2)了解复杂问题的递归算法设计。 本次实验中,下列实验项目选做一。 1、顺序栈的基本操作 [问题描述] 设计算法,实现顺序栈的各种基本操作 [基本要求] (1)初始化栈s。 (2)从键盘输入10个字符以$结束,建立顺序栈。 (3)从键盘输入1个元素,执行入栈操作。 (4)将栈顶元素出栈。 (5)判断栈是否为空。 (6)输出从栈顶到栈底元素。 要求程序通过一个主菜单进行控制,在主菜单界面通过选择菜单项的序号来调用各功能函数。 2、链栈的基本操作 [问题描述] 设计算法,实现链栈的各种基本操作 [基本要求] (1)初始化栈s。 (2)从键盘输入10个字符以$结束,建立带头结点的链栈。 (3)从键盘输入1个元素,执行入栈操作。 (4)完成出栈操作。 (5)判断栈是否为空。 (6)输出从栈顶到栈底元素。 (7)输出链栈的长度。 要求程序通过一个主菜单进行控制,在主菜单界面通过选择菜单项的序号来调用各功能函数。 3、循环队列的基本操作 [问题描述] 设计算法,实现循环顺序队列的建立、入队、出队等操作。 [基本要求] (1)从键盘输入10个字符以$结束,建立循环队列,并显示结果。 (2)从键盘输入1个元素,执行入队操作,并显示结果。 (3)将队头元素出队,并显示结果。 (4)要求程序通过一个主菜单进行控制,在主菜单界面通过选择菜单项的序号来调用各功能函数。

4、只用尾指针表示的循环链表队列的综合操作 [问题描述] 假设以带头结点的的循环链表表示队列,并且只设一个指针指向队尾元素的结点(注意不设头指针),试编写队列初始化、入队、出队函数。 [基本要求及提示] (1)首先定义链表结点类型。 (2)编写带头结点的循环链表的初始化函数,只用尾指针表示。 (3)编写入队函数、出队函数。 (4)在主函数中编写菜单(1.初始化;2.入队;3.出队;4.退出),调用上述功能函数。 5、用标志域表示队空队满状态的循环队列的综合操作 [问题描述] 要求循环队列不损失一个空间全部都得到利用,设置一个标志域tag,以0和1来区分当队头与队尾指针相同时队列状态的空和满,试编写与此结构相对应的入队和出队操作。 [基本要求及提示] (1)教材中为区分当队头与队尾指针相同时队列状态的空和满,以牺牲一个空间的代价来实现的,空:Q->front==Q->rear,满:(Q->rear+1)%MAXSIZE==Q->front。 (2)本题不损失一个空间全部都得到利用,为此如下定义循环队列类型: Typedef struct { QueueElementType element[MAXSIZE]; int front; int rear; int tag; }SeqQueue; 此时,循环队列空和满的条件分别为: Q->front==Q->rear&&tag==0 和 Q->front==Q->rear&&tag==1 (3)编写入队函数、出队函数。 (4)在主函数中编写菜单(1.入队;2.出队;3.退出),调用上述功能函数。 6、利用辅助数组进行栈的逆置 [问题描述] 利用辅助栈将栈中的元素逆置。 [基本要求及提示] 在主函数中编写菜单(1.入栈;2.出栈;3.逆置;4.退出)调试运行程序。 7、利用辅助栈进行队列的逆置 [问题描述] 利用辅助栈进行队列元素逆置。 [基本要求及提示] 在主函数中编写菜单(1.入队;2.出队;3.逆置;4.退出)调试运行程序。 8、Hanoi塔问题

c语言实验报告

C程序设计课程 实验报告册 所在学院________________ 班级________________ 学号________________ 姓名________________ 教师________________ 2016 年6 月

《C语言程序设计》实验报告(1 )学号:姓名:班级:成绩:

2. 编写一个函数prim,要求判定正整数n是否为素数,调用上述函数,按每行8个输出2到200 之间所有素数。 (源程序上传文件名为:您自己的学号+实验报告1-2.c,例如:10151234实验报告1-2.c)代码: 程序运行结果截图(要体现出您的学号和姓名): 四、实验收获

《C语言程序设计》实验报告(2 )学号:姓名:班级:成绩:

#20. 出错行号原因正确代码 2、请在函数fun的横线上填写若干表达式,使从键盘上输入一个整数n,输出斐波纳契数列。斐波纳契数列是一种整数数列,其中每数等于前面两数之和,如:0 1 1 2 3 5 8 13……,请上机调试该程序验证自己的填充。 (源程序上传文件名为:您自己的学号+实验报告2-1.c,例如:10151234实验报告2-1.c) #include int fun(int n); main() { int i, n = 0; scanf("%d", &n); for (i=0; i

杨辉三角形实验报告

题目:编写程序,根据输入的行数,屏幕显示杨辉三角形(Pascal’s triangle) 班级:自动化05 姓名:刘丽丽 学号:10054107 完成日期:2011.12.20 一.需求分析 1、本演示程序中,利用顺序队列打印杨辉三角。杨辉三角的特 点是两个腰上的数字都为1,其它位置上的数字是其上一行 中与之相邻的两个整数之和,故在打印过程中,第i行上的 元素要由第i-1行中的元素来生成。这是一个基于队列的操 作来实现杨辉三角不断生成的过程。 2、此次输出的杨辉三角不需要只有一个1的第一行,但只需对 输出实际杨辉三角的程序稍作修改即可; 3、在计算机终端上显示"提示信息"之后,由用户在键盘上输入 演示程序中需要输入的数据,以“回车符”为结束标志。相 应的输入数据和运算结果显示在其后。 4、程序执行的命令包括: 1)构造顺序队列; 2)分析第 i 行元素与第 i+1行元素的关系

目的是从前一行的数据可以计算下一行的数据 从第i 行数据计算并存放第i+1行数据 5、 测试数据 输入行数 n=3; 输出结果为: 1 1 1 2 1 1 3 3 1 二. 概要设计 链队列的抽象数据类型定义为: ADT Queue{ 数据对象 :D={ai| ai ∈Elemset ,i=1,2,3,···n ,n >=0} 1 1 i = 1 1 2 1 2 1 3 3 1 3 1 4 6 4 1 4 1 5 10 10 5 1 5 1 6 15 20 15 6 1 6

数据关系:R={<ai-1 ,ai>| ai-1 ,ai∈D,i=1,2,···n} (约定其中ai端为队列头,an端为队列尾) 基本操作: InitQueue(&Q) 操作结果:构造一个空队列 DestroyQueue(&Q) 初始条件:队列已存在 操作结果:队列被销毁 ClearQueue(&Q) 初始条件:队列已存在 操作结果:将Q清空 QueueEmpty(Q) 若队为空,则返回为TRUE,否则返回为FALSE。Queuelength(Q) 初始条件:队列已存在 操作结果:返回Q的元素个数 Gethead(Q,&e) 初始条件:队列非空 操作结果:用e返回Q的队首元素 Enqueue(&Q,&e) 初始条件:队列已存在 操作结果:插入的元素e为Q的新队首元素

杨辉三角队列实现

杨辉三角显示实验报告 1.问题描述: 编写程序,根据输入的行数,屏幕显示杨辉三角。 2.基本要求: (1)行数不大于20行。 (2)基于队列的操作来实现杨辉三角的不断生成过程。(注:不要用其它的公式计算的方法或者二维数组来实现) (3)基于数组实现队列的物理数据结构 3.需求分析: 1、输入形式:输入一个整数n ,0<=n<=20 2、输出形式:打印出来前(n+1)行的杨辉三角数列 3、功能实现:输出前20层的杨辉三角序列 4、样例输入输出:(数据加强版) 输入:10 输出: 1 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

1 7 21 35 35 21 7 1 1 8 28 56 70 56 28 8 1 1 9 36 84 126 126 84 36 9 1 5、效率分析:O(n) 4.概要设计: 利用到队列先进先出的性质(First In First Out),基本的算法实现是利用已经进队的元素在其出队之前杨辉三角的下一行数列,----即利用要出队的元素来不断地构造新的进队的元素,即在第N行出队的同时,我们来构造杨辉三角的第N+1行,从而实现打印杨辉三角的目的。 5.详细设计: 算法思想已经在概要设计中提到了,现在通过基于队列基本操作的函数以及程序的模块化思想来实现杨辉三角的打印输出问题。 算法函数描述: 队列类: 队列类的数据成员: int front,rear,//ront和rear分别是指向队头和队尾的指针 maxsize;//队列中的元素数 int* listArray //存放队列中的元素 队列的基本操作: V oid Queue(int ) function://构造一个空队列

ASPNET实验报告

实验1 C#程序设计1(2学时) [实验目的] 了解C#语言的特点。 熟悉C#的开发环境。 掌握用VS2008编写C#基本程序。 [实验内容] 1、循环实现: 2、从键盘输入一行字符串,用数组来存放统计出的字母、数字、空格和其他字符个数。题一 using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace shiyan1 { class Program { static void Main(string[] args) { int x=2, y=1,a=0,b=0; double s = 0, t = 1.0; for (int i = 0; i < 10; i++) { a = x ; b = y; s +=t* a / b; x = a + b; y = a; t = -1.0 * t; } Console.WriteLine("s="+s); Console.ReadKey(); }

} } 题二 public static void Main() { int letters = 0, digits = 0, spaces = 0, others = 0; Console.WriteLine("请输入一个字符串: "); string input = Console.ReadLine(); foreach(char chr in input) { if (char.IsLetter(chr)) letters++; else if (char.IsNumber(chr)) digits++; else if (char.IsWhiteSpace(chr)) spaces++; else others++; } Console.WriteLine("字母的个数为:{0}",letters); Console.WriteLine("数字的个数为:{0}", digits); Console.WriteLine("空格的个数为:{0}", spaces); Console.WriteLine("其他字符的个数为:{0}", others); } 运行结果

相关文档
最新文档