数据结构课程设计进制转换.docx
《数据结构课程设计进制转换.docx》由会员分享,可在线阅读,更多相关《数据结构课程设计进制转换.docx(27页珍藏版)》请在冰豆网上搜索。
数据结构课程设计进制转换
数据结构课程设计
设计说明书
进制转换的实现
学生姓名
JUGG
学号
¥#··
班级
Dotaallstar——
成绩
优秀
指导教师
Puck
dota科学与技术
天灾元年3月14日
数据结构课程设计评阅书
题目
进制转换的实现
学生姓名
JUGG
学号
@#%¥#¥%#
指导教师评语及成绩
成绩:
教师签名:
年月日
答辩教师评语及成绩
成绩:
教师签名:
年月日
教研室意见
总成绩:
室主任签名:
年月日
Dotaallstar
课程设计任务书
天灾元年—近卫戊年第二学期
专业:
ganker学号:
sadofaiofo姓名:
课程设计名称:
数据结构课程设计
设计题目:
进制转换的实现
完成期限:
自天灾元年年3月1日至近卫戊年年3月14日共2周
设计依据、要求及主要内容(可另加附页):
进制数制是人们利用符号进行计数的科学方法。
数制有很多种,在计算机中常用的数制有:
十进制,二进制、八进制和十六进制。
十六进制数有两个基本特点:
它由十六个字符0~9以及A,B,C,D,E,F组成(它们分别表示十进制数0~15),十六进制数运算规律是逢十六进一,例如:
十六进制数4AC8可写成(4AC8)16,或写成4AC8H。
要求:
(1)输入一个十进制数N,将它转换成R进制数输出,并可以进行逆转换。
(2)输入数据包含多个测试实例,每个测试实例包含两个整数N(32位整数)和R(2<=R<=16,R<>10)。
(3)为每个测试实例输出转换后的数,每个输出占一行。
如果R大于10,则对应的数字规则参考16进制(比如,10用A表示,等等)。
(4)界面友好。
指导教师(签字):
教研室主任(签字):
批准日期:
年月日
摘要
由于数制计算和不同数制之间转换的需要,设计了一个10进制转换其它进制(36进制以内)及逆转换的软件,该软件具有简单的将10进制数转换成2、8、16进制数以及较复杂的高进制数的转换和逆转功能。
本软件采用C语言编写以VC++作为软件开发环境,采用顺序栈存储方式来存储运算中的数位,借助栈后进先出的特点,易于结果输出。
操作简单,界面清晰,易于为用户所接受。
关键词:
进制转换;顺序栈;逆转换
1课题描述
数制有很多种,在计算机中常用的数制有:
十进制,二进制、八进制和十六进制。
十六进制数有两个基本特点:
它由十六个字符0~9以及A,B,C,D,E,F组成(它们分别表示十进制数0~15),十六进制数运算规律是逢十六进一,例如:
十六进制数4AC8可写成(4AC8)16,或写成4AC8H。
更大一些的数制则扩展十六进制未用的其他大写字母。
顺序栈是顺序存储结构的栈,是利用一组地址连续的存储单元依次存放自栈底到栈顶的数据元素。
同时附设栈顶指针top和栈基指针base,来方便栈内数据元素的存取和栈的扩充。
2问题分析和任务定义
问题分析:
编写进制转换及其逆转,其算法过程恰好是结果的逆序,因此建立一个顺序栈将计算过程中得到的数位顺序进栈,则按出栈顺序就会输出对应的转换结果。
逆转程序借助字符数组按顺序将每个数位转换成十进制数后求和,得到逆转结果
例如:
11转换成二进制数
11%2=1;11/2=5;1入栈;
5%2=1;5/2=2;1入栈;
2%2=0;2/2=0;0入栈;
被除数不为0;
按顺序出栈,得到结果为110;
任务定义:
1)画出流程图;
2)任意建立一个容量为20个栈元素的空栈;
3)将十进制数与要转进制先求余,将余数顺序入栈;
4)阐明测试方法,写出完整的运行结果;
5)撰写课程设计说明书。
3逻辑设计
(1)ADTStack{
数据对象:
D={ai|ai∈ElemSet,i=1,2,…,n,n≥0}
数据关系:
R1={|ai-1,ai∈D,i=2,…,n}
基本操作:
Inistack(&S)
操作结果:
构造一个空栈S。
stackEmpty(&S)
初始条件:
栈S已存在。
操作结果:
判断栈S是否为空,若为空,则返回1;否则返回0.
push(&S,x)
初始条件:
栈S已存在。
操作结果:
插入元素x为新的栈顶元素。
Pop(&S。
&e)
初始条件:
栈S已存在且非空。
操作结果:
删除S的栈顶元素,并用y返回其值。
}ADTStack
(2)主函数流程图如图3.2所示
图3.1创建主函数流程图
(3)十进制转换其他进制数流程图如图3.3所示
图3.2十进制转换其他进制数算法流程图
(4)其他进制数转换十进制数流程图如图3.4所示
图3.3倒序输出算法流程图
4详细设计
本程序主要有三个算法:
一、十进制整数转换其他进制数,其主要思路为:
例如:
11转换成二进制数
11%2=1;11/2=5;
5%2=1;5/2=2;
2%2=0;2/2=0;
被除数不为0;
转换结果为110;
二、十进制小数转换其他进制数,其主要思路为:
例如:
0.125转换成二进制小数
0.125*2=0.25;取结果的整数为0;
0.25*2=0.5;取结果的整数为0;
0.5*2=1.0;取结果的整数为1;
小数部分不为0;
转换结果为0.001;
三、其他数制转换十进制数,其主要思路为:
例如:
二进制数10.1转换成十进制数
1*
=2;
0*
=1;
1*
=0.5;
逆转数字存储在数组中,最后的结束符’\0’,为标志。
转换结果为2+1+0.5=3.5;
5程序编码
#include
#include
#include
#defineSTACK_INIT_SIZE20
#defineSTACKINCREMENT10
typedefintSElemType;
typedefstruct{
SElemType*base,*top;
intstacksize;
}SqStack;
intInitStack(SqStack&S){
S.base=(SElemType*)malloc(STACK_INIT_SIZE*sizeof(SElemType));
if(!
S.base)exit(0);
S.top=S.base;
S.stacksize=STACK_INIT_SIZE;
return1;
}
intPush(SqStack&S,SElemTypee){
if(S.top-S.base>=S.stacksize){
S.base=(SElemType*)realloc(S.base,(S.stacksize+STACKINCREMENT)*sizeof(SElemType));
if(!
S.base)exit(0);
S.top=S.base+S.stacksize;
S.stacksize+=STACKINCREMENT;
}
*S.top++=e;
return1;
}
intPop(SqStack&S,SElemType&e){
if(S.top==S.base)return0;
e=*--S.top;
return1;
}
intStackEmty(SqStackS){
if(S.top==S.base)return1;
elsereturn0;
}
voidXSZZ(doublen,intT){
inti=0;
doublea;
if(n==0.0)printf("00000");
while(n!
=0.0)
{
a=T*n;
n=a-(int)a;
if(a>=10)
{
printf("%c",((int)a-10+'A'));
i++;
}
else{
printf("%d",((int)a>0?
(int)a:
0));
i++;
}
if(i==5)break;
}
}
intNZ(){
inti=0,j,T,k=0;
doublesum=0;
chara[20],X;
getchar();
printf("输入转换数");
while((a[i]=getchar())!
='\n'){
if((a[i]<='9'&&a[i]>='0')||(a[i]<='Z'&&a[i]>='A')||a[i]=='.');
else{break;}
if(a[i]=='.')k=i;
i++;}
k=k?
k:
i;
if(a[i]!
='\n'){
while(getchar()!
='\n');
printf("输入有误");
return0;}
a[i]='\0';
a[k]='\0';
printf("输入转换数的进制");
scanf("%d%c",&T,&X);
if((!
(T>1&&T<36))||X!
='\n'){
while(getchar()!
='\n');
printf("输入有误");printf("sdf%c",X);
return0;}
for(j=0;j{
if(((a[j]-'0'>=T)&&(a[j]<='9'))||((a[j]-'A'+10>=T)&&(a[j]>'9')))
{
printf("输入有误!
");return1;
}
if(a[j]>='A')
sum+=((a[j]-'A'+10)*pow(T,k-j-1));
else
sum+=((a[j]-'0')*pow(T,k-j-1));
}
for(j=k+1;j
{
if(((a[j]-'0'>=T)&&(a[j]<='9'))||((a[j]-'A'+10>=T)&&(a[j]>'9')))
{
printf("输入有误!
");return1;
}
if(a[j]>='A')
sum+=((a[j]-'A'+10)*pow(T,k-j));
else
sum+=((a[j]-'0')*pow(T,k-j));
}
if(!
(((a[j]-'0'>=T)&&(a[j]<='9'))||((a[j]-'A'+10>=T)&&(a[j]>'9'))))printf("结果为%f",sum);
return1;
}
intZZ(){
intN,T,i=0,a;
doubleZ,M;
charX[10];
SElemTypee;
SqStackS;
InitStack(S);
printf("输入转换数:
");
scanf("%lf%c",&Z,&X[0]);
if(X[0]!
='\n'){while(X[i]!
='\n'){
i++;
printf("输入有误!
");return1;}
printf("输入转换进制:
");
scanf("%d%c",&T,&X[0]);
if(T<36&&T>1&&X[0]=='\n')
{printf("%c",X[0]);
N=(int)Z;
M=Z-N;
while(N)
{
if(T>10)
{
a=N%T;
if(a>=10)
{
a=a-10+'A';
Push(S,a);
}
elsePush(S,N%T);
}
elsePush(S,N%T);
N=N/T;
}
printf("结果为:
");
if(StackEmty(S))printf("0");
while(!
StackEmty(S))
{
Pop(S,e);
if(e>=10)printf("%c",e);
elseprintf("%d",e);
}
printf(".");
XSZZ(M,T);
}
else
{printf("输入有误\n");i=0;
while(X[i]!
='\n'){
i++;
scanf("%c",&X[i]);}
}}
main()
{
intchoice;
charX;
do{printf("Press1:
十进制转换其他进制数\nPress2:
其他进制数转换十进制数\n");
scanf("%d",&choice);
switch(choice){
case1:
ZZ();break;
case2:
NZ();break;
default:
printf("输入有误!
");
}
printf("\ncontinue?
y/n\n");
scanf("\t%c",&X);
while(X!
='n'&&X!
='y'){
printf("输入有误!
\n请重新输入:
");
scanf("\t%c",&X);
}
}while(X=='y');
return0;
}
6程序调试与测试
(1)输入十进制14.25转换成十六进制数为E.4.
图6.1十进制转换其他进制数运行图
(2)输入二进制1.1转换为十进制1.5
图6.2其他进制转换十进制数运行图
(3)输入数字字符混合体(非法字符)程序返回错误提示
图6.3程序健壮性测试
(4)程序调试过程修改:
在不同进制数的互转换过程中小数部分尤为不好处理,例如:
三进制数2.1整数部分2无需转换,小数0.1转换结果为1/3纯循环小数。
七进制数6.3、3.1、2.135,这些小数部分根本无法转换成十进制整数,这里不一一赘述,故设定转换结果保留五位小数。
7结果分析
在设计的过程中遇到了许多问题,并最终得到解决,其分析过程如下:
(1)考虑到本程序转换的数字对象并不是天文数字,栈操作定义中,初始化栈空间为20(存储20位数字),但也可能出现空间不足。
解决的办法是当空间不足时自动进行扩充。
(2)程序的健壮性问题。
数据通过一定的形式读入地。
当输入格式有误时就程序无法计算时,返回输入错误重新输入。
(3)程序的循环操作问题。
当输入有误时必须把输入的错误字符读入,再进行下次操作。
时间复杂度T(n)=O(n);
空间复杂度S(n)=O(n);
8总结
本程序实现了数制转换及其逆转换功能,具有强大的健壮性和容错能力。
顺序栈只参与其中的十进制整数转换部分,小数转换部分的算法与整数部分不同所以另成函数体。
逆转换借助数组读入数位进行转换,其整数和小数部分算法相同故属一个函数。
程序改进最多的要属健壮性部分,为此加入了好多读取非法输入部分。
在整整两个星期的日子里,可以学到很多很多的的东西,尤其是漫长的改错部分!
不仅可以巩固了以前所学过的知识,而且学到了很多在书本上所没有学到过的知识。
参考文献
[1]严蔚敏,吴伟民.数据结构(C语言版)[M].北京:
清华大学出版社,2002
[2]谭浩强.C程序设计[M].北京:
清华大学出版社,2005
[3]李建忠.大学计算机基础[M].西安:
西北大学出版社,2005
[4]何钦铭,颜晖.C语言程序设计[M].北京:
高等教育出版社,2008
[5]谢俊屏.大学计算机基础实验教程[M].西安:
西北大学出版社,2005
附代码:
#include
#include
#include
#defineSTACK_INIT_SIZE100
#defineSTACKINCREMENT10
typedefintSElemType;
typedefstruct{
SElemType*base,*top;
intstacksize;
}SqStack;
intInitStack(SqStack&S){
S.base=(SElemType*)malloc(STACK_INIT_SIZE*sizeof(SElemType));
if(!
S.base)exit(0);
S.top=S.base;
S.stacksize=STACK_INIT_SIZE;
return1;
}
intPush(SqStack&S,SElemTypee){
if(S.top-S.base>=S.stacksize){
S.base=(SElemType*)realloc(S.base,(S.stacksize+STACKINCREMENT)*sizeof(SElemType));
if(!
S.base)exit(0);
S.top=S.base+S.stacksize;
S.stacksize+=STACKINCREMENT;
}
*S.top++=e;
return1;
}
intPop(SqStack&S,SElemType&e){
if(S.top==S.base)return0;
e=*--S.top;
return1;
}
intStackEmty(SqStackS){
if(S.top==S.base)return1;
elsereturn0;
}
voidXSZZ(doublen,intT){
inti=0;
doublea;
if(n==0.0)printf("00000");
while(n!
=0.0)
{
a=T*n;
n=a-(int)a;
if(a>=10)
{
printf("%c",((int)a-10+'A'));
i++;
}
else{
printf("%d",((int)a>0?
(int)a:
0));
i++;
}
if(i==5)break;
}
}
intNZ(){
inti=0,j,T,k=0;
doublesum=0;
chara[20],X;
getchar();
printf("输入转换数");
while((a[i]=getchar())!
='\n'){
if((a[i]<='9'&&a[i]>='0')||(a[i]<='Z'&&a[i]>='A')||a[i]=='.');
else{break;}
if(a[i]=='.')k=i;
i++;}
k=k?
k:
i;
if(a[i]!
='\n'){
while(getchar()!
='\n');
printf("输入有误");
return0;}
a[i]='\0';
a[k]='\0';
printf("输入转换数的进制");
scanf("%d%c",&T,&X);
if((!
(T>1&&T<36))||X!
='\n'){
while(getchar()!
='\n');
printf("输入有误");printf("sdf%c",X);
return0;}
for(j=0;j{
if(((a[j]-'0'>=T)&&(a[j]<='9'))||((a[j]-'A'+10>=T)&&(a[j]>'9')))
{
printf("输入有误!
");return1;
}
if(a[j]>='A')
sum+=((a[j]-'A'+10)*pow(T,k-j-1));
else
sum+=((a[j]-'0')*pow(T,k-j-1));
}
for(j=k+1;j
{
if(((a[j]-'0'>=T)&&(a[j]<='9'))||((a[j]-'A'+10>=T)&&(a[j]>'9')))
{
printf("输入有误!
");return1;
}
if(a[j]>='A')
sum+=((a[j]-'A'+10)*pow(T,k-j));
else
sum+=((a[j]-'0')*pow(T,k-j));
}
if(!
(((a[j]-'0'>=T)&&(a[j]<='9'))||((a[j]-'A'+10>=T)&&(a[j]>'9'))))printf("结果为%f",sum);
return1;
}
intZZ(){
intN,T,i=0,a;
doubleZ,M;
charX[10];
SElemTypee;
SqStackS;
InitStack(S);
printf("输入转换数:
");
scanf("%lf%c",&Z,&X[0]);
if(X[0]!
='\n'){printf("输入有误!
");while(X[i]!
='\n'){
i++;
scanf("%c",&X[i]);}return1;}
printf("输入转换进制:
");
scanf("%d%c",&T,&X[0]);
if(T<36&&T>1&&X[0]=='\n')
{printf("%c",X[0]);
N=(int)Z;
M=Z-N;
while(N)
{
if(T>10)
{
a=N%T;
if(a>=10)
{
a=a-10+'A';
Push(S,a);
}
elsePush(S,N%T);
}
elsePush(S,N%T);
N=N/T;
}
printf("结果为:
");
if(StackEmty(S))printf("0");
while(!
StackEmty(S))
{
Pop(S,e);
if(e>=10)printf("%c",e);
elseprintf("%d",e);
}
printf(".");
XSZZ(M,T);
}
else
{printf("输入有误\n");i=0;
while(X[i]!
='\n'){
i++;
scanf("%c",&X[i]);}
}}
main()
{
intchoice;
charX;
do{printf("Press1:
十进制转换其他进制数\nPress2:
其他进制数转换十进制数\n");
scanf("%d",&choice);
switch(choice){
case1:
ZZ();break;