蓝桥杯练习题 基础练习 十六进制转八进制 ———C++实现
【题目】
问题描述
给定n个十六进制正整数,输出它们对应的八进制数。
输入格式
输入的第一行为一个正整数n (1<=n<=10)。
接下来n行,每行一个由0-9、大写字母A~F组成的字符串,表示要转换的十六进制正整数,每个十六进制数长度不超过100000。
输出格式
输出n行,每行为输入对应的八进制正整数。
注意
输入的十六进制数不会有前导0,比如012A。
输出的八进制数也不能有前导0。
【提交成绩】
时间:15ms
内存占用:5.9MB
【总体思路】
十六进制转八进制采用中间进制作为桥梁,这里选择二进制。转换的实现过程在函数 ‘’ int* Converse(char str[], int length) ‘’ 中实现,输入一个十六进制字符串,返回一个八进制整型数组。main()函数中每输入一个十六进制字符串,就通过调用函数输出一个八进制整型数组,并整体存放在指针数组中。最后统一通过指针数组输出转换后的八进制码。
【完整代码】
#include <iostream>
#include <string.h>
#include <stdio.h>
#define MAX 100000
using namespace std;
int* Converse(char str[], int length) {
int i = 0, j = 1, count = 0;
int true_length;
if (4 * length % 3 != 0) {
while ((4 * length + j) % 3 != 0) j++;
true_length = length * 4 + j;
}
else true_length = length * 4; //true_length为存放二进制实际需要的位数
int* a = new int[true_length]; //a[]存放二进制码,最后增加一个位置给结束符号
if (4 * length % 3 != 0) { //多增加的位数在数组头添0
for (int i = 0; i < j; i++) {
a[i] = 0;
count++;
}
}
while (str[i] != '\0') {
switch (str[i]) {
case '0': a[count++] = 0; a[count++] = 0; a[count++] = 0; a[count++] = 0; break; //0000
case '1': a[count++] = 0; a[count++] = 0; a[count++] = 0; a[count++] = 1; break; //0001
case '2': a[count++] = 0; a[count++] = 0; a[count++] = 1; a[count++] = 0; break; //0010
case '3': a[count++] = 0; a[count++] = 0; a[count++] = 1; a[count++] = 1; break; //0011
case '4': a[count++] = 0; a[count++] = 1; a[count++] = 0; a[count++] = 0; break; //0100
case '5': a[count++] = 0; a[count++] = 1; a[count++] = 0; a[count++] = 1; break; //0101
case '6': a[count++] = 0; a[count++] = 1; a[count++] = 1; a[count++] = 0; break; //0110
case '7': a[count++] = 0; a[count++] = 1; a[count++] = 1; a[count++] = 1; break; //0111
case '8': a[count++] = 1; a[count++] = 0; a[count++] = 0; a[count++] = 0; break; //1000
case '9': a[count++] = 1; a[count++] = 0; a[count++] = 0; a[count++] = 1; break; //1001
case 'A': a[count++] = 1; a[count++] = 0; a[count++] = 1; a[count++] = 0; break; //1010
case 'B': a[count++] = 1; a[count++] = 0; a[count++] = 1; a[count++] = 1; break; //1011
case 'C': a[count++] = 1; a[count++] = 1; a[count++] = 0; a[count++] = 0; break; //1100
case 'D': a[count++] = 1; a[count++] = 1; a[count++] = 0; a[count++] = 1; break; //1101
case 'E': a[count++] = 1; a[count++] = 1; a[count++] = 1; a[count++] = 0; break; //1110
case 'F': a[count++] = 1; a[count++] = 1; a[count++] = 1; a[count++] = 1; break; //1111
}
i++;
} //转化为二进制完毕,a[]存放二进制码
int* b = new int[true_length / 3+1]; //b[]存放八进制码
int last;
for (int i = 0; i < (true_length + 1) / 3; i++) {
b[i] = a[3 * i] * 4 + a[3 * i + 1] * 2 + a[3 * i + 2] * 1;
last = i;
}
b[++last] = -1; //'-1'为结束标志
if (b[0] == 0) {
for (int i = 0; b[i] != -1; i++) {
b[i] = b[i + 1];
}
}
return b;
}
int main()
{
int n, length;
char ch[MAX];
cin >> n; //十六进制码数量
int** result = new int* [n];
for (int i = 0; i < n; i++) {
cin >> ch;
length = strlen(ch);
result[i] = Converse(ch, length);
}
for (int i = 0; i < n; i++) { //八进制码数组最后加了一个结束符号'-1'
for (int j = 0; result[i][j] != -1; j++) {
cout << result[i][j];
}
cout << endl;
}
return 0;
}
【其他想法】
十六进制转八进制用十进制做桥梁也可以。
输入的十六进制字符串可以先存在一个指针数组中,只调用一次函数,一次性全部转换为八进制码再返回。(理论上有更好的时间复杂度)
**第一次写文章,小白一个,有错误之处请斧正