数据结构(17)栈典型问题之C++实现数值转换

来源:互联网 发布:安卓鼓机软件 编辑:程序博客网 时间:2024/05/16 13:58

  • 导言
  • 数值转换
    • 算法
    • 具体实现包括顺序栈完整定义
    • 运行结果
    • 结束语

导言

前面学习了顺序栈的一些基本定义和函数操作原型,本章是以数值转换为例子,给出顺序栈所有函数的实现。

数值转换

十进制N和其他d进制的转换是计算机实现计算的基本问题,其解决方法很多,其中一个简单算法基于下列原理:

N=(N div d)×d+N mod d

(其中div为整除运算,mod为求余运算)

比如(1348)10=(2504)8。其运算过程如下:

N N div 8 N mod 8 1348 168 4 168 21 0 21 2 5 2 0 2

现在有一个要求,需要编写一个满足下列要求的程序:对于输入的非零十进制整数,打印输出与其等值的八进制数。
由于上述计算过程是从低位到高位顺序产生的八进制数的各位数,而打印输出,一般是从高位到低位进行,恰好和计算过程相反。因此,若将计算过程中得到的八进制数的各位按顺序入栈,则按出栈序列打印输出的即为与输入对应的八进制数。

算法

void conversion (int Num) {  // 算法3.1    // 对于输入的任意一个非负十进制整数,打印输出与其等值的八进制数    ElemType e;      SqStack S;    InitStack(S);      // 构造空栈    while (Num) {        Push(S, Num % 8);        Num = Num/8;    }    while (!StackEmpty(S)) {        Pop(S,e);        printf ("%d", e);    }    printf("\n");} // conversion

具体实现(包括顺序栈完整定义)

#define N 8 // 定义待转换的N机制/* 函数结果状态代码 */#define     TRUE                1#define     FALSE               0#define     OK                  1#define     ERROR               0#define   OVERFLOW             -2typedef int SElemType; // 定义栈元素类型为整型typedef int Status; /* Status是函数的类型,其值是函数结果状态代码,如OK等 *///相关头文件包含#include <iostream>using namespace std;/*栈的顺序存储表示 */#define STACK_INIT_SIZE 10 /* 存储空间初始分配量 */#define STACKINCREMENT 2 /* 存储空间分配增量 */typedef struct SqStack{    SElemType *base; /* 在栈构造之前和销毁之后,base的值为NULL */    SElemType *top; /* 栈顶指针 */    int stacksize; /* 当前已分配的存储空间,以元素为单位 */}SqStack; /* 顺序栈 *//* --------    顺序栈基本函数实现    -------------------*/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 DestroyStack(SqStack *S){ /* 销毁栈S,S不再存在 */    free((*S).base);    (*S).base = NULL;    (*S).top = NULL;    (*S).stacksize = 0;    return OK;}Status ClearStack(SqStack *S){ /* 把S置为空栈 */    (*S).top = (*S).base;    return OK;}Status StackEmpty(SqStack S){ /* 若栈S为空栈,则返回TRUE,否则返回FALSE */    if (S.top == S.base)        return TRUE;    else        return FALSE;}int StackLength(SqStack S){ /* 返回S的元素个数,即栈的长度 */    return S.top - S.base;}Status GetTop(SqStack S, SElemType &e){    if (S.top == S.base)return ERROR;    e = *(S.top - 1);    return OK;}//GetTopStatus 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;}//pushStatus Pop(SqStack &S, SElemType &e){//若栈不空,则删除S的栈顶元素,用e返回其值,并返回OK;否则返回ERROR    if (S.top == S.base)return ERROR;    e = *--S.top;    return OK;}//popStatus StackTraverse(SqStack S, Status(*visit)(SElemType)){ /* 从栈底到栈顶依次对栈中每个元素调用函数visit()。 */    /* 一旦visit()失败,则操作失败 */    while (S.top>S.base)        visit(*S.base++);    cout << "\n";    return OK;}void visit(SElemType e){    cout << e ;}void conversion(){// 对于输入的任意一个非负十进制整数,打印输出与其等值的N进制数    SqStack Sq;    int number = 0;    SElemType e;    cout << "请输入要转换的数字(数值必须不小于0):";    cin >> number;    cout << "将十进制数字" << number << "转换成" << N << "进制为:";    if (number < 0)    {        cout << "数值小于0,无法为你转变进制";    }    else    {        InitStack(&Sq);        while (number){            Push(Sq, number % N);            number /= 8;        }        while (!StackEmpty(Sq))        {            Pop(Sq, e);            cout << e;        }        cout << endl;    }}int main(){    //本程序说明,是在VS2013中运行的,若是其他地方无法运行,建议修改代码    //程序声明    cout << "***************************************************************************" << endl;    cout << "                   《数据结构》<C语言版本>严蔚敏 吴伟名 编著              " << endl;    cout << "                                编写年月2016年3月                         " << endl;    cout << "                                 编写者:YuYunTan                          " << endl;    cout << "                                      算法3.1                             " << endl;    cout << "***************************************************************************" << endl;    conversion();    system("pause");    return 0;}

运行结果

这里写图片描述

结束语

为了不失去一般性,所以代表进制的数目,采取了数字N代表进制,此程序适用于2进制和8进制,若是想做16进制,还得需要额外判断才能做成,而且还得修改SElemType的值。

1 0
原创粉丝点击