栈的应用实例--数制转换
题目:
假设现在要编制一个满足下列要求的程序:对于输入的任意一个非负十进制整数,打印输出与其等值的八进制数。
解析:
先来看一个例子:十进制转二进制
1)十进制数156,转为二进制的结果是10011100,转换过程如下:
- 156除以2,商为78,余数为0;
- 78除以2,商为39,余数为0;
- 39除以2,商为19,余数为1;
- 19除以2,商为9,余数为1;
- 9除以2,商为4,余数为1;
- 4除以2,商为2,余数为0;
- 2除以2,商为1,余数为0;
- 1除以2,商为0,余数为1;
- 综上,将余数倒序排列,得10011100 。
由上,我们很容易看出进制转换的过程。
由于上述计算过程从低位到高位顺序产生的八进制数的各个数位,而打印输出,一般来说应从高位到低位进行,恰好和计算过程相反。因此,需要将计算过程中得到的八进制数的各位顺序进栈,则按出栈序列打印输出的即为与输入对应的八进制数。
十进制整数转换为八进制
typedef int Status; /* Status是函数的类型,其值是函数结果状态代码,如OK等 */
typedef int Boolean; /* Boolean是布尔类型,其值是TRUE或FALSE */
typedef int SElemType; /* 定义栈元素的类型 */
#include<malloc.h> /* malloc()等 */
#include<stdio.h> /* EOF(=^Z或F6),NULL */
#include<process.h> /* exit() */
/* 函数结果状态代码 */
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
#define OVERFLOW -2
/* -------------------------- 栈的顺序存储表示 -----------------------------*/
#define STACK_INIT_SIZE 10 /* 存储空间初始分配量 */
#define STACKINCREMENT 2 /* 存储空间分配增量 */
typedef struct SqStack
{
SElemType *base; /* 在栈构造之前和销毁之后,base的值为NULL */
SElemType *top; /* 栈顶指针 */
int stacksize; /* 当前已分配的存储空间,以元素为单位 */
}SqStack; /* 顺序栈 */
/* ----------------------------------------------------------------------------*/
Status visit(SElemType c)
{
printf("%d ", c);
return OK;
}
/* --------------------------------- 需要用到的顺序栈基本操作 ------------------------------------*/
Status InitStack(SqStack *S)
{ /* 构造一个空栈S */
(*S).base = (SElemType *)malloc(STACK_INIT_SIZE * sizeof(SElemType));
if (!(*S).base)
exit(OVERFLOW); /* 存储分配失败 */
(*S).top = (*S).base;
(*S).stacksize = STACK_INIT_SIZE;
return OK;
}
Status StackEmpty(SqStack S)
{ /* 若栈S为空栈,则返回TRUE,否则返回FALSE */
if (S.top == S.base)
return TRUE;
else
return FALSE;
}
Status Push(SqStack *S, SElemType e)
{ /* 插入元素e为新的栈顶元素 */
if ((*S).top - (*S).base >= (*S).stacksize) /* 栈满,追加存储空间 */
{
(*S).base = (SElemType *)realloc((*S).base, ((*S).stacksize + STACKINCREMENT) * sizeof(SElemType));
if (!(*S).base)
exit(OVERFLOW); /* 存储分配失败 */
(*S).top = (*S).base + (*S).stacksize;
(*S).stacksize += STACKINCREMENT;
}
*((*S).top)++ = e;
return OK;
}
Status Pop(SqStack *S, SElemType *e)
{ /* 若栈不空,则删除S的栈顶元素,用e返回其值,并返回OK;否则返回ERROR */
if ((*S).top == (*S).base)
return ERROR;
*e = *--(*S).top;
return OK;
}
/* -------------------------------------------------------------------------------------------------*/
void conversion() /* 算法3.1 */
{ /* 对于输入的任意一个非负十进制整数,打印输出与其等值的八进制数 */
SqStack s;
unsigned n; /* 非负整数 */
SElemType e;
InitStack(&s); /* 初始化栈 */
printf("n(>=0)=");
scanf_s("%u", &n); /* 输入非负十进制整数n */
while (n) /* 当n不等于0 */
{
Push(&s, n % 8); /* 入栈n除以8的余数(8进制的低位) */
n = n / 8;
}
while (!StackEmpty(s)) /* 当栈不空 */
{
Pop(&s, &e); /* 弹出栈顶元素且赋值给e */
printf("%d", e); /* 输出e */
}
printf("\n");
}
void main()
{
conversion();
}
运行结果:
十进制整数转换为八进制
typedef int Status; /* Status是函数的类型,其值是函数结果状态代码,如OK等 */
typedef int Boolean; /* Boolean是布尔类型,其值是TRUE或FALSE */
typedef int SElemType; /* 定义栈元素的类型 */
#include<malloc.h> /* malloc()等 */
#include<stdio.h> /* EOF(=^Z或F6),NULL */
#include<process.h> /* exit() */
/* 函数结果状态代码 */
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
#define OVERFLOW -2
/* -------------------------- 栈的顺序存储表示 -----------------------------*/
#define STACK_INIT_SIZE 10 /* 存储空间初始分配量 */
#define STACKINCREMENT 2 /* 存储空间分配增量 */
typedef struct SqStack
{
SElemType *base; /* 在栈构造之前和销毁之后,base的值为NULL */
SElemType *top; /* 栈顶指针 */
int stacksize; /* 当前已分配的存储空间,以元素为单位 */
}SqStack; /* 顺序栈 */
/* ----------------------------------------------------------------------------*/
Status visit(SElemType c)
{
printf("%d ", c);
return OK;
}
/* --------------------------------- 需要用到的顺序栈基本操作 ------------------------------------*/
Status InitStack(SqStack *S)
{ /* 构造一个空栈S */
(*S).base = (SElemType *)malloc(STACK_INIT_SIZE * sizeof(SElemType));
if (!(*S).base)
exit(OVERFLOW); /* 存储分配失败 */
(*S).top = (*S).base;
(*S).stacksize = STACK_INIT_SIZE;
return OK;
}
Status StackEmpty(SqStack S)
{ /* 若栈S为空栈,则返回TRUE,否则返回FALSE */
if (S.top == S.base)
return TRUE;
else
return FALSE;
}
Status Push(SqStack *S, SElemType e)
{ /* 插入元素e为新的栈顶元素 */
if ((*S).top - (*S).base >= (*S).stacksize) /* 栈满,追加存储空间 */
{
(*S).base = (SElemType *)realloc((*S).base, ((*S).stacksize + STACKINCREMENT) * sizeof(SElemType));
if (!(*S).base)
exit(OVERFLOW); /* 存储分配失败 */
(*S).top = (*S).base + (*S).stacksize;
(*S).stacksize += STACKINCREMENT;
}
*((*S).top)++ = e;
return OK;
}
Status Pop(SqStack *S, SElemType *e)
{ /* 若栈不空,则删除S的栈顶元素,用e返回其值,并返回OK;否则返回ERROR */
if ((*S).top == (*S).base)
return ERROR;
*e = *--(*S).top;
return OK;
}
/* -------------------------------------------------------------------------------------------------*/
void conversion()
{ /* 对于输入的任意一个非负10进制整数,打印输出与其等值的16进制数 */
SqStack s;
unsigned n; /* 非负整数 */
SElemType e;
InitStack(&s); /* 初始化栈 */
printf("n(>=0)=");
scanf_s("%u", &n); /* 输入非负十进制整数n */
while (n) /* 当n不等于0 */
{
Push(&s, n % 16); /* 入栈n除以16的余数(16进制的低位) */
n = n / 16;
}
while (!StackEmpty(s)) /* 当栈不空 */
{
Pop(&s, &e); /* 弹出栈顶元素且赋值给e */
if (e <= 9)
printf("%d", e);
else
printf("%c", e + 55);
}
printf("\n");
}
void main()
{
conversion();
}
运行结果: