维吾尔语数字转文本

维吾尔语数字读法转换器 - 设计与实现

完整代码在最下面封装到一个类里面大家随便用。

一、背景与需求

在维吾尔语语音合成(TTS)和文本处理场景中,经常需要将阿拉伯数字转换为维吾尔语的自然读法。例如:

  • 123.45 → بىر يۈز يىگىرمە ئۈچ پۈتۈن يۈزدىن قىرىق بەش
  • 100 → يۈز(而非 بىر يۈز)
  • 1000 → مىڭ(而非 بىر مىڭ)

这种转换需要遵循维吾尔语的数字读法习惯,包括数位规则、特殊省略规则、小数读法等。


二、维吾尔语数字读法规则

2.1 基础数字(0-9)

数字 维吾尔语 数字 维吾尔语
0 نۆل 5 بەش
1 بىر 6 ئالتە
2 ئىككى 7 يەتتە
3 ئۈچ 8 سەككىز
4 تۆت 9 توققۇز

2.2 十位整数的固定读法

维吾尔语中,整十数有固定的读法:

数字 维吾尔语 数字 维吾尔语
10 ئون 60 ئاتمىش
20 يىگىرمە 70 يەتمىش
30 ئوتتۇز 80 سەكسەن
40 قىرىق 90 توقسان
50 ئەللىك

2.3 数位单位

从右向左,每3位一组,对应的单位:

位置 单位 说明
第1组(个位组) 无 0-999
第2组 مىڭ 千
第3组 مىليۇن 百万
第4组 مىليارد 十亿
第5组 تىرىليۇn 万亿

2.4 三位数读法规则

任意三位数(0-999)的读法:

  1. 百位 :数字 + يۈز
  2. 十位 :
    • 整十:使用固定的整十读法
    • 非整十:十位词 + 个位数字
  3. 个位:直接读出数字

特殊规则: 当数字为 100 且是最高位组且后面没有非零组时,读作 يۈز,省略开头的 بىر。

2.5 分组读法示例

数字 分组 读法
223 223 ئىككى يۈز يىگىرمە ئۈچ
003 003 ئۈچ
223,003 223 | 003 ئىككى يۈز يىگىرمە ئۈچ مىڭ ئۈچ

2.6 小数读法

小数部分根据位数决定单位:

小数位数 单位 示例
1位 ئوندىن 0.5 → نۆل پۈتۈن ئوندىن بەش
2位 يۈزدىن 12.43 → ئون ئىككى پۈتۈن يۈزدىن قىرىق ئۈچ
3位 مىڭدىن 223003.234 → ئىككى يۈز يىگىرمە ئۈچ مىڭ ئۈچ پۈتۈن مىڭدىن ئىككى يۈز ئوتتۇز تۆت

格式: 整数部分 + پۈتۈن + 小数单位 + 小数数字读法

2.7 特殊规则(省略"بىر")

当满足以下条件时,省略开头的 بىر:

  1. 数字以1开头
  2. 后面全是0
  3. 是最高位组且后面没有非零组
数字 常规读法 正确读法 说明
100 بىر يۈز يۈز 100是整百
1000 بىر مىڭ مىڭ 1000是整千
1000000 بىر مىليۇن مىليۇn 100万是整百万
102 بىر يۈز ئىككى بىر يۈز ئىككى 有零头,不省略
1001 بىر مىڭ بىر مىڭ بىر 千位组后面有非零组

三、算法设计

3.1 核心流程

复制代码
输入数字
    ↓
转为字符串
    ↓
处理科学计数法
    ↓
处理负数
    ↓
分离整数和小数
    ↓
整数部分处理 ← 从右向左每3位分组 → 每组独立读 → 加单位
    ↓
小数部分处理 ← 判断位数 → 加单位 → 读取数字
    ↓
拼接:整数部分 + پۈتۈن + 小数部分
    ↓
处理负数符号
    ↓
返回结果

3.2 整数部分处理算法

复制代码
function readIntegerPart(numStr):
    去除前导零
    如果 numStr == "0": 返回 "نۆل"
    
    // 从右向左每3位分组
    groups = []
    while numStr 还有字符:
        groups.push(numStr.slice(-3))
        numStr = numStr.slice(0, -3)
    groups.reverse()
    
    result = []
    for group in groups:
        if group == 0: continue
        
        // 判断是否为最高位组
        isFirst = (index == 0)
        // 检查后面是否有非零组
        hasFollowingNonZero = check(groups, index)
        
        // 读取当前组(三位数)
        words = readThreeDigits(group, isFirst, hasFollowingNonZero)
        result.push(words)
        
        // 添加单位
        unitIndex = groups.length - 1 - index
        if unitIndex > 0:
            result.push(UNITS[unitIndex])
    
    return result

3.3 三位数读法算法

复制代码
function readThreeDigits(num, isFirst, hasFollowingNonZero):
    if num == 0: return []
    
    result = []
    hundreds = floor(num / 100)
    remainder = num % 100
    
    // 处理百位
    if hundreds > 0:
        // 特殊规则:100 读作 "يۈز"
        if hundreds == 1 && remainder == 0 && isFirst && !hasFollowingNonZero:
            result.push("يۈز")
        else:
            result.push(DIGITS[hundreds])
            result.push("يۈز")
    
    // 处理十位和个位
    if remainder > 0:
        if remainder < 10:
            result.push(DIGITS[remainder])
        else if remainder % 10 == 0:
            result.push(TENS[remainder])
        else:
            tens = floor(remainder / 10) * 10
            ones = remainder % 10
            result.push(TENS[tens])
            result.push(DIGITS[ones])
    
    return result

3.4 小数部分处理算法

复制代码
function readDecimalPart(decimalStr):
    if decimalStr为空: return []
    
    len = decimalStr.length
    unit = DECIMAL_UNITS[len]
    
    // 超过3位小数,逐位读出
    if unit不存在:
        逐位读取每个数字
        return result
    
    // 去除前导零后读取
    num = parseInt(decimalStr)
    if num == 0:
        return [unit, "نۆل"]
    
    // 按三位一组读取
    result = readIntegerPart(String(num))
    result.unshift(unit)  // 添加小数单位
    
    return result

四、实现方案

4.1 技术选型

  • 语言:JavaScript(ES6+)
  • 运行环境:浏览器
  • 设计模式:类封装
  • 字符集:UTF-8(支持维吾尔语阿拉伯字母)

4.2 类结构设计

javascript 复制代码
class UyghurNumberConverter {
  // 静态数据映射
  static DIGITS = { ... }          // 0-9基础数字
  static TENS = { ... }            // 10-90整十数
  static UNITS = [ ... ]           // 数位单位
  static DECIMAL_UNITS = { ... }   // 小数单位
  
  // 核心方法
  static readThreeDigits()         // 读取三位数
  static hasNonZeroAfter()         // 检查后续非零组
  static readIntegerPart()         // 读取整数部分
  static readDecimalPart()         // 读取小数部分
  
  // 公开API
  convert()                        // 单个转换
  convertBatch()                   // 批量转换
  convertWithFormat()              // 格式化输出
}

4.3 数据映射

基础数字:

javascript 复制代码
DIGITS = {
  0: 'نۆل', 1: 'بىر', 2: 'ئىككى', 3: 'ئۈچ',
  4: 'تۆت', 5: 'بەش', 6: 'ئالتە',
  7: 'يەتتە', 8: 'سەككىز', 9: 'توققۇز'
}

整十数:

javascript 复制代码
TENS = {
  10: 'ئون', 20: 'يىگىرمە', 30: 'ئوتتۇز',
  40: 'قىرىق', 50: 'ئەللىك', 60: 'ئاتمىش',
  70: 'يەتمىش', 80: 'سەكسەن', 90: 'توقسان'
}

数位单位:

javascript 复制代码
UNITS = ['', 'مىڭ', 'مىليۇن', 'مىليارد', 'تىرىليۇn']

小数单位:

javascript 复制代码
DECIMAL_UNITS = {
  1: 'ئوندىن',   // 十分位
  2: 'يۈزدىن',   // 百分位
  3: 'مىڭدىن'    // 千分位
}

五、使用示例

5.1 基础使用

javascript 复制代码
// 创建转换器实例
const converter = new UyghurNumberConverter();

// 转换整数
converter.convert(123);        // "بىر يۈز يىگىرمە ئۈچ"
converter.convert(100);        // "يۈز"
converter.convert(1000);       // "مىڭ"
converter.convert(1001);       // "مىڭ بىر"

// 转换小数
converter.convert(12.43);      // "ئون ئىككى پۈتۈن يۈزدىن قىرىق ئۈچ"
converter.convert(100.6);      // "يۈز پۈتۈن ئوندىن ئالتە"
converter.convert(223003.234); // "ئىككى يۈز يىگىرمە ئۈچ مىڭ ئۈچ پۈتۈن مىڭدىن ئىككى يۈز ئوتتۇز تۆت"

5.2 批量转换

javascript 复制代码
const numbers = [1, 10, 100, 1000];
converter.convertBatch(numbers);
// ['بىر', 'ئون', 'يۈز', 'مىڭ']

5.3 格式化输出

javascript 复制代码
const result = converter.convertWithFormat(12345.67);
// {
//   number: 12345.67,
//   reading: 'ئون ئىككى مىڭ ئۈچ يۈز قىرىق بەش پۈتۈن يۈزدىن ئاتمىش يەتتە',
//   formatted: '12,345.67'
// }

六、测试用例

6.1 测试数据

javascript 复制代码
const testCases = [
  0, 5, 12, 20, 43, 99,
  100, 102, 130, 200, 305,
  1000, 1001, 1100, 12345,
  223003, 1000000, 1000001, 1000100,
  12.43, 100.6, 1000.5, 223003.234,
  3.14, 0.5, 100.01,
  1234567890, -123, -3.14
];

6.2 预期输出

数字 维吾尔语读法
0 نۆل
100 يۈز
102 بىر يۈز ئىككى
1000 مىڭ
1001 مىڭ بىر
223003.234 ئىككى يۈز يىگىرمە ئۈچ مىڭ ئۈچ پۈتۈن مىڭدىن ئىككى يۈز ئوتتۇز تۆت

七、性能与优化

7.1 时间复杂度

  • 单次转换:O(log n),其中n为数字大小
  • 批量转换:O(k log n),k为数字个数

7.2 空间复杂度

  • 转换过程中使用数组存储中间结果
  • 内存占用与数字位数成正比

7.3 优化点

  1. 缓存机制:对重复出现的数字可考虑缓存结果
  2. 流式处理:对于超大数字,可考虑流式处理避免内存溢出
  3. 预编译:将静态数据预编译,减少运行时开销

八、扩展性考虑

8.1 支持更多数位

当前支持到 تىرىليۇn(万亿),如需支持更大数字,只需扩展 UNITS 数组。

8.2 支持更多小数位

当前支持3位小数(千分位),如需支持更多位,可扩展 DECIMAL_UNITS 或实现逐位读法。

8.3 支持其他语言

该设计模式可推广到其他语言的数字读法转换,只需替换数据映射和读法规则。


九、总结

本文介绍了维吾尔语数字读法转换器的设计与实现,包括:

  1. 完整的规则整理:基础数字、整十数、数位单位、分组读法、小数读法、特殊规则
  2. 清晰的算法设计:核心流程、整数处理、小数处理、三位数读法
  3. 完善的实现方案:类封装、数据映射、API设计
  4. 丰富的使用示例:单个转换、批量转换、格式化输出

该工具可广泛应用于维吾尔语TTS配音、文本处理、教育软件等场景,具有良好的实用价值和扩展性。

相关推荐
小羊没烦恼!3 天前
微服务化的基石——持续集成
java·大数据·word·powerpoint·.net
倒头就睡的小比特3 天前
算法竞赛C++常用的STL
c++·算法
默_笙3 天前
🍙 给每个请求过安检:FastAPI 是怎么把校验写进类型注解的
python
俊昭喜喜里3 天前
java中的继承和多态的区别
java
小羊没烦恼!3 天前
初探性能优化——2个月到4小时的性能提升
java·开发语言·windows·算法·c#
qq_426003963 天前
启动playwright录制codegen生成自动化测试脚本
python·自动化
譕痕3 天前
JSONObject与JSONArray封装数据格式区别
java·json
虎头金猫3 天前
4K 视频总卡在公网带宽?用 N1 + OpenList 把网盘播放链路重新理顺
运维·服务器·网络·python·容器·beautifulsoup·pandas
胡写代码3 天前
别再前后端各写一套表单校验了
java·后端
小鱼能吃糖3 天前
缺陷修复总览 · mall电商项目:5类缺陷,1个病根,4个业务域
java·电商