题意理解

输入十六进制的数(以字符串的形式),将其转换成十进制数并输出。

方法一

十六进制数最前面两个字符是“0x”,不需要识别。其余字母中,A~F分别代表10~15。从右往左看,最低位要乘以16016^0,倒数第二位要乘以16116^1,以此类推。最后将每一位转化的结果求和即可。过程如图所示: alt

具体代码如下:

#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(N2)O(N^2)。N表示16进制数的位数。乘以16的操作,从低位到高位依次是0,1,2,...,N-1次,总共为N(N1)/2N(N-1)/2次。
空间复杂度: O(1)O(1)。没有开辟新空间。

方法二

可以看到方法一中,对于十六进制中的高位字符,要乘以多个16,这种重复的操作增加了时间复杂度。我们可以从左往右处理字符串,将高位字符乘以16的操作和低位字符乘以16一起完成。步骤如下:
(1)设置一个初始值ten为0。
(2)每遇到一个字符,把ten乘以16在加上该字符对应的十进制数。
(3)将(2)的结果赋值给ten。
不断重复操作(2)(3)直到处理完字符串。示意图如下: alt

具体代码如下:

#include<iostream>
#include<string>

using namespace std;

int main()
{
    string s;
    int ten,tran;
    while (cin>>s)
    {
        ten = 0;//初始值为0
        for (int i=2;i<s.size();i++)
        {
            //将十六进制的字符转化为十进制数字
            if ('0'<=s[i] && s[i]<='9')
                tran = s[i]-'0';
            else
                tran = s[i]-'A'+10;
            ten = ten*16+tran;//不断迭代
        }
        cout<<ten<<endl;
    }
    return 0;
}

时间复杂度: O(N)O(N)。对于十六进制数中的每一个字符,遍历一次,并且相应地只进行一次乘法操作。
空间复杂度: O(1)O(1)。没有开辟新空间。