编程基础 - 栈的应用 - 进制/数制转换(Numeral Conversion)

版权声明:本文为博主原创文章,未经允许不得转载。 https://blog.csdn.net/darkrabbit/article/details/89409573

编程基础 - 栈的应用 - 进制/数制转换(Numeral Conversion)

返回分类:全部文章 >> 基础知识

返回上级:编程基础 - 栈(Stack)



1 数制转换说明

数制转换方面,在另一篇文章( 编程基础 - 进制转换(Binary Conversion) )已经做了详细的解释。

这里将不再重新说明,它使用了栈了原理,但并未使用栈。

在这里,我将使用栈重新编写其中的十进制转其它进制


2 数制转换(C++ Code)

我们的改动非常有限,只是将结果存入一个栈stack<char>,然后循环打印。

2.1 头文件main.h

#pragma once

#include <vector> // 向量列表
#include <stack> // 栈
#include <unordered_map> // 字典

2.2 主函数文件main.cpp

我们在转换之前,应该先初始化数字到字母的映射(十进制转其它中,char2int并没有用到):

// 初始化双向映射
//      char2int:   字母到数字的映射
//      int2char:   数字到字母的映射
void InitNumeralMapping(unordered_map<char, int> &char2int, unordered_map<int, char> &int2char)
{
    // 初始化数字 0-9
    for (int c = '0', i = 0; c <= '9'; c++, i++)
    {
        char2int[(char)c] = i;
        int2char[i] = (char)c;
    }

    // 初始化字母 a-z
    for (int c = 'a', i = 10; c <= 'z'; c++, i++)
    {
        char2int[(char)c] = i;
        int2char[i] = (char)c;
    }

    // 初始化数字 A-Z
    for (int c = 'A', i = 36; c <= 'Z'; c++, i++)
    {
        char2int[(char)c] = i;
        int2char[i] = (char)c;
    }
}

在转换时,同时存储每一步的结果,这样在打印时可以看到转换过程:

// 转换10进制到其它进制
// params:
//      num:        需要转换的十进制数
//      numeration: (2-62)进制
//      int2char:   十进制数到其它进制的映射
//      steps:      每一步结果[{被除数 : {商 : 余数}}]
//      output:     输出栈
void ConvertDec2Other(long long num, 
                      int numeration, 
                      unordered_map<int, char> int2char,
                      vector<pair<long long, pair<long long, char>>> &steps,
                      stack<char> &output)
{
    if (num == 0)
    {
        output.push('0');
        return;
    }

    //// 10进制可直接用 #include <string> 中的 std::to_string(num)
    //if (numeration == 10)
    //{
    //    string numStr = to_string(num);
    //    for (int i = numStr.length - 1; i >= 0; i--)
    //    {
    //        output.push(numStr[i]);
    //    }
    //    return;
    //}

    long long quotient = num; // 定义商,并初始化为被除数
    int remainder; // 定义余数
    while (quotient != 0)
    {
        pair<long long, pair<long long, int>> step;
        step.first = quotient;

        remainder = quotient % numeration; // 求余数
        output.push(int2char[remainder]); // 将映射放入栈
        quotient = quotient / numeration; // 求商

        step.second = pair<long long, char>(quotient, int2char[remainder]);
        steps.push_back(step);
    }
}

最后,是我们的主函数:

#include "main.h"

#include <iostream>
using namespace std;

constexpr int MIN_NUMERATION = 2; // 常量,最小进制
constexpr int MAX_NUMERATION = 62; // 常量,最大进制

void InitNumeralMapping(unordered_map<char, int> &char2int, unordered_map<int, char> &int2char);
void ConvertDec2Other(long long num,
                      int numeration,
                      unordered_map<int, char> int2char,
                      vector<pair<long long, pair<long long, char>>> &steps,
                      stack<char> &output);

int main()
{
    unordered_map<char, int> char2int; // 字母到数字的映射
    unordered_map<int, char> int2char; // 数字到字母的映射
    InitNumeralMapping(char2int, int2char); // 初始化两个映射

    long long num;
    int numeration;

    while (true)
    {
        cout << "进制转换,依次输入正整数和进制(2-62)(以空格分割):";
        while (!(cin >> num >> numeration) || numeration < MIN_NUMERATION || numeration > MAX_NUMERATION)
        {
                cin.clear();
                cin.ignore(numeric_limits<streamsize>::max(), '\n');
                cout << "输入不合法,请重新输入:";
        }
        cin.ignore(numeric_limits<streamsize>::max(), '\n');

        vector<pair<long long, pair<long long, char>>> steps; // 定义每一步结果
        stack<char> output; // 定义结果栈
        ConvertDec2Other(num, numeration, int2char, steps, output); // 转换进制

        // 打印每一步结果
        cout << "转换过程:" << endl;
        for (int i = 0; i < steps.size(); i++)
        {
            cout << '\t' << (i + 1) << ": ";
            cout << steps[i].first << " / " << numeration << " = ";
            cout << steps[i].second.first << " ... " << steps[i].second.second;
            cout << endl;
        }

        // 打印最终结果
        cout << "转换" << numeration << "进制结果为:";
        while (output.size() > 0)
        {
            cout << output.top();
            output.pop();
        }

        cout << endl << endl;
    }

    system("pause");
    return 0;
}

3.3 运行结果

进制转换,依次输入正整数和进制(2-62)(以空格分割):54263 16
转换过程:
        1: 54263 / 16 = 3391 ... 7
        2: 3391 / 16 = 211 ... f
        3: 211 / 16 = 13 ... 3
        4: 13 / 16 = 0 ... d
转换16进制结果为:d3f7

进制转换,依次输入正整数和进制(2-62)(以空格分割):172537163216 1
输入不合法,请重新输入:3216382736183 62
转换过程:
        1: 3216382736183 / 62 = 51877140906 ... b
        2: 51877140906 / 62 = 836728079 ... 8
        3: 836728079 / 62 = 13495614 ... b
        4: 13495614 / 62 = 217671 ... c
        5: 217671 / 62 = 3510 ... P
        6: 3510 / 62 = 56 ... C
        7: 56 / 62 = 0 ... U
转换62进制结果为:UCPcb8b


猜你喜欢

转载自blog.csdn.net/darkrabbit/article/details/89409573