HJ33.整数与IP地址间的转换
#include <iostream>
#include <string>
#include <sstream>
#include <regex>
#include <string.h>
const int BYTE = 8;
unsigned int str2uint(const std::string& s) {
unsigned int ret = 0;
std::stringstream ss;
ss << s;
ss >> ret;
ss.clear();
return ret;
}
std::string uint2str(unsigned int n) {
std::string ret = "";
std::stringstream ss;
ss << n;
ss >> ret;
ss.clear();
return ret;
}
unsigned int ip2uint(const std::string& s) {
unsigned int ans = 0;
for (char* p = strtok((char*)s.data(), "."); p; p = strtok(NULL, ".")) {
ans = (ans << BYTE) + str2uint(p);
}
return ans;
}
std::string uint2ip(unsigned int n) {
std::string ans;
for (int i = 4; i > 0; --i) {
ans = (i == 1 ? "" : ".") + uint2str(n & ((1 << BYTE) - 1)) + ans;
n >>= BYTE;
}
return ans;
}
bool is_ip(const std::string& s) {
std::regex res("\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}");
return std::regex_match(s, res);
}
int main() {
std::string in;
while (getline(std::cin, in)) {
if (is_ip(in)) {
std::cout << ip2uint(in) << '\n';
}else {
std::cout << uint2ip(str2uint(in)) << '\n';
}
}
return 0;
}
解题思路:
难点1:这题用c来解算是撞在枪口上了,c的位运算简直不要太爽,只要能想到与2的幂方相关的运算都能用位运算来做就可以了,整数转字符串一个稍微绕点,因为要取模;
难点2:再次吐槽c++的字符串与整形之间的类型转换,迫不得已手撕了一大堆,有空手撕个通用的模板;
难点3:是否是ip的判断吧,感觉仅用'.'来判断是不是ip也太草率了,这里还是用了正则,算是活学活用了;
难点4:与2的幂方相关的取模、乘除分别对应的等价形式,不知道就拉闸,硬算也可以,费事点;
难点5:c++的split,还好已经踩过坑,上一道题的strtok直接用上;
知识点:
知识点1:与2的幂方相关位运算;
2^n <——> 1 << n;
a * 2^n <——> a << n;
a / 2^n <——> a >> n;
a % 2^n <——> a & ((1 << n) - 1);