编程基础 - 栈的应用 - 进制/数制转换(Numeral Conversion)
文章目录
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