栈和队列的应用——数制转换软件
(1)将十进制转化为其他进制,对于其转换问题:其一般的解决方法是利用辗转相除法。以一个十进制转化为八进制问题为例:假设N=6666,示例如下进行辗转相除运算:
即得到的结果为(6666)10=(15012)8,转换的八进制数是各个数位从低位到高位依次顺序产生的,而产生的的结果通常是按照从高位到低位的顺序依次输出,即输出顺序和产生顺序加好相反,这就与栈的操作原则相符合。
总结可以得到以下的算法:
当N>0时重复步骤1和步骤2.
①、若N不等于0,则将N%8压入栈中,继续执行步骤二;若N等于0,则依次将栈中的数据输出,程序结束。
②、用N%8去代替N,返回①;
(2)、将一个其他进制的数(n)转化为十进制,通常将这个数除以10得到每一个数的位数(n[i]),在根据这个数所在这个数字的位置i,以及n(i),求出n[i]*(转换的进制)i。这里可以将n[i]放入队列中,因为其存储结构与队列相似。举例将八进制的894转化为十进制,过程如图:
(894)8=(4+9*8+8*82)10=(588)10
总结算法如下:
当i<n.length时重复步骤1和2;
①、i<n.length时,将n%10的值放入队列;继续执行步骤②;若i=n.length,则输出sum( n[i]*(转换的进制)i )。
②、用n/10去代替n,返回①。
运行结果如下图:
具体的程序如下:
#include<stdio.h> #include<string.h> #include<malloc.h> #include<process.h> #include<math.h> #include<stdlib.h> typedef int ElemType; #define STACK_INIT_SIZE 10 #define STACK_INCREAMENT 2 #define MAXNUM 20 //顺序栈 typedef struct SqStack{ ElemType *top; ElemType *base; int stacksize; }SqStack; //队列的链式结构 typedef struct QNode{ ElemType data; struct QNode *next; }QNode,*QueuePtr; typedef struct LinkQueue{ QueuePtr front; QueuePtr rear; }LinkQueue; void conversionC(); //栈的初始化 void InitStack(SqStack *s) { s->base=(ElemType *)malloc(STACK_INIT_SIZE*sizeof(ElemType)); if(!s->base) { printf("栈初始化时的空间分配失败了!\n"); exit(0); } s->top=s->base; s->stacksize=STACK_INIT_SIZE; } //判断栈是否为空 int SqStack_empty(SqStack s) { if(s.base==s.top) return 1; else return 0; } //入栈 int SqStack_push(SqStack *s,ElemType x) { if(s->top-s->base>=s->stacksize) { s->base=(ElemType *)realloc(s->base,(s->stacksize+STACK_INCREAMENT)*sizeof(ElemType)); if(!s->base){ printf("栈空间的扩展出错了!\n"); exit(0); } s->top=s->base+STACK_INIT_SIZE; s->stacksize+=STACK_INCREAMENT; } *(s->top)++=x; return 1; } //出栈 int SqStack_pop(SqStack *s,ElemType *x) { if(SqStack_empty(*s)) return 0; *x=*(--s->top); return 1; } //打印栈中的元素 void print(SqStack s) { SqStack s1=s; ElemType x; while(!SqStack_empty(s1)) { SqStack_pop(&s1,&x); printf("%d ",x); } printf("\n"); } //初始化队列 int Init_queue(LinkQueue *Q) { //构造一个空队列 Q->front=Q->rear=(QueuePtr)malloc(sizeof(QNode)); if(!Q->front) { printf("队列初始化失败!\n"); exit(0); } Q->front->next=NULL; return 1; } int En_queue(LinkQueue *Q,ElemType x) { QNode *p=(QueuePtr)malloc(sizeof(QNode)); if(!p) { printf("开辟新节点失败!\n"); exit(0); } p->data=x; p->next=NULL; if(Q->rear==NULL) Q->front=Q->rear=p; else{ Q->rear->next=p; Q->rear=p; } return 1; } int Empty_queue(LinkQueue Q) { if(Q.front==Q.rear) return 1; else return 0; } int De_queue(LinkQueue *Q,ElemType *x) { if(Empty_queue(*Q)) { printf("队列已经为空了!\n"); return 0; } QueuePtr p=Q->front->next; *x=p->data; Q->front->next=p->next; if(Q->rear==p) //此时队列为空,创造为空的判断条件 Q->rear=Q->front; free(p); return 1; } /***************开始进制的转换************/ void conversionA(int m) { //(栈)将非负十进制数转化为m进制数 SqStack s; unsigned int n; InitStack(&s); printf("请输入一个十进制数:"); scanf("%u",&n); int value=n; while(n) { SqStack_push(&s,n%m); n=n/m; } switch(m){ case 2: printf("%d转化为二进制的数为:",value); break; case 8: printf("%d转化为八进制的数为:",value); break; case 16: printf("%d转化为十六进制的数为:",value); break; default: printf("你输入的进制转换本系统不支持\n"); return; } if(m==16) { //十六进制的数需要用到英文字符,此时要做特殊的打印 ElemType e; while(!SqStack_empty(s)) { SqStack_pop(&s,&e); if(e<=9) printf("%d ",e); else printf("%c",e+55); } printf("\n"); } else print(s); } void conversionB(int m) { //(队列)将m进制数转化为十进制数 LinkQueue Q; unsigned int n; Init_queue(&Q); switch(m){ case 2: printf("请您输入一个二进制的数:"); break; case 8: printf("请您输入一个八进制的数:"); break; case 16: printf("请您输入一个十六进制的数:"); break; default: printf("你输入的进制转换本系统不支持\n"); return; } if(m==16) { conversionC(); return; } scanf("%u",&n); while(n) { En_queue(&Q,n%10); n=n/10; } int x,value=0; int i=0; while(!Empty_queue(Q)) { De_queue(&Q,&x); value=value+x*pow(m,i++); } printf("转化后的十进制值为:%d",value); printf("\n"); } //十六进制转十进制:对输入的十六进制数做特殊的处理 void conversionC() { char n[30]; scanf("%s",n); int len=strlen(n); int i,desc=0,j=0; for(i=0;i<len;i++) { if(n[i]>=48 && n[i]<=57 || n[i]>=65 && n[i]<=70 || n[i]>=97 && n[i]<=102 ) continue; else { printf("you must input a hex number!\n"); //??? exit(-1); } } for(i=len-1;i>=0;i--,j++) //i代表十六进制数的第i个位置,相应的倍数是j次方 { if(n[i]<=57) desc+=(n[i]-'0')*pow(16,j); else if(n[i]<=70) desc+=(n[i]-55)*pow(16,j); else desc+=(n[i]-87)*pow(16,j); } printf("%d\n",desc); } void main() { int select; printf("************欢迎来到数值转换软件**************\n\n"); printf("---------- 1、十 - 二进制转换 --------------\n"); printf("---------- 2、十 - 八进制转换 --------------\n"); printf("---------- 3、十 - 十六进制转换--------------\n"); printf("---------- 4、二 - 十进制转换 --------------\n"); printf("---------- 5、八 - 十进制转换 --------------\n"); printf("---------- 6、十六 - 十进制转换 -------------\n"); printf("---------- 7、退出软件 -------------\n"); while(1) { printf("\n请输入相应的操作:"); scanf("%d",&select); switch(select) { case 1: conversionA(2); break; case 2: conversionA(8); break; case 3: conversionA(16); break; case 4: conversionB(2); break; case 5: conversionB(8); break; case 6: conversionB(16); break; case 7: printf(" ^-^ 感谢您的使用!\n\n"); exit(0); } } }
很希望自己是一棵树,守静、向光、安然,敏感的神经末梢,触着流云和微风,窃窃的欢喜。脚下踩着最卑贱的泥,很踏实。还有,每一天都在隐秘成长。