問題描述
給定n個十六進制正整數,輸出它們對應的八進制數。
輸入格式
輸入的第一行爲一個正整數n (1<=n<=10)。
接下來n行,每行一個由09、大寫字母AF組成的字符串,表示要轉換的十六進制正整數,每個十六進制數長度不超過100000。
輸出格式
輸出n行,每行爲輸入對應的八進制正整數。
【注意】
輸入的十六進制數不會有前導0,比如012A。
輸出的八進制數也不能有前導0。
樣例輸入
2
39
123ABC
樣例輸出
71
4435274
思路:剛開始想得是先轉換成十進制,但是字符串長度太大了。所以先轉化成二進制,轉化成二進制之後,如果字符串長度不是3的倍數,就在前面補0,每三位二進制數化爲一個八進制數即可。
AC代碼:
#include<bits/stdc++.h>
using namespace std;
int n;
string res,ans;
stack<int> s,t;
string binary[]={"0000","0001","0010","0011","0100","0101","0110","0111","1000","1001","1010",
"1011","1100","1101","1110","1111"}; //先定義好0-16的二進制數
map<string,string> a;
void init() {
a["000"]="0"; //二八轉換
a["001"]="1";
a["010"]="2";
a["011"]="3";
a["100"]="4";
a["101"]="5";
a["110"]="6";
a["111"]="7";
}
void converse(string str) {
res="";
ans="";
int cur;
for(int i=0;i<str.length();i++) {
if(str[i]>='0'&&str[i]<='9') {
cur=(int)(str[i]-48);
}else {
cur=(int)(str[i]-55);
}
res+=binary[cur]; //轉成二進制
}
int n=res.length();
int x=n%3;
if(x==1) {
res="00"+res; //補0
}else if(x==2) {
res="0"+res;
}
for(int i=0;i<res.length();i+=3) {
ans+=a[res.substr(i,3)]; //每三位轉成一位八進制數
}
int i=0;
for(i=0;i<ans.length();i++) {
if(ans[i]!='0') { //注意不能輸出前導0
break;
}
}
ans.erase(0,i);
cout<<ans<<endl;
}
int main() {
init();
int n;
cin>>n;
string str;
for(int i=1;i<=n;i++) {
cin>>str;
converse(str);
}
return 0;
}