大数阶乘与快速排序算法(汇编)

大数阶乘与快速排序算法(汇编)
大数阶乘与快速排序算法(汇编)

微机原理

课程设计说明书设计题目:大数阶乘与排序

专业

班级

学生

指导教师

2014 年春季学期

目录

目录 (1)

一.课设目的与要求 (2)

1.课设目的 (2)

2.题目要求 (2)

二.基本原理 (2)

1.大数阶乘原理设计 (2)

2.排序原理设计 (2)

三.架构设计 (2)

四.方案实现与测试 (3)

五.分析总结 (9)

六.参考文献 (9)

一.课设目的与要求

1.课设目的:检验和提高学生在汇编语言程序设计,微机原理与接口应用方面分析问

题与解决问题的能力

2.题目要求:

1).要求实现用汇编语言编写设计一个求解大数的阶乘精确值的程序;采用字节型数组

存放阶乘结果的每个数字位,采用逐位相乘,再对每一位规格化来实现;输出结成结果的位数及尾零的个数。

2).用汇编语言编写设计快速排序与希尔排序程序,注意合理使用堆栈,以避免堆栈溢

出,进一步动态显示排序过程。

二.基本原理

1.大数阶乘原理设计:我们在处理一个大于一定范围的数的阶乘时,无论使用什么类型去保存运算结果都必然会发生溢出,这势必会导致运算结果出错。使用数组来模拟数字,这样无论结果数字有多大,只要数组的长度够长就能表示出来,用这个办法可以进行大数据的运算。

2.排序原理设计:快速排序原理:首先任意选取一个数据(通常选用数组的第一个数)作为关键数据,然后将所有比它小的数都放到它前面,所有比它大的数都放到它后面,这个过程称为一趟快速排序。

三.架构设计

核心思想就是把计算结果每一位上的数字保存到一个数组成员中,例如:

把112保存至数组中,保存结果应该是

result[0] 2

result[1] 1

result[2] 1

把整个数组看成一个数字,这个数字和一个数相乘的时候,需要每一位都和这个乘数进行相乘运算还需要把前一为的进位加上。运算方法和小学数学是一样的,乘积的个位是当前位上应该表示的数字,10位以上的需要进位。因为乘数不可能大于10000,所以乘数和一个小于10的书相乘的时候不会大于100000,再加上前一位的进位用一个int型数据来保持这个结果就没有问题。写法如下:

int 结果= result[x] * 乘数+ 进位;

每一位的计算结果有了,把这个结果的个位数拿出来放到这个数组元素上:

result[x] = 结果%10;

接下来的工作就是计算出进位:

进位= 结果/ 10;

这样一位一位的把整个数组计算一遍,最后可能还有进位,用同样的方法,把进位的数值拆成单个数字,放到相应的数组元素中。

最后输出一下结果,从最高位吧数字打印一遍就OK了。

一趟快速排序的算法是:

1)设置两个变量i、j,排序开始的时候:i=0,j=N-1;

2)以第一个数组元素作为关键数据,赋值给key,即key=A[0];

3)从j开始向前搜索,即由后开始向前搜索(j--),找到第一个小于key的值A[j],将A[j]赋给A[i];

4)从i开始向后搜索,即由前开始向后搜索(i++),找到第一个大于key的A[i],将A[i]赋给A[j];

5)重复第3、4步,直到i=j; (3,4步中,没找到符合条件的值,即3中A[j]不小于key,4中A[i]不大于key的时候改变j、i的值,使得j=j-1,i=i+1,直至找到为止。找到符合条件的值,进行交换的时候i, j指针位置不变。另外,i==j这一过程一定正好是i+或j-完成的时候,此时令循环结束)。

希尔排序原理:先取一个小于n的整数d1作为第一个增量,把文件的全部记录分组。所有距离为d1的倍数的记录放在同一个组中。先在各组内进行直接插入排序;然后,取第二个增量d2

四.方案实现与测试

大数阶乘源代码:

include io32.inc

.data

infoMsg byte '请输入你要求的阶乘',13,10,0

errorMsg byte '你输入的数小于0',13,10,0

account byte '阶乘的位数为:',13,10,0

zeroaccount byte '尾零的个数为:',13,10,0

inputnum dword 0

bufferNum dword 100000 dup (0),0

temp dword 0

arrayNum dword 1

carry dword 0

.code

start:

mov eax,1

mov bufferNum[0],eax

mov eax,offset infoMsg

call dispmsg

call readsid

mov inputnum ,eax

cmp eax,0

jl DONE;输入的数小于0;输入的数不小于0

mov ebx,2

OUTER:

cmp ebx,inputnum

jg FINISH;完成计算外层循环用ebx

mov ecx,1

mov eax,0

mov carry,eax

FLAG1:

cmp ecx,arrayNum

jg OUTIN;大于1跳出内循环内层循环用ecx

mov eax,ebx

mul bufferNum[ecx*4-4]

add eax,carry

adc edx,0;还要加进位标志,也就是说加了上一步的进位push ebx

mov ebx,0ah

div ebx

pop ebx

mov bufferNum[ecx*4-4],edx

mov carry,eax

inc ecx

jmp FLAG1

OUTIN:

cmp carry,0

jz FLAG2

mov eax,1

add arrayNum,eax;所用到的数组的个数

mov edx,0

mov eax,carry

push ebx

mov ebx,0ah

div ebx

pop ebx

push edx

mov eax,arrayNum

push ebx

mov ebx,04h

mul ebx

pop ebx

sub eax,4

pop edx

mov bufferNum[eax],edx;保存余数到数组

mov edx,0

mov eax,carry

push ebx

mov ebx,0ah

div ebx

pop ebx

mov carry,eax

jmp OUTIN ;循环保存余数直到进位只剩个位FLAG2:

inc ebx

jmp OUTER

FINISH:

;输出结果

mov ecx,arrayNum

FLAG3:

cmp ecx,0

jle OVER

mov eax,bufferNum[ecx*4-4]

call dispsid

mov eax,0

dec ecx

jmp FLAG3

DONE:

cmp edi,0

je OVER

mov eax,offset errorMsg

call dispmsg

OVER:

call dispcrlf

MOV eax,offset account

call dispmsg

MOV eax,arrayNum

call dispuid

call dispcrlf

mov ecx,1

mov edi,0

zero:

mov eax,bufferNum[ecx*4-4]

cmp eax,0

jne F0

inc edi

inc ecx

cmp ecx,arrayNum

jge F0

jmp zero

F0:

MOV eax,offset zeroaccount

call dispmsg

mov eax,edi

call dispuid

call dispcrlf

exit 0

end start

快速排序源代码:

include io32.inc

includelib msvcrt.lib ;这里是引入类库相当于 #include了 printf PROTO C :PTR DWORD, :VARARG ;声明一下我们要用的函数头

MAXSIZE =1000

.data

count dword 0

arrBytes DWORD MAXSIZE dup (0)

szFormat BYTE " %d", 09h, 0

szFormat1 BYTE 0ah, 0 ;换行

in_msg byte '请输入排序数据(-1 结束)',10,13,0

out_msg byte '快速(降序)排序结果如下:',10,13,0

notice byte '.........testing........',10,13,0

.code

dumparray PROC array:PTR DWORD, arrsize:DWORD

mov eax,offset notice

call dispmsg

mov EBX, offset arrBytes

mov ECX, arrsize

xor ESI, ESI

Tag1:

push ecx

INVOKE printf, OFFSET szFormat, DWORD PTR [EBX+ESI] pop ecx

add ESI, 4

LOOP Tag1

INVOKE printf, OFFSET szFormat1

RET

dumparray ENDP

readInArray proc pCount:DWORD

xor ebx,ebx

mov eax,offset in_msg

call dispmsg

xor eax,eax

call readsid

cmp eax,0

jl DONE

mov arrBytes[4*ebx],eax

inc ebx

jmp again

DONE:

mov count,ebx

ret

readInArray endp

qsort PROC array:PTR DWORD, lowitem:DWORD, highitem:DWORD LOCAL pivot:DWORD ;定义局部变量

MOV EBX, array

MOV EDX, lowitem

MOV ESI, lowitem

MOV EDI, highitem

CMP ESI, EDI

JGE TagEnd

MOV EAX, DWORD PTR [EBX+EDX*4]

MOV pivot, EAX

MOV EAX, EDI

SUB EAX, ESI

MOV ECX, EAX

INC EDX

Tag1:

MOV EAX, pivot

CMP EAX, DWORD PTR [EBX+EDX*4]

JL Tag2

JMP Tag3

Tag2:

MOV EAX, DWORD PTR [EBX+EDX*4]

XCHG EAX, DWORD PTR [EBX+ESI*4+4]

MOV DWORD PTR [EBX+EDX*4], EAX

MOV EAX, DWORD PTR [EBX+ESI*4]

XCHG EAX, DWORD PTR [EBX+ESI*4+4]

MOV DWORD PTR [EBX+ESI*4], EAX

INC ESI

INC EDX

LOOP Tag1

DEC ESI

PUSH ESI

INVOKE qsort, array, lowitem, ESI

POP ESI

INC ESI

INC ESI

INVOKE qsort, array, ESI, highitem

TagEnd:

RET

qsort ENDP

main :

invoke readInArray ,addr count

xor eax,eax

INVOKE dumparray, ADDR arrBytes, count MOV EAX, count

DEC EAX

INVOKE qsort, ADDR arrBytes, 0, EAX

mov eax,offset out_msg

call dispmsg

INVOKE dumparray, ADDR arrBytes, count RET

end main

大数阶乘测试结果截图:

快速排序测试结果截图:

五.分析总结

经过了一周的努力,我们终于完成本次课设任务。看似普普通通的题目真正动起手来还真心无从下手,困难重重。比如说是大数阶乘,首先由于它和我们传统意义上计算阶乘有着很大的区别,所以接受一个新的理念就是一件难事,然后把其转换为程序代码的操作又是一大难事。所以以后要多多动手,想的和做的还有很大区别。总之我们这周收获挺大,复习了算法,熟悉了汇编。

六.参考文献

【1】钱晓捷,《微机原理与接口技术》,西安,机械工业出版社,2008年

【2】胡元义,《数据结构教程》,西安,西安电子科技大学出版社,2010年

阶乘运算

//阶乘各算法的 C++ 类实现 #include #include #include #include using namespace std; class Factorial { static const int MAXN = 5001; // 最大阶乘数,实际用不到这么大int *data[MAXN]; // 存放各个数的阶乘 int *nonzero; // 从低位数起第一个非0数字 int maxn; // 存放最大已经计算好的n的阶乘int SmallFact(int n); // n <= 12的递归程序 void TransToStr(int n, int *s); // 将数n倒序存入数组中 void Multply (int* A, int* B, int* C, int totallen); // 执行两个高精度数的乘法public: Factorial(); ~Factorial(); void Calculate(int n); // 调用计算阶乘 int FirstNonZero(int n); // 返回阶乘末尾第一个非0数字int CountZeros(int n); // 返回阶乘末尾有多少个0 int SecondNum(int n); // 返回阶乘左边的第二个数字 bool CanDivide(int m, int n); // 判断数值 m 是否可以整除 n! void Output(int n) const; }; int Factorial::SmallFact(int n) { if (n == 1 || n == 0) return 1; return SmallFact(n-1)*n; } void Factorial::TransToStr(int n, int *tmp) { int i = 1; while (n) { tmp[i++] = n%10; n /= 10; } tmp[0] = i-1; } void Factorial::Multply (int* A, int* B, int* C, int totallen) { int i, j, len; memset(C, 0, totallen*sizeof(int));

阶乘的计算和处理程序设计

阶乘的计算及处理程序设计 一、问题描述 要求输入一个自然数n,求n!,同时统计结果中有几个0。 二、课题分析 1)计算n!。 2)统计0的个数。 三、数据结构的设计 x:输入的数n i:n! b:储存数据i上的各位上的数,从而判断b是否为0 j:统计0的个数 四、处理结构的设计 建立两个函数f1和f2,使f1函数起到求阶乘的作用,f2函数起到求0个数的作用。

求阶乘流程图

计算0的个数流程 五、源程序 1)主要结构体: f1函数: long int f1(int x) { long int i; //声明长整型变量i if (x==0||x==1) //采用递归函数f1求阶乘i=1; else i=f1(x-1)*x; return (i); }

f2函数: int f2(int i) {int j=0; int b=0; while(i>=10) //循环结构,判断末位是否为零,再去末位{b=i %10; if(b==0)j++; i=i/10; } return (j); } 2)整体: #include long int f1(int x) { long int i; if (x==0||x==1) i=1; else i=f1(x-1)*x; return (i); } int f2(int i) {int j=0; int b=0; while(i>=10) {b=i %10; if(b==0)j++; i=i/10; } return (j); } void main() {long int f1(int x); int f2(int x); long int k; int n,i; printf("please input n:"); scanf("%d",&n); k=f1 (n); i=f2 (k); printf("%d! is %ld\nthere are %d zero!\n",n,k,i);

冒泡排序的算法及其程序实现

冒泡排序的算法及其程序实现 浙江省慈溪中学施迪央 教学分析: 本节课是浙江教育出版社出版的普通高中课程标准实验教科书《算法与程序设计》第二第3节以及第五章第3节的部分教学内容。 一组不长的数据(如5个),从小到大排序,对学生来说是一件容易的事情,但他们并不知道计算机是怎么实现排序的,同时他们也没见识过计算机对大量数据(如1000个)的排序。学习排序有助于学生对计算机工作原理的认识。冒泡排序对学生来说初次接触,但前面的枚举算法和解析算法的部分内容对学习排序有一定的帮助,如数组变量的定义及使用方法、双重循环的使用方法及特点以及如何通过键盘输入一批数据(即text1_keypress()事件)在前面都已涉及,冒泡排序的学习又可以巩固前面的知识。 关于冒泡排序的算法及程序实现我安排了3个课时,本案例是在教室内完成的2节随堂课,第3课时安排学生上机实践:对键盘输入的一批数据进行冒泡排序。 教学目标: 1、知识与技能: 了解排序及冒泡排序的概念及特点 掌握冒泡排序算法的原理 初步掌握冒泡排序的程序实现 2、过程与方法: 理解冒泡排序的分析过程,并初步掌握用冒泡排序算法来设计解决简单的排序问题 3、情感态度与价值观: 通过冒泡排序算法的分析过程,培养学生思维的严谨性以及用科学方法解决问题的能力使学生深入理解计算机的工作原理,激发了学生学习程序兴趣。 教学重点: 冒泡排序算法的原理 教学难点: 分析冒泡排序的实现过程 教学策略: 讲授法与探究法。教师讲授、学生听讲,教师提问、学生动脑,层层深入,步步为营,一切水到渠成。 教学准备: 编写好手动输入一批的数据的冒泡排序的程序 编写好计算机自动生成数据的冒泡排序的程序 课堂中使用的教学课件 教学过程: 一、问题引入 问题一:什么是排序? 所谓排序,把杂乱无章的一列数据变为有序的数据,比如7,3,4,8,1这五个数据从小到大排序,结果是1,3,4,7,8,我们很容易排出来。那么电脑是怎么进行排序的呢?问题二:一批数据在VB中如何存储的?比如如何存储六位裁判为一位运动员评出的分数? 用数组变量来存储一批类型、作用相同的数据,如分别用d(1),d(2),d(3),d(4),d(5),d(6)来存储六位裁判给出的分数。 问题三:如果运动员的最后得分是从这6个分数中去掉最高分与最低分后的平均分,你认为

汇编语言实现十个数的排序

DATAS SEGMENT DATA0 DB'Please input a numbers (0-65535):','$' DATA1 DB' over flow input again:','$' DATA2 DB'The num you have put is:',0ah,0dh,'$' DATA3 DB'After exchange the num is:',0ah,0dh,'$' DATA4 DB' ','$' DATA DW 10 DUP(?) DATAS ENDS STACKS SEGMENT DW 256 DUP(?);此处输入堆栈段代码STACKS ENDS CODES SEGMENT ASSUME CS:CODES,DS:DA TAS,SS:STACKS ;/****************************************/ ;-----------程序开始------------ START: MOV AX,DA TAS MOV DS,AX MOV SI,0 MOV CX,10 ;----------循环输入------------ L: CALL INPUT ADD SI,2 CALL NEWLINE LOOP L MOV DX,OFFSET DATA2 MOV AH,9 INT 21H ;-------输入后显示---------- MOV CX,10 MOV DI,0 AGAIN: CALL PRINT CALL SPACE ADD DI,2 LOOP AGAIN ;----------排序-------------

MOV CX,9 MOV DI,0 LOOP0: CALL SORT ADD DI,2 LOOP LOOP0 CALL NEWLINE MOV DX,OFFSET DATA3 MOV AH,9 INT 21H ;----------交换后显示------------- MOV CX,10 MOV DI,0 AGAIN0: CALL PRINT CALL SPACE ADD DI,2 LOOP AGAIN0 ;----------返回系统-------------- EXIT: MOV AH,4CH INT 21H ;/**************************************/ ;------------输入函数-------- INPUT PROC NEAR PUSH AX PUSH BX PUSH CX PUSH DX ;----------提示信息---------- MOV DX,OFFSET DATA0 MOV AH,9 INT 21H MOV BX,0 ;BX存放十进制数 CLC MOV DX,0

计算N的阶乘

北华航天工业学院 课程设计报告(论文) 设计课题:计算N的阶乘 专业班级: 学生姓名: 指导教师: 设计时间:2010年12月16日

北华航天工业学院电子工程系 微机原理与接口技术课程设计任务书 指导教师:刘金梅教研室主任: 2010年12 月18 日

内容摘要 本次课程设计编写计算N!的程序。数值N由键盘输入,结果在屏幕上输出,通过编制一个阶乘计算程序,了解怎样在汇编语言一级上实现高级语言中的数学函数。其难点在于随着N的增大,其结果远非寄存器所能容纳。这就必须把结果放在一个内存缓冲区中。然而乘法运算只限于两个字相乘,因此要确定好算法,依次从缓冲区中取数,进行两字相乘,并将DX中的高16位积作为产生的进位。 索引关键词:N的阶乘汇编语言内存缓冲区

目录 序言————————————————————5 正文————————————————————5 一、程序算法————————————————-—-5 二、源程序—————————————————-—-6 三、程序运行与调试—————————————-—11 四、N的阶乘程序流动图——————————-—-—11 心得体会——————————————————13 参考文献——————————————————13

序言 本文是关于微型计算机原理写文件课程设计。编写程序,将内存区域中用调试程序(DEBUG)设置好的一连串数据(以Ctrl+z为结束符)做为一个文件存入磁盘,文件名为DATA.ASM。内存区域的段地址和偏移地址在程序中输入。 随着计算机的高速发展,微型计算机已经应用到各个领域,微型计算机原理应用技术已经成为电子信息的核心产业。 微型计算机原理是计算机科学与技术、通讯工程、电气工程、机电工程的核心课程。 通过这次课程设计,是我们更好地理解了课程中所学的理论知识,并把实际问题转化为理论知识,学会如何把学到的知识用于解决实际问题,培养我们的动手能力。 正文 一、程序算法 阶乘的定义为N!=N(N-1)(N-2)……2,从左至右依次计算,结果保存在缓冲区BUF中。缓冲区BUF按结果由高到低依次排列。程序首先将BP初始化为N,N 不等于0或1则将N送入BUF缓冲区最低字节单元中。然后使BP为N-1,以后BP依次减1,直到变化为1为止。每次让BP与BUF中的字节单元按由低到高的次序相乘。低位结果AX仍保存在相应的BUF字节单元中,高位结果DX则送到进位字单元CY中,作为高字相乘时从低字来的进位,初始化CY为0.计算结果的长度随着乘积运算而不断增长。由字单元LEN指示。LEN单元初始化为1。当最高字单元与BP相乘时。若DX不为0,则结果长度要扩展。

微机原理-实验一-汇编语言-冒泡排序

微机原理实验报告 班级:XXXXX 姓名:XXXX 学号:20XXXX XXXXX大学 信息科学与技术学院 信息工程系

实验一汇编语言程序设计-(具体题目) 一、实验目的(根据实际情况修改): 1、熟悉MASM编译环境,了解程序的汇编方法; 2、熟悉常用汇编指令,学习汇编程序设计方法; 3、学习汇编语言的调试过程,通过调试过程认识CPU执行程序的方式; 4、了解冒泡法原理,学习多重循环的编程方法。 二、实验内容: 编写程序,用冒泡法实现将数据段内9,8,7,6,5,4,3,2,1按照由小到大的顺序重新排列。 三、程序流程图和程序代码 1、流程图 2、代码与注释(代码不能和指导书完全一样,写出注释,写出寄存器尤其是DS的值)

data segment buf1 db 8,7,6,5,4,3,2,1 data ends code segment assume cs:code,ds:data start: mov ax,data //传送数据段data mov ds,ax mov dx,7 //dx放外循环7次 L3: mov cx,dx //cx放内循环7次 lea si,buf1 //将db里的数据传送到si L2: mov al,[si] cmp al,[si+1] //比较[si]与[si+1] jb L1 //[si]<[si+1],跳转到L1 xchg al,[si+1] //[si]>[si+1],两两交换 mov [si],al L1: inc si //si减1 loop L2 //循环L2 dec dx //外循环减1,没减到0则跳转到L3 jnz L3 //入内循环,计数初值 mov ah,4ch int 21h code ends end start 四、调试过程及遇到的问题 1、程序执行截图

大数阶乘与快速排序算法(汇编)

微机原理 课程设计说明书设计题目:大数阶乘与排序 专业 班级 学生 指导教师 2014 年春季学期

目录 目录 (1) 一.课设目的与要求 (2) 1.课设目的 (2) 2.题目要求 (2) 二.基本原理 (2) 1.大数阶乘原理设计 (2) 2.排序原理设计 (2) 三.架构设计 (2) 四.方案实现与测试 (3) 五.分析总结 (9) 六.参考文献 (9)

一.课设目的与要求 1.课设目的:检验和提高学生在汇编语言程序设计,微机原理与接口应用方面分析问 题与解决问题的能力 2.题目要求: 1).要求实现用汇编语言编写设计一个求解大数的阶乘精确值的程序;采用字节型数组 存放阶乘结果的每个数字位,采用逐位相乘,再对每一位规格化来实现;输出结成结果的位数及尾零的个数。 2).用汇编语言编写设计快速排序与希尔排序程序,注意合理使用堆栈,以避免堆栈溢 出,进一步动态显示排序过程。 二.基本原理 1.大数阶乘原理设计:我们在处理一个大于一定范围的数的阶乘时,无论使用什么类型去保存运算结果都必然会发生溢出,这势必会导致运算结果出错。使用数组来模拟数字,这样无论结果数字有多大,只要数组的长度够长就能表示出来,用这个办法可以进行大数据的运算。 2.排序原理设计:快速排序原理:首先任意选取一个数据(通常选用数组的第一个数)作为关键数据,然后将所有比它小的数都放到它前面,所有比它大的数都放到它后面,这个过程称为一趟快速排序。 三.架构设计 核心思想就是把计算结果每一位上的数字保存到一个数组成员中,例如: 把112保存至数组中,保存结果应该是 result[0] 2 result[1] 1 result[2] 1 把整个数组看成一个数字,这个数字和一个数相乘的时候,需要每一位都和这个乘数进行相乘运算还需要把前一为的进位加上。运算方法和小学数学是一样的,乘积的个位是当前位上应该表示的数字,10位以上的需要进位。因为乘数不可能大于10000,所以乘数和一个小于10的书相乘的时候不会大于100000,再加上前一位的进位用一个int型数据来保持这个结果就没有问题。写法如下: int 结果= result[x] * 乘数+ 进位; 每一位的计算结果有了,把这个结果的个位数拿出来放到这个数组元素上: result[x] = 结果%10; 接下来的工作就是计算出进位: 进位= 结果/ 10; 这样一位一位的把整个数组计算一遍,最后可能还有进位,用同样的方法,把进位的数值拆成单个数字,放到相应的数组元素中。

高中信息技术_冒泡排序算法教学设计学情分析教材分析课后反思

高一冒泡排序教学设计 基本路线:数组-排序-冒泡排序【冒泡排序原理--流程图-算法优化】-小结 一、教材分析:本节内容选自浙江教育出版社《算法与程序设计》第五章第三节。本节课主要讲解冒泡排序思想。排序算法是使用频率最高的算法之一,而冒泡排序是其中一种很典型而且相对简单的方法。它的学习同时为后面的选择排序做了铺垫。 教学目标 知识目标:掌握冒泡排序的原理;掌握冒泡排序的流程图; 能力目标:学会使用冒泡排序思想设计解决简单排序问题的算法;进一步理解程序设计的基本方法,体会程序设计在现实中的作用; 进一步学习流程框图的使用。 情感目标:增强分析问题、发现规律的能力,激发学习热情; 学情分析 通过前面的学习,学生已经了解vb算法设计的基本知识,学会 利用自然语言和流程图描述解决问题的算法,对排序中循环语句以有了一定的基础。但数组变量的使用方法尚未接触,程序设计思想比较弱,在实际生活中往往忽视运用排序算法来处理实际问题,这就要求学生通过本节课的学习,学会运用冒泡排序算法来处理实际问题,并为以后学习其它排序算法打下基础。 二、重点难点 重点:理解冒泡排序原理及它的流程图

难点:理解冒泡排序中的遍、次等概念(即对变量使用的理解)以及用流程图描述冒泡排序的过程 三、教学策略与手段 采用讲解法、演示法、分析归纳法引导学生参与思考,用逐步求精的方式降低学生的理解难度,化抽象为具体,由特殊到一般,有效地突出重点、突破难点。 四、课前准备 1.教师的教学准备:冒泡排序的课件、学案、素材 2.教学环境的设计与布置:多媒体网络教室、电子白板、多媒体教学平台等 五、教学过程 课前学习【设计意图】学生能自己学会的不讲。排序数组知识点相对简单,由学生自学完成,之前的知识点学生可能会有所遗忘,通过这个方式让学生回顾。冒泡排序算法原理比较容易也由学生自学完成。 已给出的素材,完成学案关于数组、冒泡排序和循环结构的基本模式的相关部分的内容,。 请同学们学习学习网站上的课前学习,并完成学案的相关部分的内容。 上课! 对答案。

关于阶乘的程序编写

数的阶乘 很多教材中的阶乘程序只是简单地用了阶乘的定义,算法比较简单,考虑也不够全面,其相应的程序如下: /* 数的阶乘(经典版)*/ #include"stdio.h" main() { extern jiecheng(int n); int n; printf("请输入一个数:"); scanf("%d",&n); jiecheng(n); } extern jiecheng(int n) { long result=1; int i; for(i=1;i<=n;i++) result*=i; printf("该数的阶乘为:%ld\n",result); } 该函数在参数n比较小的时候运行完全正常,但是随着n变大(如,超过12)就出现

了问题,结果会溢出而变成意料之外的数据,究其原因,是因为任何基本类型的变量都有一定的表示范围。要计算更大参数的阶乘,可以使用数组存放阶乘结果,于是有了下面的程序: /* 数的阶乘(改进版)*/ #include"stdio.h" main() { int n; printf("请输入一个数:"); scanf("%d",&n); jiecheng(n); } int jiecheng(int n) { int m,i,j,c,t,a[1000]; a[0]=1; m=1; for(i=2;i<=n;i++) { for(c=0,j=0;j

} while(c) { a[m++]=c%10; c/=10; } } printf("该数的阶乘为:"); for(j=m-1;j>=0;j--) printf("%d",a[j]); printf("\n"); } 这样一来,就可以计算大数的阶乘了。如有疑问,多谢赐教!

采用汇编语言实现阶乘运算

汇编语言程序设计报告 课程设计题目:采用汇编语言实现阶乘运算 学号:10081437 姓名:张子琦 院系:测试与光电工程学院 专业:测控技术与仪器 指导教师:陈振华

采用汇编语言实现阶乘运算 学生姓名:张子琦班级:10081437 指导老师:陈振华 摘要:汇编语言是微型计算机原理及应用的基础,微机主机和接口所要实现的功能都要通过汇编语言来实现。尽管汇编语言程序设计编程效率低,但其运行效率高、速度快。因此掌握汇编语言是学好微机原理和接口设计的第一步。编写计算N!的程序。数值由键盘输入,结果在屏幕上输出。[1] 关键字:汇编语言N!键盘输入屏幕输出 指导老师签名:

Factorial implemented in assembly language Student name :Ziqi Zhang Class:10081437 Supervisor:Zhenhua Chen Abstract:Assembly language is the basis of the principles and applications of the microcomputer, the microcomputer host functions and interfaces to achieve should be achieved through the assembly language. Despite the low efficiency of assembly language programming programming, but it’s high operating efficiency, and speed. Therefore, the assembly language is the first step to learn Microcomputer Principle and Interface Design. Written calculation of N! Procedures. Numerical keyboard input, output results on the screen. Key words:Assembly language N! Keyboard input Screen output Signature of Supervisor:

微机原理实验报告冒泡排序

一、实验目的 (1)学习汇编语言循环结构语句的特点,重点掌握冒泡排序的方法。 (2)理解并掌握各种指令的功能,编写完整的汇编源程序。 (3)进一步熟悉DEBUG的调试命令,运用DEBUG进行调试汇编语言程序。 二、实验内容及要求 (1)实验内容:从键盘输入五个有符号数,用冒泡排序法将其按从小到大的顺序排序。 (2)实验要求: ①编制程序,对这组数进行排序并输出原数据及排序后的数据; ②利用DEBUG调试工具,用D0命令,查瞧排序前后内存数据的变化; ③去掉最大值与最小值,求出其余值的平均值,输出最大值、最小值与平均值; ④用压栈PUSH与出栈POP指令,将平均值按位逐个输出; ⑤将平均值转化为二进制串,并将这组二进制串输出; ⑥所有数据输出前要用字符串的输出指令进行输出提示,所有数据结果能清晰显示。 三、程序流程图Array (1)主程序:MAIN

(2)

就是 NAME BUBBLE_SORT DATA SEGMENT ARRAY DW 5 DUP(?) ;输入数据的存储单元 COUNT DW 5 TWO DW 2 FLAG1 DW 0 ;判断符号标志 FLAG2 DB 0 ;判断首位就是否为零的标志FAULT DW -1 ;判断出错标志 CR DB 0DH,0AH,'$' STR1 DB 'Please input five numbers seperated with space and finished with Enter:','$' STR2 DB 'The original numbers:','$' STR3 DB 'The sorted numbers:','$' STR4 DB 'The Min:','$' STR5 DB 'The Max:','$' STR6 DB 'The Average:','$' STR7 DB 'The binary system of the average :','$' STR8 DB 'Input error!Please input again!''$' DATA ENDS CODE SEGMENT MAIN PROC FAR ASSUME CS:CODE,DS:DATA,ES:DATA START: PUSH DS AND AX,0 PUSH AX MOV AX,DATA MOV DS,AX LEA DX,STR1 MOV AH,09H ;9号DOS功能调用,提示输入数据 INT 21H CALL CRLF ;回车换行 REIN: CALL INPUT ;调用INPUT子程序,输入原始数据CMP AX,FAULT ;判断就是否出错, JE REIN ;出错则重新输入

大数乘法

大数乘法 (一)介绍: 还是模拟的方法,用数组c[] 记录a[] 和b[]的乘积。之后在把c[] 中 的每一位变成个位数就ok 了! (二)代码如下: #include #include using namespace std; char a[100],b[100]; int len_a,len_b; int c[200]; void mul(char a[],char b[],int c[],int l_a,int l_b) { int i,j; for(i=l_a-1;i>=0;i--) { for(j=l_b-1;j>=0;j--) c[i+j+2]+=(a[i]-'0')*(b[j]-'0');//这个操作比较好,保证了相乘之后相加形 //成了错位,易于进行c[]每一位的相加操作} for(i=l_a+l_b;i>0;i--) { c[i-1]+=c[i]/10; c[i]%=10; } bool flag= true; i=0; while(c[i]==0) i++; for(;i<=len_a+len_b;i++) { flag=false; cout<

int main() { cin>>a>>b; len_a=strlen(a),len_b=strlen(b); memset(c,0,sizeof(c)); mul(a,b,c,len_a,len_b); return 0; }

阶乘排列组合公式计算

阶乘排列组合公式计算 加法原理:做一件事,完成它可以有N类加法,在第一类办法中有M1种不同的方法,在第二类办法中有M2种不同的方法,……,在第N类办法中有MN种不同的方法。那么完成这件事共有N=M1+M2+...+MN 种不同的方法。即一次性完成的用加法原理。 乘法原理:做一件事,完成它需要分成N个步骤,做第一步有M1种不同的方法,做第二步有M2种不同的方法,……,做第N步有MN种不同的方法,那么完成这件事共有 N=M1×M2×... ×MN 种不同的方法。即二次以上完成的用乘法原理。 排列:从N个不同元素中,任取M(M<=N)个元素,按照一定的顺序排成一列,叫做从N个不同元素中取出M个元素的一个排列。 排列数:从N个不同元素中取出M(M<=N)个元素的所有排列的个数,叫做从N个不同元素中取出M个元素的排列数。记作:Pmn 排列数公式:Pmn =n(n-1)(n-2)...(n-m+1) 全排列:N个不同元素全部取出的一个排列,叫做N个不同元素的一个全排列。 自然数1到N的连乘积,叫做N的阶乘。记作:n! 。0!=1。 全排列公式:Pnn =n! 排列数公式还可写成:Pmn = n!/(n-m)! 组合:从N个不同元素中,任取M(M<=N)个元素并成一组,叫做从N个不同元素中取出M个元素的一个组合。 排列与元素的顺序有关,组合与元素的顺序无关。 组合数:从N个不同元素中取出M(M<=N)个元素的所有组合的个数,叫做从N个不同元素中取出M个元素的组合数。记作:Cmn 组合数公式:Cmn = Pmn / Pmm = n(n-1)(n-2)...(n-m+1)/m! = n!/m!/(n-m)! 组合性质1:Cmn = Cn-mn ( C0n =1) 组合性质2:Cmn+1 = Cmn + Cm-1n

微机原理实验报告-冒泡排序

一、实验目的 (1)学习汇编语言循环结构语句的特点,重点掌握冒泡排序的方法。 (2)理解并掌握各种指令的功能,编写完整的汇编源程序。 (3)进一步熟悉DEBUG的调试命令,运用DEBUG进行调试汇编语言程序。 二、实验内容及要求 (1)实验内容:从键盘输入五个有符号数,用冒泡排序法将其按从小到大的顺序排序。(2)实验要求: ①编制程序,对这组数进行排序并输出原数据及排序后的数据; ②利用DEBUG调试工具,用D0命令,查看排序前后内存数据的变化; ③去掉最大值和最小值,求出其余值的平均值,输出最大值、最小值和平均值; ④用压栈PUSH和出栈POP指令,将平均值按位逐个输出; ⑤将平均值转化为二进制串,并将这组二进制串输出; ⑥所有数据输出前要用字符串的输出指令进行输出提示,所有数据结果能清晰显示。 三、程序流程图Array(1)主程序:MAIN 否

(2)冒泡排序子程序: SORT 是 否 是 否 是

四、程序清单 NAME BUBBLE_SORT DATA SEGMENT ARRAY DW 5 DUP(?) ;输入数据的存储单元 COUNT DW 5 TWO DW 2 FLAG1 DW 0 ;判断符号标志 FLAG2 DB 0 ;判断首位是否为零的标志 FAULT DW -1 ;判断出错标志 CR DB 0DH,0AH,'$' STR1 DB 'Please input five numbers seperated with space and finished with Enter:','$' STR2 DB 'The original numbers:','$' STR3 DB 'The sorted numbers:','$' STR4 DB 'The Min:','$' STR5 DB 'The Max:','$' STR6 DB 'The Average:','$' STR7 DB 'The binary system of the average :','$' STR8 DB 'Input error!Please input again!''$' DATA ENDS CODE SEGMENT MAIN PROC FAR ASSUME CS:CODE,DS:DATA,ES:DATA START: PUSH DS AND AX,0 PUSH AX MOV AX,DATA MOV DS,AX LEA DX,STR1 MOV AH,09H ;9号DOS功能调用,提示输入数据 INT 21H CALL CRLF ;回车换行 REIN: CALL INPUT ;调用INPUT子程序,输入原始数据 CMP AX,FAULT ;判断是否出错, JE REIN ;出错则重新输入 LEA DX,STR2 MOV AH,09H ;9号DOS功能调用,提示输出原始数据 INT 21H CALL OUTPUT ;调用OUTPUT子程序,输出原始数据 CALL SORT ;调用SORT子程序,进行冒泡排序 LEA DX,STR3 MOV AH,09H ;9号DOS功能调用,提示输出排序后的数据 INT 21H CALL OUTPUT ;调用OUTPUT子程序,输出排序后的数据

大数的阶乘(n!)

信息科学与工程学院 编程设计实验文档 题目:较大数的阶乘 一、设计目的: 1.解决一般大数的阶乘问题,可以避免一般算法实行时的数据溢 出的弊端 2.培养自己对算法的理解,提高自身的水平 3.熟练对c语言的操作,加强对c语言的理解 二、设计分析:

实现一般较小的数的阶乘,可以直接利用普通的乘法进行循环 运算即可,即利用s=n*(n-1)的核心算法。但是,当n比较 大的时候,会造成运算的结果,即s会变得特别大,便会造成 数据溢出。此时,就需要另一种算法,是结果可以保存,不溢 出。那么,这个算法就是要解决这个问题,所以,我想到另一 方式用来解决这个问题,即利用数组。 如下: 首先,定义两个整型的数组: int a[200];//暂且先设定是200位,我称之为“结果数组” int add[200];//我称之为“进位数组” 现在具体说明两个数组的作用: 1.a[200] 比如说,一个数5的阶乘是120,那么我就用这个数组存储它: a[0]=0 a[1]=2 a[2]=1 因此,用这样的数组我们可以放阶乘后是200位的数 2.在介绍add[200]之前,我介绍一下算法的思想,就以6!为 例:

从上面我们知道了5!是怎样存储的。 就在5!的基础上来计算6!,演示如下: fac[0]=fac[0]*6=0 fac[1]=fac[1]*6=12 fac[2]=fac[2]*6=6 3.现在就用到了我们的:“进位数组”add[1000]. 先得说明一下:add[i]就是在第2步中用算出的结果中,第 i位向第i+1位的进位数值。还是接上例: add[0]=0; add[1]=1; // 计算过程:就是 (a[1]+add[0]) % 10=1 add[2]=0; // 计算过程:就是 (a[2]+add[1]) % 10=0 ....... ....... ....... add[i+1] =( a[i+1] + add[i] ) % 10 三、算法流程图

VB程序设计-多种方法求阶乘

VB程序设计-多种方法求阶乘 (作者:草原飞狼 2014年5月26日) 声明:仅供学习与交流使用,高手请飘过,谢谢! 布局 运行界面(1)

运行界面(2) 源代码如下: Private Sub Command1_Click() Rem 求任意数阶乘,不大于171 Dim mul As Double Dim i As Integer Dim k As Integer mul = 1 '赋初值 k = Val(InputBox("请输入一个正整数,不大于171!", "输入提示", "5")) Rem 以下算法是求指定数的阶乘,典型的算法 For i = 1 To k mul = mul * i Next i Print k & "的阶乘结果是:"; mul End Sub Private Sub Command2_Click() Rem 清空 Form1.Cls End Sub Private Sub Command3_Click() Rem 退出 Unload Me End Sub Private Sub Command4_Click()

Rem 普通过程求阶乘 Dim mul As Double Dim i As Integer Dim k As Integer mul = 1 '赋初值 k = Val(InputBox("请输入一个正整数,不大于171!", "输入提示", "5")) Rem 以下算法是求指定数的阶乘 Call fac(k) '函数调用,注意调用方法 Print k & "的阶乘结果是:"; fac(k) End Sub Private Function fac(ByVal k As Integer) As Double 'byval表示参数按值传递Rem 普通的函数过程 Dim i As Integer Dim mul As Double mul = 1 For i = 1 To k mul = mul * i Next i fac = mul '结果返回给函数,典型的用法End Function Private Sub Command5_Click() Rem 递归过程求阶乘 Dim i As Integer Dim k As Integer Dim mul As Double mul = 1 '赋初值 k = Val(InputBox("请输入一个正整数,不大于171!", "输入提示", "5")) Rem 以下递归函数的调用 Call fac_digui(k) Print k & "的阶乘结果是:"; fac_digui(k) End Sub Private Function fac_digui(ByVal k As Integer) As Double Rem 递归过程求阶 Rem 以下是递归算法求阶乘,注意写法,编写递归算法时,方法类似 If k = 1 Then fac_digui = 1 Else fac_digui = fac_digui(k - 1) * k End If End Function

用汇编语言冒泡排序经典程序

data segment A dw 03h, 0dh, 08h, 1dh, 20h, 0fdh ;两个字节保存一个值,对应十进制的3,13,8,29,32,253 data ends code segment main proc far assume cs:code, ds:data start: push ds sub ax, ax ;ax寄存器清零 push ax mov ax, data mov ds, ax mov cx, 7 dec cx ;减1指令 loop1: ;cx=cx-1若cx!=0则继续循环 mov di, cx ;把CX寄存器的值传送到以DS寄存器(默认是DS寄存器)的内容为段值有效地址为DI 的存储单元中 mov bx, 0 loop2: mov ax, a[bx] ;把第bx个数传给ax寄存器 cmp ax, a[bx+2] ;比较第bx个数和第bx+2个数????? jle continue ;jle:小于等于则跳转,否则执行下句 xchg ax, a[bx+2] ;否则两比较数交换位置 mov a[bx], ax continue: add bx, 2 loop loop2 mov cx, di loop loop1 mov cx, 7 mov bx, 0 next: mov ax, [bx] push cx call show pop cx mov ah, 2

mov dl, ' ' int 21h add bx, 2 loop next ret main endp show: ; 显示ax里的值 mov cx, 10 cmp ax, 0 jle done div cl ;除法:被除数在DX,AX中,除数在cl中 push ax xor ah, ah ;xor实现两个操作数按位‘异或’运算,结果送至目的操作数中 call show pop dx mov dl, dh or dl, 30h ;或运算 mov ah, 2 int 21h done: ret code ends end start

微机原理实验报告-冒泡排序

WORD格式 一、实验目的 (1)学习汇编语言循环结构语句的特点,重点掌握冒泡排序的方法。 (2)理解并掌握各种指令的功能,编写完整的汇编源程序。 (3)进一步熟悉DEBUG的调试命令,运用DEBUG进行调试汇编语言程序。 二、实验内容及要求 (1)实验内容:从键盘输入五个有符号数,用冒泡排序法将其按从小到大的顺序排序。(2)实验要求: ①编制程序,对这组数进行排序并输出原数据及排序后的数据; ②利用DEBUG调试工具,用D0命令,查看排序前后内存数据的变化; ③去掉最大值和最小值,求出其余值的平均值,输出最大值、最小值和平均值; ④用压栈PUSH和出栈POP指令,将平均值按位逐个输出; ⑤将平均值转化为二进制串,并将这组二进制串输出; ⑥所有数据输出前要用字符串的输出指令进行输出提示,所有数据结果能清晰显示。 三、程序流程图 开 始(1)主程序:MAIN 初始化 键盘输入数据 调用INPUT子程序 显示输入错误 否 输入是否正确 是 显示原始数据 调用OUTPUT子程序

WORD格式 显示冒泡排序后的数据 调用SORT子程序 调用OUTPUT子程序 显示最小值Min 显示One子程序 显示最大值Max 调用One子程序 显示其余数平均值Average 调用One子程序 显示平均值二进制串Binary 调用One子程序 结束

(2)冒泡排序子程序:SORT COUNT1----外循环次数 进入COUNT2----内循环次数 i----数组下标 初始化 COUNT1=N-1 COUNT2=COUNT1 SI=0 否 Ai≥i A+1 是 Ai与A i+1两数交换 SI=SI+2 COUNT2=COUNT2-1 否 COUNT2=0? 是 COUNT1=COUNT1-1 否 COUNT2=0? 是 返回

经验技巧6-2 大数阶乘优化算法

经验技巧6-2 大数阶乘优化算法 【例6-6】给出了大数阶乘的算法,该算法使用数组存放阶乘的结果,每一个数组元素存放结果的一位。计算十万的阶乘需要近260秒的时间,实际上只要程序中的N足够大,还可以求更大数的阶乘,但程序执行的时间会更长,可能要几个小时,甚至更长,因此需要考虑对算法进行优化。 int型数组的每一个元素可以存放的最大整数为2147483647,是一个十位数,而算法中每一个元素只存放结果的一位,显然太浪费了。 由于算法中需要计算自然数n与数组元素值的乘积加上前一位的进位,所以每个数组元素的位数不能太多,否则将超过最大整数2147483647而导致溢出,如果每个数组元素存放4位数,大约可计算到二十万的阶乘,确保结果是精确的,如果再使用无符号基本整型,大约可计算到四十万的阶乘,确保结果是精确的。 由此,定义符号常量M的值为10000作为模数,符号常量B的值为4表示数组元素存放的最多位数,符号常量N的值为600000表示n!结果位数的B分之一,存放n!结果的数组bit定义为静态无符号基本整型。 计算i!时将原来的用10除处理进位和余数改为用M除。 由于除存放最高位的元素外,每个元素都存放B位,而存放最高位的元素可能不足B位,输出前需先统计存放最高位元素bit[k]的位数,另外,低位的0(只能输出一个0)和不足B位的应使用B个输出域宽,不足的用0补足,才能保证其它各位均输出B位。 其它说明详见程序代码中的注释。 优化的程序代码: (1)#include "stdio.h" (2)#define M 10000//M与n的乘积不能超过4294967295 (3)#define B 4//数组元素存放的最多位数 (4)#define N 600000 //n!的位数,要足够大 (5)int fact(int bit[],int n) (6){ (7)int i,j,k=N-1,carry;//k表示第一个非0元素的下标 (8)bit[k]=1; (9)for(i=2;i<=n;i++) (10){ (11)carry=0;//carry表示进位数,开始进位数为0 (12)for(j=N-1;j>=k;j--) (13){

相关文档
最新文档