探索C/C++ 进制转换之美:从原理到应用 您所在的位置:网站首页 c语言整数的反序输出 探索C/C++ 进制转换之美:从原理到应用

探索C/C++ 进制转换之美:从原理到应用

2023-05-21 03:40| 来源: 网络整理| 查看: 265

一、简介 (Introduction) 进制前缀表示整数常量示例转换库接口参数及返回值示例二进制0b 或 0B0b1010std::bitsetstd::bitset binary(42); std::bitset binary(“101010”);八进制0075std::octstd::cout std::string hex_str = "2A"; int decimal_num; // 将十六进制字符串转换为十进制整数 std::istringstream(hex_str) >> std::hex >> decimal_num; // 将十进制整数转换为八进制字符串 std::stringstream octal_ss; octal_ss int decimal_num = 61; std::stringstream octal_ss; // 将十进制整数转换为八进制字符串 octal_ss std::string octal_str = "52"; int decimal_num; // 将八进制字符串转换为十进制整数 std::istringstream(octal_str) >> std::oct >> decimal_num; // 将十进制整数转换为二进制字符串 std::bitset binary_bitset(decimal_num); std::string binary_str = binary_bitset.to_string(); // 去除字符串前导零 size_t non_zero_pos = binary_str.find_first_not_of('0'); binary_str = binary_str.substr(non_zero_pos); std::cout int decimal_num = 42; // 将十进制整数转换为二进制字符串 std::bitset binary_bitset(decimal_num); std::string binary_str = binary_bitset.to_string(); // 去除字符串前导零 size_t non_zero_pos = binary_str.find_first_not_of('0'); binary_str = binary_str.substr(non_zero_pos); std::cout std::string hex_str = "2A"; int decimal_num; // 将十六进制字符串转换为十进制整数 std::istringstream(hex_str) >> std::hex >> decimal_num; // 将十进制整数转换为二进制字符串 std::bitset binary_bitset(decimal_num); std::string binary_str = binary_bitset.to_string(); // 去除字符串前导零 size_t non_zero_pos = binary_str.find_first_not_of('0'); binary_str = binary_str.substr(non_zero_pos); std::cout std::string binary; std::string octal; std::string decimal; std::string hexadecimal; };

然后,创建一个进制转换类 BaseConverter,实现所需的功能:

class BaseConverter { public: NumberRepresentation convert(int number) { NumberRepresentation num_repr; num_repr.binary = int_to_binary(number); num_repr.octal = int_to_octal(number); num_repr.decimal = std::to_string(number); num_repr.hexadecimal = int_to_hex(number); return num_repr; } std::string hex_array_to_string(const uint8_t *hex_array, size_t size) { std::stringstream ss; ss int decimal = 0; for (size_t i = 0; i std::string binary; while (decimal > 0) { binary = std::to_string(decimal % 2) + binary; decimal /= 2; } return binary; } int octal_to_decimal_math(const std::string& octal) { int decimal = 0; for (size_t i = 0; i std::string octal; while (decimal > 0) { octal = std::to_string(decimal % 8) + octal; decimal /= 8; } return octal; } int hexadecimal_to_decimal_math(const std::string& hex) { int decimal = 0; for (size_t i = 0; i value = digit - '0'; } else if ('A' value = digit - 'a' + 10; } else { throw std::invalid_argument("Invalid hexadecimal character"); } decimal = decimal * 16 + value; } return decimal; } std::string decimal_to_hexadecimal_math(int decimal) { const char* hex_digits = "0123456789ABCDEF"; std::string hex; while (decimal > 0) { hex = hex_digits[decimal % 16] + hex; decimal /= 16; } return hex; } double binary_fraction_to_decimal_math(const std::string& binary_fraction) { double decimal = 0; double mult = 0.5; for (char ch : binary_fraction) { decimal += (ch - '0') * mult; mult *= 0.5; } return decimal; } std::string decimal_fraction_to_binary_math(double decimal_fraction, int precision) { std::string binary_fraction; while (precision > 0 && decimal_fraction > 0) { decimal_fraction *= 2; binary_fraction += (decimal_fraction >= 1) ? '1' : '0'; if (decimal_fraction >= 1) { decimal_fraction -= 1; } --precision; } return binary_fraction; } private: std::string int_to_binary(int number) { std::bitset binary_bitset(number); std::string binary_str = binary_bitset.to_string(); size_t non_zero_pos = binary_str.find_first_not_of('0'); return binary_str.substr(non_zero_pos); } std::string int_to_octal(int number) { std::stringstream ss; ss BaseConverter converter; int input_number = 42; NumberRepresentation num_repr = converter.convert(input_number); std::cout std::string binary; for (int i = 31; i >= 0; --i) { binary += ((decimal >> i) & 1) ? '1' : '0'; } size_t non_zero_pos = binary.find_first_not_of('0'); return binary.substr(non_zero_pos); }

该函数首先创建一个空的二进制字符串。然后,从最高位(第31位)开始,逐位进行以下操作:使用右移操作符将当前位移动到二进制表示的最低位(第0位),然后用按位与操作符 & 和 1 进行按位与运算。这样可以得到当前位的值(0 或 1)。将这个值转换为字符并添加到二进制字符串中。

最后,使用 find_first_not_of 函数找到第一个不是 ‘0’ 的字符的位置,从该位置开始截取子字符串,以去除前导零。这样,我们使用位操作符实现了十进制整数到二进制字符串的转换。在实际应用中,还可以类似地使用位操作符实现其他进制间的转换。

4.2.3 实际应用案例 (Practical Application Cases)

在某些应用场景中,例如网络协议或加密技术等,位操作符特别适用。使用位操作符进行进制转换可以实现高效的算法,提高程序的性能。

案例1:网络协议

许多网络协议(如 IPv4、IPv6 或 TCP/IP 等)在传输数据时需要操作二进制位。在这些场景中,位操作符可以实现高效的算法,达到更好的性能。

例如,IPv4 地址通常表示为 4 个十进制整数(每个范围在 0-255 之间),用英文句点分隔。但在实际中,IPv4 地址是 32 位的二进制整数。使用位操作符可以方便地在二进制和点分十进制之间进行转换。例如,IP 地址子网掩码的计算就需要用到位操作符。

案例2:加密技术

在加密技术中,密钥和明文往往需要进行位级别的操作以产生密文。例如,DES(Data Encryption Standard)加密算法中,在密钥生成和加密过程中大量使用了位操作符。进行置换、选择、异或等操作时,位操作符可以简化实现过程,提高计算速度。

通过这些实际应用案例,可以看到位操作符在进制转换以及其他处理二进制位的场景中具有明显的性能优势。在性能敏感的场合,使用位操作符进行进制转换和其他二进制位操作是一个理想的选择。同时,我们需要权衡代码的可读性和性能,因此在不同的场景下,我们可以根据需要灵活地选择使用位操作符或其他方法。

4.3 利用C++ 标准库中的进制转换功能 (Using Base Conversion Functions in C++ Standard Library)

C++ 标准库提供了一些实用功能,可帮助我们进行进制转换。例如,可以使用 处理二进制字符串, 实现进制间的转换等。比如以下示例:

例1: 使用 bitset 处理二进制字符串 #include std::string int_to_binary(int integer) { std::bitset binary_bitset(integer); return binary_bitset.to_string(); }

在这个例子中,我们将整数转换为一个包含 32 位的 bitset。接着,我们使用 bitset 的 to_string() 函数将其转换为二进制字符串。需要注意的是,bitset::to_string() 生成的字符串可以包含前导零,根据需求可以选择进一步处理结果。

例2: 使用 stringstream 实现进制间的转换 #include #include int hex_to_decimal(const std::string& hexadecimal) { int decimal; std::stringstream ss(hexadecimal); ss >> std::hex >> decimal; return decimal; }

在此示例中,我们将十六进制字符串转换为十进制整数。首先,我们创建一个 stringstream 对象并将十六进制字符串输入其中。然后使用 std::hex 修饰符指定我们将从 stringstream 读取十六进制整数。最后,通过将 stringstream 对象转换为整数,实现进制间的转换。

在实际项目中,可以根据性能需求和代码可读性来决定是使用位操作符实现进制转换,还是使用 C++ 标准库中提供的功能。在很多情况下,使用 C++ 标准库的功能具有良好的代码可读性,且性能足够满足需求。

五、进制转换相关面试题

本章将提供一些针对进制转换的面试题。这些题目主要分为以下几个部分:

5.1 基本进制转换题目

这部分面试题主要测试对进制转换基本概念的理解和基本编程能力。

面试题1:将给定的十进制整数转换为二进制字符串

问题描述:给定一个非负整数 n,要求将其转换为二进制字符串。

要求:

写一个函数 string decimal_to_binary(int n),输入为非负整数 n,输出为二进制字符串。

示例:

输入: 2 输出: "10" 输入: 10 输出: "1010" 面试题2:将给定的十进制整数转换为十六进制字符串

问题描述:给定一个整数 n,要求将其转换为十六进制字符串。注意:负整数应当用补码表示。

要求:

写一个函数 string decimal_to_hex(int n),输入为整数 n,输出为十六进制字符串。

示例:

输入: 26 输出: "1A" 输入: -1 输出: "FFFFFFFF" 面试题3:将给定的二进制字符串转换为十进制整数

问题描述:给定一个二进制字符串 s,要求将其转换为十进制整数。

要求:

写一个函数 int binary_to_decimal(const string &s),输入为二进制字符串 s,输出为十进制整数。

示例:

输入: "11010" 输出: 26 输入: "1010" 输出: 10 5.2 复杂进制转换题目

这部分面试题较复杂,测试在实际应用中处理较为复杂的进制转换问题的能力。

面试题4:计算两个二进制字符串的和

问题描述:给定两个二进制字符串 a 和 b,返回它们的和(用二进制表示)。

要求:

写一个函数 string add_binary(const string &a, const string &b),输入为两个二进制字符串 a 和 b,输出为它们的和(二进制表示)。

示例:

输入: a = "1010", b = "110" 输出: "10000" 面试题5:将 IPv4 地址从十进制点分表示法转换为二进制表示

问题描述:给定一个有效的 IPv4 地址 ip,使用点分十进制格式表示。请实现一个函数,将给定的 IPv4 地址从十进制点分表示法转换为 32 位二进制整数表示。

要求:

写一个函数 uint32_t ipv4_decimal_to_binary(const string &ip),输入为一个表示 IPv4 地址的字符串,输出为 32 位二进制整数。

示例:

输入: ip = "192.168.1.1" 输出: 3232235777 面试题6:计算汉明距离

问题描述:给定两个整数 x 和 y,计算它们的汉明距离。汉明距离(Hamming distance)是相应位置上二进制数值不同的位数。

要求:

写一个函数 int hamming_distance(int x, int y),输入为两个整数 x 和 y,输出为它们的汉明距离。

示例:

输入: x = 1, y = 4 输出: 2 原因: 1 (0 0 0 1) 4 (0 1 0 0) ↑ ↑ 5.3 进制转换与其他技术结合的题目

这部分面试题将进制转换与其他领域(如数据结构、算法等)相结合,测试在实际项目中处理更加负责的问题的能力。

面试题7:二叉树中根到叶路径的二进制求和

问题描述:给定一个由 0 和 1 组成的二叉树,每个根到叶路径表示一个二进制数。从上到下遍历,指定的一个路径构成的二进制数,请计算所有路径的和。

要求:

给定树的根结点,请写一个函数 int sum_root_to_leaf(TreeNode* root),输入为二叉树的根节点,输出为所有二进制路径和。

示例:

输入: 1 / \ 0 1 / \ / \ 1 0 0 1 输出: 22 解释: (100)1 + (101)5 + (110)6 + (111)7 = 22 面试题8:验证 UTF-8 编码

问题描述:UTF-8 是一种变长字节编码,用于表示 Unicode 编码的字符。请验证给定的字节数组是否表示有效的 UTF-8 编码。

要求:

写一个函数 bool is_valid_utf8(const vector& data),输入为表示字节的整数数组,输出为布尔值,表示输入是否为有效的 UTF-8 编码。

示例:

输入: data = [197, 130, 1] 输出: true 解释: 这是有效的 UTF-8 编码,表示字母 "ć"(U+0107)。 面试题9:数字与字母的相互转换

问题描述:给定一个整数,实现整数与字母之间的相互转换。从 1 开始,分别表示字母 A 到 Z。例如,1 对应 A,2 对应 B,…,26 对应 Z。要求不使用任何库函数。

要求:

写两个函数 string int_to_alpha(int n) 和 int alpha_to_int(const string& s),分别将整数转换为字母字符串和将字母字符串转换为整数。

示例:

输入: 28 输出: "AB" 输入: "AB" 输出: 28 5.4 面试题答案 面试题1:将给定的十进制整数转换为二进制字符串 string decimal_to_binary(int n) { if (n == 0) { return "0"; } string result; while (n > 0) { result = (n % 2 ? '1' : '0') + result; n /= 2; } return result; } 面试题2:将给定的十进制整数转换为十六进制字符串 string decimal_to_hex(int n) { if (n == 0) { return "0"; } const char* hex_digits = "0123456789ABCDEF"; string result; for (int i = 7; i >= 0; --i) { result += hex_digits[(n >> (i * 4)) & 0xf]; } size_t non_zero_pos = result.find_first_not_of('0'); return result.substr(non_zero_pos); } 面试题3:将给定的二进制字符串转换为十进制整数 int binary_to_decimal(const string &s) { int result = 0; for (const char c : s) { result = result * 2 + (c - '0'); } return result; } 面试题4:计算两个二进制字符串的和 string add_binary(const string &a, const string &b) { string result; int i = a.size() - 1, j = b.size() - 1; int carry = 0; while (i >= 0 || j >= 0) { int sum = carry + (i >= 0 ? a[i--] - '0' : 0) + (j >= 0 ? b[j--] - '0' : 0); result = (sum % 2 ? '1' : '0') + result; carry = sum / 2; } if (carry) { result = '1' + result; } return result; } 面试题5:将 IPv4 地址从十进制点分表示法转换为二进制表示 uint32_t ipv4_decimal_to_binary(const string &ip) { uint32_t result = 0; int num = 0, count = 0; for (const char c : ip) { if (c == '.') { result = (result int xor_result = x ^ y; int distance = 0; while (xor_result) { distance += xor_result & 1; xor_result >>= 1; } return distance; } 面试题7:二叉树中根到叶路径的二进制求和 int sum_path(TreeNode* node, int path_val) { path_val = (path_val left && !node -> right) { return path_val; } int total_sum = 0; if (node -> left) { total_sum += sum_path(node -> left, path_val); } if (node -> right) { total_sum += sum_path(node -> right, path_val); } return total_sum; } int sum_root_to_leaf(TreeNode* root) { if (!root) { return 0; } return sum_path(root, 0); } 面试题8:验证 UTF-8 编码 bool is_valid_utf8(const vector& data) { int n_bytes = 0; for (int byte : data) { if (n_bytes == 0) { if (byte >> 5 == 0b110) n_bytes = 1; else if (byte >> 4 == 0b1110) n_bytes = 2; else if (byte >> 3 == 0b11110) n_bytes = 3; else if (byte >> 7 != 0) return false; } else { if (byte >> 6 != 0b10) return false; n_bytes--; } } return n_bytes == 0; } 面试题9:数字与字母的相互转换 string int_to_alpha(int n) { if (n result = char('A' + (n - 1) % 26) + result; n = (n - 1) / 26; } return result; } int alpha_to_int(const string& s) { int result = 0; for (const char c : s) { result = result * 26 + (c - 'A' + 1); } return result; } 六、结论与展望

经过前五章的学习,我们发现进制转换不仅是编程领域中的基础知识,而且对提高逻辑思维能力和解决实际问题具有很大的帮助。从心理学的角度来看,掌握进制转换原理以及相关应用不仅有助于提升对数学思维的理解,还有利于培养求知欲和语言表达能力。

通过本博客所涉及的实例和面试题,我们可以看到进制转换在计算机科学领域中具有广泛的应用,涉及数据结构、网络编程、编码等多个方面。不论是用于工作还是面试,这些知识点都会为你带来独特的优势。同时,编程面试中出现的进制转换相关问题往往需要在有限的时间内找到合适的解决方案,因此从心理学的角度来说,这些问题具有挑战性,有助于锻炼思维能力和建立心理承受压力的机制。

在未来的工作与学习中,我们相信掌握好进制转换技能将在各个领域产生深远的影响。在本博客的学习过程中,希望大家积极参与讨论,增进共同的理解,并将所学应用到实际问题中。同时,我们期待你将所学到的知识和面试题应用于实际项目中,为计算机科学发展做出更多的贡献。

感谢你的阅读与支持!如果你觉得这篇博客对你的学习有所帮助,欢迎点击收藏并点赞。期待我们在学习的道路上相互激励,共同成长!如有任何问题和建议,欢迎在评论区留言讨论,我们将尽快回复。再次感谢!



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有