如何在C++中实现类二进制计数的十进制数值及英文转写算法?
Hey Joseph, this is a fun problem—combining binary counting logic with decimal representation and English number words! Let's break this down into two manageable parts: generating that binary-like decimal sequence, and converting each number to its English cardinal equivalent. Here's how to pull this off in C++:
First, let's clarify what this sequence actually is: each number is the binary representation of an integer, interpreted as a decimal number. For example:
- Binary
1→ decimal1 - Binary
10→ decimal10 - Binary
11→ decimal11 - Binary
100→ decimal100, and so on.
The simplest way to generate this is to simulate binary increment on a string, then convert that string to a decimal integer. Here's a straightforward implementation:
#include <iostream> #include <string> #include <algorithm> // Helper to increment a binary string (e.g., "11" → "100") std::string increment_binary_string(std::string s) { int i = s.size() - 1; // Flip 1s to 0s until we hit a 0 or the start of the string while (i >= 0 && s[i] == '1') { s[i] = '0'; i--; } // If we reached the start, prepend a 1 if (i < 0) { s.insert(s.begin(), '1'); } else { s[i] = '1'; } return s; } int main() { std::string binary_str = "1"; // Generate the first 7 numbers in the sequence for (int i = 0; i < 7; i++) { long long decimal_num = stoll(binary_str); // Convert binary string to decimal std::cout << decimal_num << " "; binary_str = increment_binary_string(binary_str); } // Output: 1 10 11 100 101 110 111 return 0; }
Alternatively, you can generate the sequence by taking integers starting from 1, converting each to a binary string, then parsing that string as a decimal number. The string method above is just more direct for this specific use case.
Next, we need a function to turn those decimal numbers into words like "one", "ten", "one hundred and eleven". This requires handling different number ranges (ones, teens, tens, hundreds, thousands, etc.). Here's a robust implementation that works for numbers up to billions:
#include <iostream> #include <vector> #include <string> // Handle numbers 0-19 std::string convert_less_than_20(int num) { const std::vector<std::string> words = { "zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten", "eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nineteen" }; return words[num]; } // Handle multiples of 10 (20, 30, ..., 90) std::string convert_tens(int num) { const std::vector<std::string> words = { "", "", "twenty", "thirty", "forty", "fifty", "sixty", "seventy", "eighty", "ninety" }; std::string result = words[num / 10]; if (num % 10 != 0) { result += "-" + convert_less_than_20(num % 10); } return result; } // Handle numbers 0-999 std::string convert_less_than_1000(int num) { std::string result; if (num >= 100) { result += convert_less_than_20(num / 100) + " hundred"; num %= 100; if (num != 0) { result += " and "; // Remove this line for American English } } if (num != 0) { result += (num < 20) ? convert_less_than_20(num) : convert_tens(num); } return result; } // Handle larger numbers by breaking into thousands/millions/billions std::string number_to_english(long long num) { if (num == 0) return "zero"; const std::vector<std::string> scales = {"", "thousand", "million", "billion"}; std::string result; int scale_idx = 0; while (num > 0) { int part = num % 1000; if (part != 0) { std::string part_str = convert_less_than_1000(part); if (!result.empty()) { result = part_str + " " + scales[scale_idx] + ", " + result; } else { result = part_str + " " + scales[scale_idx]; } } num /= 1000; scale_idx++; } // Clean up trailing spaces/commas if (!result.empty() && result.back() == ' ') result.pop_back(); if (!result.empty() && result.back() == ',') result.pop_back(); return result; }
Now just combine the sequence generator with the word converter. Here's the full example:
// Include all helper functions from above here int main() { std::string binary_str = "1"; for (int i = 0; i < 7; i++) { long long decimal_num = stoll(binary_str); std::cout << decimal_num << " → " << number_to_english(decimal_num) << std::endl; binary_str = increment_binary_string(binary_str); } /* Output: 1 → one 10 → ten 11 → eleven 100 → one hundred 101 → one hundred and one 110 → one hundred and ten 111 → one hundred and eleven */ return 0; }
- Overflow Handling: Use
long longinstead ofintto handle larger numbers in the sequence (since binary strings get long quickly, e.g., binary1000000is decimal1000000, which fits in a 32-bit int, but longer strings will need 64-bit integers). - English Variations: The "and" in "one hundred and one" is standard in British English. For American English, just remove the line adding " and " in
convert_less_than_1000. - Scalability: The word converter works up to billions, but you can extend the
scalesvector to handle trillions and beyond if needed.
内容的提问来源于stack exchange,提问作者Joseph

