十六进制转八进制(浅显易懂)
十六進(jìn)制轉(zhuǎn)八進(jìn)制
#分析+算法實(shí)現(xiàn)+代碼+測試數(shù)據(jù)
#技巧:分析+處理+調(diào)試(大不了就調(diào)試)
分析
這個(gè)題是藍(lán)橋杯的一道練習(xí)題,對于十六進(jìn)制轉(zhuǎn)八進(jìn)制的話,是可以通用的。
題目的描述大概是這樣的:給n個(gè)十六進(jìn)制數(shù),n<=10,每個(gè)數(shù)的長度不超過10000。
這里涉及到字符型以及string類類類型,待會(huì)再強(qiáng)調(diào)。
下面分析一下此題:
要想把十六進(jìn)制轉(zhuǎn)成八進(jìn)制,首先想到把十六進(jìn)制轉(zhuǎn)成二進(jìn)制再轉(zhuǎn)成八進(jìn)制。
于是,如何把十六進(jìn)制數(shù)轉(zhuǎn)化成二進(jìn)制01呢?首先想到的是偷懶,直接利用
c語言的scanf和printf類型轉(zhuǎn)換,真特么容易!
哦,差點(diǎn)忘掉了,每個(gè)十六進(jìn)制數(shù)的長度不超過一萬!其實(shí),我看到這里就
呵呵了,不是我不會(huì),是懶的寫,字符串的一些操作太繁瑣,有些細(xì)節(jié)還要
耐心的處理,很容易就把一個(gè)人清晰的腦袋擰成一股麻繩,各種自我質(zhì)疑,
不過不要著急,所以保持冷靜,這種題還是很容易的,相信自己。
經(jīng)過分析,這道題的算法倒是很容易,如下:
每一個(gè)十六進(jìn)制的值都可以轉(zhuǎn)化成4位二進(jìn)制值,每三個(gè)二進(jìn)制值組成一個(gè)八進(jìn)制值,所以,先把十六進(jìn)制轉(zhuǎn)換成01的二進(jìn)制字串,然后把01串轉(zhuǎn)化成八進(jìn)制。
算法實(shí)現(xiàn)
因?yàn)槭M(jìn)制總共就十六個(gè)字符,這里使用switch對應(yīng)01碼進(jìn)行選擇,然后對string對象str作+運(yùn)算,逐個(gè)轉(zhuǎn)換成4位的01碼存入到string的對象str中,直到全部轉(zhuǎn)化成二進(jìn)制代碼。
然后把二進(jìn)制字串的長度*4%3求出存入一個(gè)變量r中。
如何求string類類型的長度呢?
1 str.length();
2 str.size();
接著有一個(gè)優(yōu)化技巧可以使用,(優(yōu)化技巧)就是這個(gè)
01串開始轉(zhuǎn)化八進(jìn)制的時(shí)候該從哪開始?
如果余數(shù)為零,對誰取余從誰開始,否則從余數(shù)開始。
這個(gè)是我對代碼進(jìn)行優(yōu)化后發(fā)現(xiàn)的。
然后就是如何轉(zhuǎn)化成八進(jìn)制的整數(shù)輸出呢?當(dāng)然是看01碼了。因?yàn)槊咳灰唤M成一個(gè)八進(jìn)制值,使用一個(gè)變量ans記錄在三位中的哪個(gè)位上,使用sum+=pow(2,ans)轉(zhuǎn)化成數(shù)值,每執(zhí)行完一組,ans和sum歸初值。每次輸出sum值,最終輸出的就是目標(biāo)的八進(jìn)制。
因?yàn)槭嵌嘟M輸入數(shù)據(jù),而只定義了兩個(gè)string的對象對整個(gè)程序進(jìn)行操作,所以
string類類型的對象如何清零呢?
1 str.clear()//使用clear()函數(shù);
2 str="";//賦空
小插曲(可以不看,為了擰回博主的腦回路而寫)
之前我常常會(huì)把string類類型和char型混用,如今我終于弄明白了。
比如:
之前我會(huì)這樣寫,scanf輸出string類型的對象值。
string str;printf("%s",str);
哎?為什么會(huì)報(bào)錯(cuò)?
或者說會(huì)寫成這樣,使用c的函數(shù)企圖得到string型對象的長度。
string str; int len=strlen(str);
后來的后來,我終于明白了,之前學(xué)習(xí)c的時(shí)候順帶學(xué)的c++,我一直把這string 和 char型的東西當(dāng)成一家的,其實(shí),他們只是有關(guān)系,但是不是一家的,東西也不能亂串使用,string是字符串類類型。
(這里我使的是string類型的對象對字符串進(jìn)行操作。)
代碼
//利用switch+string類型
//注意字符串要雙引號(hào)#include<stdio.h>
#include<iostream>
#include<string>
#include<string.h>
#include<math.h>
using namespace std;
int main(){int n;string str_temp,str_in;scanf("%d",&n);for(int i=0;i<n;i++){str_in="";str_temp="";//給字符串賦空cin>>str_in;int len=str_in.length();for(int j=0;j<len;j++){switch(str_in[j]){case '0': str_temp+="0000";break;case '1': str_temp+="0001";break;case '2': str_temp+="0010";break;case '3': str_temp+="0011";break;case '4': str_temp+="0100";break;case '5': str_temp+="0101";break;case '6': str_temp+="0110";break;case '7': str_temp+="0111";break;case '8': str_temp+="1000";break;case '9': str_temp+="1001";break;case 'A': str_temp+="1010";break;case 'B': str_temp+="1011";break;case 'C': str_temp+="1100";break;case 'D': str_temp+="1101";break;case 'E': str_temp+="1110";break;case 'F': str_temp+="1111";break;default: break;}}//cout<<str_temp<<endl;//把01串轉(zhuǎn)化成目標(biāo)串int len_s=str_temp.length();int ans=2;int sum=0;int r=len*4%3;if(r==1){if(str_temp[0]=='1')printf("1");}else if(r==2){if(str_temp[0]=='0'&&str_temp[1]=='1')printf("1");else if(str_temp[0]=='1'&&str_temp[1]=='0')printf("2");else if(str_temp[0]=='1'&&str_temp[1]=='1')printf("3");}else{if(str_temp[0]=='0'&&str_temp[1]=='0'&&str_temp[2]=='0')r=3;}for(int i=r;i<len_s;i++){if(str_temp[i]=='1')sum+=pow(2,ans);ans--;if(ans==-1){printf("%d",sum);ans=2;sum=0;}}printf("\n");}
}
測試數(shù)據(jù)
輸入
2
39
123ABC
輸出
71
4435274
總結(jié)
以上是生活随笔為你收集整理的十六进制转八进制(浅显易懂)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: NWERC 2018 A. Access
- 下一篇: Codeforces Round #74