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);