问题描述
给定n个十六进制正整数,输出它们对应的八进制数。
输入格式
输入的第一行为一个正整数n (1<=n<=10)。
接下来n行,每行一个由0~9、大写字母A~F组成的字符串,表示要转换的十六进制正整数,每个十六进制数长度不超过100000。
输出格式
输出n行,每行为输入对应的八进制正整数。
【注意】
输入的十六进制数不会有前导0,比如012A。
输出的八进制数也不能有前导0。
样例输入
2
39
123ABC
样例输出
71
4435274
【提示】
先将十六进制数转换成某进制数,再由某进制数转换成八进制。
根据提示 采用先转化为十进制 再转化为八进制的方法
#include <iostream>
#include <string>
#include <algorithm>
#include <sstream>
using namespace std;
// 十六进制转十进制
long long hexToDecimal(const string& hex) {
long long result = 0;
for (size_t i = 0; i < hex.length(); ++i) {
result *= 16;
char c = hex[i];
if (c >= '0' && c <= '9') {
result += c - '0';
} else if (c >= 'A' && c <= 'F') {
result += c - 'A' + 10;
}
}
return result;
}
// 十进制转八进制
string decimalToOctal(long long decimal) {
ostringstream oss;
while (decimal > 0) {
oss << (decimal % 8);
decimal /= 8;
}
string octal = oss.str();
reverse(octal.begin(), octal.end());
return octal.empty() ? "0" : octal;
}
int main() {
int n;
cin >> n;
while (n--) {
string hexNumber;
cin >> hexNumber;
long long decimal = hexToDecimal(hexNumber);
string octal = decimalToOctal(decimal);
cout << octal << endl;
}
return 0;
}
由于测试集包含非常长的数据,用long long类型存储
发现虽然可以输出正确的结果,但无法测试通过
于是换方法,不再用long long类型 改用string
#include<iostream> // 包含输入输出流库
#include<math.h> // 包含数学函数库
#include<map> // 包含映射容器库
using namespace std; // 使用标准命名空间
// 二进制字符串转换为八进制
int main(){
int n; // 定义整数变量 n,用于存储输入的测试用例数量
cin>>n; // 从标准输入流读取测试用例数量
// 循环处理每个测试用例
while(n--){
string s; // 定义字符串变量 s,用于存储输入的十六进制数
cin>>s; // 从标准输入流读取十六进制数
int len1 = s.length(); // 获取字符串 s 的长度
string res1=""; // 定义字符串变量 res1,用于存储转换后的二进制字符串
// 将十六进制转换为二进制字符串
for (int i=0;i<len1;i++){
// 根据十六进制字符的不同,将其转换为对应的四位二进制字符串,并拼接到 res1 中
switch(s[i]){
case '0': res1 += "0000"; break;
case '1': res1 += "0001"; break;
case '2': res1 += "0010"; break;
case '3': res1 += "0011"; break;
case '4': res1 += "0100"; break;
case '5': res1 += "0101"; break;
case '6': res1 += "0110"; break;
case '7': res1 += "0111"; break;
case '8': res1 += "1000"; break;
case '9': res1 += "1001"; break;
case 'A': res1 += "1010"; break;
case 'B': res1 += "1011"; break;
case 'C': res1 += "1100"; break;
case 'D': res1 += "1101"; break;
case 'E': res1 += "1110"; break;
case 'F': res1 += "1111"; break;
}
}
// 二进制字符串每四个数就是一个十六进制数,每3个数就是一个八进制数,
// 这里可能存在缺0的情况,需要补充
int len2=res1.length() ; // 获取转换后的二进制字符串的长度
switch(len2%3){
case 1: res1 = "00"+res1; break; // 若长度除以3余1,则在开头补充两个0
case 2: res1 = "0"+res1; break; // 若长度除以3余2,则在开头补充一个0
}
// 此时的 res1 就是一个合法的二进制表示八进制的字符串了,
// 下面开始生成八进制字符串了
string res2=""; // 定义字符串变量 res2,用于存储最终转换后的八进制字符串
len2=res1.length(); // 获取补充0后的二进制字符串的长度
for (int i=0;i<len2;i+=3){ // 每次循环处理三位二进制数
string t = res1.substr(i,3); // 截取三位二进制数
// 避免因为000带来导致转为为八进制时有前导0
if (i==0&&t=="000") res2+=""; // 如果是第一个三位二进制数且全为0,则不做处理
else res2 += (4*((t[0])-'0')+ 2*((t[1])-'0' )+ ((t[2])-'0'))+'0'; // 否则将三位二进制数转为对应的八进制数
}
cout<<res2<<endl; // 输出转换后的八进制字符串
}
return 0; // 返回执行成功
}
虽然两个代码效果是一样的,但第二种才能通过测试,具体原因欢迎补充