csdn_export_md

本文介绍了两种编程方法来实现十六进制到八进制的转换,包括通过先转十进制再转八进制以及直接从十六进制转为二进制然后再转八进制。同时,还展示了如何处理IP地址的二进制数据,通过位运算逐段转换。这些技巧对于理解位操作和进制转换在编程中的应用至关重要。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

2021.3.30.每日" 一"题

-PTA第一题"十六进制转换为八进制"

出题人:孙佳萌
思路
方法可以为十六进制转换为十进制,十进制再转换为八进制
也可以为十六进制转换为二进制,二进制再转换为八进制

#include<iostream>  // 转二进制做法
#include<string>
using namespace std;
int main() {
	string s1, s2;
		cin >> s1;
		if (s1 == "0") {
			cout << 0;
		}
		else {
			s2 = "";//二进制
			for (int j = 0; j < s1.length(); j++) {
				switch (s1[j]) {//将十六进制转为二进制 
				case '0':
					s2 += "0000";
					break;
				case '1':
					s2 += "0001";
					break;
				case '2':
					s2 += "0010";
					break;
				case '3':
					s2 += "0011";
					break;
				case '4':
					s2 += "0100";
					break;
				case '5':
					s2 += "0101";
					break;
				case '6':
					s2 += "0110";
					break;
				case '7':
					s2 += "0111";
					break;
				case '8':
					s2 += "1000";
					break;
				case '9':
					s2 += "1001";
					break;
				case 'A':
					s2 += "1010";
					break;
				case 'a':
					s2 += "1010";
					break;
				case 'B':
					s2 += "1011";
					break;
				case 'b':
					s2 += "1011";
					break;
				case 'C':
					s2 += "1100";
					break;
				case 'c':
					s2 += "1100";
					break;
				case 'D':
					s2 += "1101";
					break;
				case 'd':
					s2 += "1101";
					break;
				case 'E':
					s2 += "1110";
					break;
				case 'e':
					s2 += "1110";
					break;
				case 'F':
					s2 += "1111";
					break;
				case 'f':
					s2 += "1111";
					break;
				default:
					break;
				}
			}
			//要转为8进制,必须是3的倍数,若不满足条件,则补0 
			if (s2.length() % 3 == 1)
				s2 = "00" + s2;
			if (s2.length() % 3 == 2)
				s2 = "0" + s2;
			int flag = 0;
			for (int k = 0; k < s2.length() - 2; k += 3) {//三位为一个单位
				int p = 4 * (s2[k] - '0') + 2 * (s2[k + 1] - '0') + s2[k + 2] - '0';
				if (p) //去前导0 
					flag = 1;
				if (flag)
					cout << p;
			}
			cout << endl;
		}
		
	
	return 0;
}


//
// 转十进制方法
#include <iostream>
using namespace std;
int main()
{
    string s;
    cin >> s;
    int ans = 0,sum=1;
    for (int i=0;i<s.size();i++) {
        if (s[i] >= '0' && s[i] <= '9') ans = ans*16 + s[i] - '0';
        else if (s[i] >= 'A' && s[i] <= 'Z') {
            ans = ans*16+s[i]-'A'+10;
        }
        else {
            ans = ans*16+s[i]-'a'+10;
        }
    }
    cout << oct << ans;  // 十进制转八进制方法与上述类似,笔者在此偷个懒
    return 0;
}

补充
有同学可能会想到直接接收十六进制类型的数据,然后输出八进制类型的数据,这样很简单,但是只要能这样做的题,都极少会出现在竞赛中,所以该方法了解即可,还是要掌握上述代码转换的方法.

-PTA第二题"IP地址转换"

出题人:张一帆
差异

和上题不同的是,本题更偏向于字符串的使用,读取字符串后,从左到右开始扫描,每8个字符转换一次数据,因题目给出的是二进制数据,所以灵活运用位运算可以使代码更加简洁.

#include <iostream>
using namespace std;
string s;   // 声明一个字符串
int dp[4],flag;  // 储存转换后的数据
int main()
{
    cin >> s;
    for (int i=0;i<s.size();i++) {
        if (s[i] == '1') dp[flag] |= 1;  // 如果改字符为1,则使该数二进制下的第一位变为1
        dp[flag] <<= 1;  // 另该数左移一位
        if ((i+1)%8 == 0) dp[flag] >>= 1,flag++;  // 如果满足此条件,则表示已扫描过了8个字符,因为之前dp[flag]会向左多移一位,所以此时向右移一位
    }
    for (int i=0;i<4;i++) {  // 输出结果
        cout << dp[i];
        if (i != 3) cout << ".";
    }
    return 0;
}

补充
如果之前没有接触过位运算,又或者是位运算不熟练,可以自己根据数据多演算几遍,明白位运算的原理.

ACWING"快速幂" https://www.acwing.com/problem/content/91/

方法分为两种,迭代法和递归法,原地址的题解介绍的很充分

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值