學校OJ題——字串(十六進位制)
阿新 • • 發佈:2018-12-18
問題 D: 十六進位制加
時間限制: 1 Sec 記憶體限制: 128 MB
提交: 486 解決: 231
[提交][狀態][討論版]
題目描述
在十六進位制表示中,ABCDEF用於表示十進位制的10、11、12、13、14、15
現輸入兩個表示十六進位制整數的字串,請計算它們相加的結果,用十進位制表示。
如果輸入的字串包含非十六進位制的編碼,無需計算,直接輸出-1表示錯誤
十六進位制轉十進位制舉例,例如十六進位制數23A4共有4位數,從右往左數,含義如下:
數字2在第4位,對應16的3次方
數字3在第3位,對應16的2次方
數字A表示十進位制的10,它在第2位,對應16的1次方
數字4在第1位,對應16的0次方
因此23A4 = 216^3 +316^2 + 1016^1 + 416^0
= 2*4096 + 3*256 + 10*16 + 4*1
= 9124
所以十六進位制的23A4轉成十進位制是9124
輸入
第一行輸入T表示有T個測試例項
第二行輸入第一個十六進位制整數的字串(長度不超過5)
第二行輸入第二個十六進位制整數的字串(長度不超過5)
依此類推輸入下一個例項
輸出
輸出相加的結果,用十進位制表示
樣例輸入
3
A8
9F
3322Q
44455
11111
22222
樣例輸出
327
-1
209715
提示
注意十六進位制的每個位表示十六的不同次冪
之前第一次寫寫的很麻煩,就大概是先判斷兩個字串是否滿足合法的十六進位制數然後再做加法
程式碼如下:
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
bool isok(string x) //判斷是不是合法字串
{
int n=x.length();
for(int i=0;i<n;i++)
if ( !((x[i]>='0' && x[i]<='9') || (x[i]>='A' && x[i]<='F')))
return false;
return true;
}
int main()
{
string str1,str2;
char* str="0123456789ABCDEF";
int T;
cin>>T;
while(T--)
{
cin>>str1>>str2;
string result;
bool tag=true;
if(str1.length()<str2.length()) //判斷哪個字串更長
tag=true;
else tag=false;
if( isok(str1) && isok(str2) ) //呼叫函式來判斷是不是合法字串
{
int maxlen=max(str1.length(),str2.length());
int minlen=min(str1.length(),str2.length());
int yushu=0;
reverse(str1.begin(),str1.end()); //反轉字串容易計算
reverse(str2.begin(),str2.end());
for(int i=0;i<maxlen;i++)
{
int temp=0;
if(i<minlen)
{
if(isalpha(str1[i]))
temp+=toupper(str1[i])-'A'+10;
else temp+=str1[i]-'0';
if(isalpha(str2[i]))
temp+=str2[i]-'A'+10;
else temp+=str2[i]-'0';
result+=str[(temp+yushu)%16];
yushu=(temp+yushu)/16; //這一塊其實可以用函式因為程式碼差不多..
}
else
{
if(tag)
{
if(isalpha(str2[i]))
temp+=str2[i]-'A'+10;
else temp+=str2[i]-'0';
result+=str[(temp+yushu)%16];
yushu=(temp+yushu)/16;
}
else
{
if(isalpha(str1[i]))
temp+=str1[i]-'A'+10;
else temp+=str1[i]-'0';
result+=str[(temp+yushu)%16];
yushu=(temp+yushu)/16;
}
}
}
if(yushu!=0)
result+=str[yushu%16];
int x=0;
int temp2=1;
for(int i=0;i<result.length();i++,temp2*=16) //十六進位制轉十進位制
{
if(isalpha(result[i]))
x+=(result[i]-'A'+10)*temp2;
else x+=(result[i]-'0')*temp2;
}
cout<<x<<endl;
}
else cout<<-1<<endl;
}
return 0;
}
後面又想了想,其實可以考慮使用字串流輸入能減少程式碼量
下面是程式碼:
#include <iostream>
#include <sstream>
using namespace std;
bool isok(string x)
{
int n=x.length();
for(int i=0;i<n;i++)
if( !((x[i]>='0' && x[i]<='9') || (x[i]>='A' && x[i]<='F')))
return false;
return true;
}
int main()
{
int T;
cin>>T;
while(T--)
{
string s1,s2;
cin>>s1>>s2;
int a,b;
if(isok(s1) && isok(s2))
{
stringstream ss(s1);
stringstream ss1(s2);
ss>>hex>>a;
ss1>>hex>>b;
cout<<a+b<<endl;
}
else cout<<-1<<endl;
}
return 0;
}
感覺第一個程式碼寫的挺失敗以後再試試能不能縮減程式碼…寫的略長