栈和队列的应用——数制转换软件

c/c++

浏览数:123

2019-6-29

AD:资源代下载服务

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

 

作者:一盏淡酒、醉了夕阳