今天這道題目呢,與前天講的「龜兔賽跑」都是從PAT的基礎編程題目中節選過來的。
難度不是很大,但是特別基礎,複習到了基礎知識,也就是二進位、十進位兩者之間的相互轉換。
我們先來看看這道題目的要求:
BCD數是用一個位元組來表達兩位十進位的數,每四個比特表示一位。
所以,如果一個BCD數的十六進位為0x12,那麼它的十進位也是12。
此時有一位小夥伴並不知道BCD數的運算規則,直接把0x12當作二進位來轉換成十進位,那就會得到18。
現在呢,我們就期望能把這個錯誤得到的十進位,轉換成我們期望得到的十進位數值。
給定的這個錯誤十進位範圍為[0,153]。
題目要求呢我們都清楚了,接下來就是如何解決這個問題。
這裡呢,主要涉及到的是十六進位和十進位之間以及二進位和十進位之間的轉換。
但我呢,好像把這道題目給想複雜了emm,結果導致簡單問題複雜化,實在是不應該啊。
理清邏輯,畫出流程圖,這是十進位轉換為二進位再進行BCD解密
程序要寫正確的話,流程圖用來幫助理清邏輯非常好用,這張流程圖畫的有些小,真的有些不好意思。

可以從這張流程圖中看出來,我的邏輯就是:
把該同學輸入的整數先轉換為二進位數,比方說給定的十進位數為18。
那麼轉換成的二進位數則為00010010。
之後再把二進位數轉換為十六進位的形式則為0001和0010。
之後分別轉換為十進位得到1和2。
然後求和1*10+2*1=12,最終得到結果。
我的代碼部分:
注意,這裡我用到了一個pow函數,這是一個求冪次方的函數,在用這個函數的時候,需要調用庫#include<math.h>。
#include<stdio.h>
#include<math.h>
int main(){
int number = 0;//初始化定義需要輸入的十進位數
int store[8] = {0};
int mod = 0;
int mild1 = 0;//求和
int mild2 = 0;//求和
scanf("%d", &number);
for(int i = 0; i < 8; i++){
mod = number%2;
number = number/2;
store[i] = mod;
}
for(int i = 7; i >= 4; i--){
if(store[i]==1){
mild1 = mild1+pow(2,i-4);
}
}
for(int i = 3; i >= 0; i--){
if(store[i]==1){
mild2 = mild2+pow(2,i);
}
}
printf("%d", mild1*10+mild2);
printf("n");
}測試結果:

提交PAT測試結果:

但是呢,我在思考,這道題目有沒有更快的方法了。
畢竟這樣從二進位開始寫,十進位轉化為二進位,然後再轉化為十六進位,然後分開二進位轉化為十進位的確麻煩了些。
於是,我再來認真地讀了一遍這道題。
讀來讀去,只發現這道題是只需要我們直接把十進位轉化為十六進位即可!然後再直接計算不就行了么。
BCD太迷惑人了!
十進位轉化為十六進位的流程:
給定一個數18,18除以16等於1取餘數得到2,再把1除以16等於0取餘數得到1。
1和2組合起來,不也能得到最終結果嗎?
流程圖,這是十進位轉換為十六進位再進行BCD解密

我的代碼部分
#include<stdio.h>
int main(){
int number = 0;//初始化定義需要輸入的十進位數
int store[8];
int mod = 0;
scanf("%d", &number);
for(int i = 0; i < 8; i++){
mod = number%16;
number = number/16;
store[i] = mod;
}
printf("%d",store[1]*10+store[0]);
}
測試結果

提交PAT測試結果

總結
在做這道題目的時候,我遇到了很多很多問題。
比方說逆序輸出的時候,我直接把1和2按照順序打出,但這樣的話就會產生問題,最小值該如何判斷。
還有要用到pow函數,這個可不能忘了。
總的來說,這道題呢,關鍵還是考我們對十進位、二進位和十六進位之間的轉換是否熟悉。
如果很熟悉的話,這道題目直接十進位與十六進位轉換一下就做出來了。
沒必要像我最開始寫的那樣兜一個大圈子。
原創文章,作者:投稿專員,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/272924.html
微信掃一掃
支付寶掃一掃