本文提供一套純 C++、無第三方依賴的中文轉拼音核心代碼,適用於 GB2312 編碼環境。核心思路:預建「區位碼區間 → 拼音」映射表,運行期通過二分查找定位拼音,支援中英數混合字符串轉換。
// 區位碼分界點(按升序),對應拼音表索引
static const unsigned short code_pin[] = {
0xb0a1, 0xb0a3, 0xb0b0, 0xb0b9, 0xb0bc, 0xb0c5, 0xb0d7, 0xb0df,
0xb0ee, 0xb0fa, 0xb1ad, 0xb1bc, 0xb1c0, 0xb1c6, 0xb1de, 0xb1ea,
// ... 共 400+ 個分界點,覆蓋 GB2312 一級漢字區
0xd7f0, 0xd7f2
};
// 拼音表,與 code_pin 索引一一對應
static const char *str_pin[] = {
"a", "ai", "an", "ang", "ao", "ba", "bai", "ban", "bang", "bao",
"bei", "ben", "beng", "bi", "bian", "biao", "bie", "bin", "bing",
"bo", "bu", "ca", "cai", "can", "cang", "cao", "ce", "ceng", "cha",
// ... 共 400+ 個拼音
"zuo"
};
static const size_t SIZE_ARRAY = sizeof(code_pin) / sizeof(short);
const char* get_pin(unsigned short char_zh) {
size_t low = 0, high = SIZE_ARRAY - 1;
while (high - low != 1) {
size_t mid = (low + high) / 2;
if (code_pin[mid] == char_zh) return str_pin[mid];
if (code_pin[mid] < char_zh) low = mid;
else high = mid;
}
// 區間判斷:若 char_zh >= code_pin[high] 則屬於 high 區間,否則屬於 low 區間
return str_pin[code_pin[high] <= char_zh ? high : low];
}
string str_to_pin(const string& input) {
string result;
int len = input.length();
for (int i = 0; i < len; ++i) {
unsigned char high = input[i];
if (high < 0x80) { // ASCII
result.push_back(high);
} else { // GB2312 雙位元組
unsigned char low = input[++i];
unsigned short zh = (high << 8) | low;
result += get_pin(zh);
}
}
return result;
}
string str_to_pin_space(const string& input) {
string result;
int len = input.length();
for (int i = 0; i < len; ++i) {
unsigned char high = input[i];
if (high < 0x80) {
if (i > 0 && input[i-1] < 0) result.push_back(' ');
result.push_back(high);
} else {
if (i > 0) result.push_back(' ');
unsigned char low = input[++i];
unsigned short zh = (high << 8) | low;
result += get_pin(zh);
}
}
return result;
}
string str_to_pin_space_(const string& input) {
string result(1, ' ');
int len = input.length();
for (int i = 0; i < len; ++i) {
unsigned char ch = input[i];
if (ch < 58) { // '0'-'9'
if (i > 0 && (input[i-1] < 0 || input[i-1] > 57)) result.push_back(' ');
result.push_back(ch);
} else if (ch > 64 && ch < 123) { // 'A'-'Z', 'a'-'z'
if (i > 0 && (input[i-1] < 0 || input[i-1] < 58)) result.push_back(' ');
result.push_back(ch);
} else { // 中文
if (i > 0) result.push_back(' ');
unsigned char low = input[++i];
unsigned short zh = (ch << 8) | low;
result += get_pin(zh);
}
}
return result;
}
int main() {
string test = "zhong hua人民dfd啊a152左邊35gdaf共和國";
cout << str_to_pin_space_(test) << endl;
// 輸出: zhong hua ren min dfd a a 152 zuo bian 35 gdaf gong he guo
return 0;
}
| 方向 | 具體措施 |
|---|---|
| 編碼支援 | 集成 iconv / ICU,自動檢測並轉換 UTF-8/GBK/Big5 至內部 GB2312 後查表 |
| 多音字處理 | 引入詞典/語料庫,上下文消歧(如「長」cháng/zhǎng),單字模式可返回首拼音或全部拼音 |
| 性能優化 | 將 code_pin/str_pin 制為 constexpr 編譯期常量;熱路徑改用完美雜湊/Trie O(1) 查找 |
| C API 封裝 | 提供 char* gb2312_to_pinyin(const char*) 供 C/其他語言調用 |
該方案以極小代碼量實現 GB2312 漢字轉拼音核心功能,二分查找保證 O(log N) 查詢效率,三種字符串處理函數覆蓋主流輸出需求。對於嵌入式、無法引入重型庫的場景,是極具性價比的選擇。生產環境建議按上表方向逐步增強編碼兼容性與多音字準確率。