题目描述
写出一个程序,接受一个十六进制的数,输出该数值的十进制表示。
数据范围:
1 <=n <= 2 31-1
输入描述:
输入一个十六进制的数值字符串
输出描述:
输出该数值的十进制字符串。不同组的测试用例用\n隔开。
题目来源
示例1a
输入:
0xAA
输出:
170
思路
可以看到方法一中,对于十六进制中的高位字符,要乘以多个16,这种重复的操作增加了时间复杂度。我们可以从左往右处理字符串,将高位字符乘以16的操作和低位字符乘以16一起完成。步骤如下:
(1)设置一个初始值ten为0。
(2)每遇到一个字符,把ten乘以16在加上该字符对应的十进制数。
(3)将(2)的结果赋值给ten。
不断重复操作(2)(3)直到处理完字符串。示意图如下:
具体实现
#include<iostream>
#include<string>
using namespace std;
//将十六进制转换为十进制
void translate(string str)
{
int ten = 0;//初始值
int tran;//每一位的转化值
for (int i = 2; i < str.size(); i++)
{
if ('0' <= str[i] && str[i] <= '9')
tran = str[i] - '0';
else
tran = str[i] - 'A' + 10;
ten = ten * 16 + tran;
}
cout << ten << endl;
}
int main()
{
string str;
while (cin >> str){
translate(str);
system("pause");
}
return 0;
}
时间复杂度
- 时间复杂度:O(n),对于十六进制数中的每一个字符,遍历一次,并且相应地只进行一次乘法操作
- 空间复杂度:O(1)
其他解法
过程如图所示:
#include<iostream>
#include<string>
using namespace std;
int main()
{
string s;
int ten,tran;
while (cin>>s)
{
ten = 0;//初始值为0
for (int i=s.size()-1;i>1;i--)
{
//将十六进制的字符转化为十进制数字
if ('0'<=s[i] && s[i]<='9')
tran = s[i]-'0';
else
tran = s[i]-'A'+10;
//将转化后的数字乘以对应次数的16
for (int j=0;j<s.size()-i-1;j++)
tran = tran*16;
ten += tran;
}
cout<<ten<<endl;
}
return 0;
}
- 时间复杂度: O(N^2)。N表示16进制数的位数。乘以16的操作,从低位到高位依次是0,1,2,…,N-1次,总共为N(N−1)/2次
- 空间复杂度: O(1)。没有开辟新空间