(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);
}
}
}