根据拼音提取首字母

根据拼音提取首字母,例如将连续的拼音字符串(如 "zhongguorenmin")分解为单独的拼音(如 ["zhong", "guo", "ren", "min"]),并能提取出拼音的首字母缩写(如 "zgrm")。

实现代码

这段代码实现了一个拼音分词和缩写提取的功能。

代码主要部分:

  1. TrieNode 类: 实现了一个字典树(Trie)的节点,用于存储拼音。
  2. insert 函数: 将拼音插入到 Trie 中。
  3. search_longest 函数: 在 Trie 中搜索最长匹配的拼音。
  4. extract_initials_and_full 函数: 将输入的文本分解为拼音,返回完整拼音列表。
  5. get_initials 函数: 从完整拼音列表中提取首字母,生成缩写。
  6. 拼音数据: 定义了声母(initials)和韵母(finals)列表。
  7. 生成有效拼音: 通过组合声母和韵母,生成有效的拼音列表。
  8. 特殊情况处理: 添加了一些特殊的拼音情况。
  9. 构建 Trie: 使用有效拼音列表构建 Trie。
  10. 测试用例: 使用一系列测试用例来演示代码的功能。

它使用 Trie 结构来高效地匹配最长的有效拼音,从而实现准确的拼音分词。

class TrieNode:
    def __init__(self):
        self.children = {}
        self.is_end = False
        self.full = ''

def insert(root, word, full):
    node = root
    for char in word:
        if char not in node.children:
            node.children[char] = TrieNode()
        node = node.children[char]
    node.is_end = True
    node.full = full

def search_longest(root, word):
    node = root
    last_match = None
    for i, char in enumerate(word):
        if char not in node.children:
            break
        node = node.children[char]
        if node.is_end:
            last_match = (i, node.full)
    return last_match

def extract_initials_and_full(text, trie):
    result = []
    i = 0
    while i < len(text):
        match = search_longest(trie, text[i:])
        if match:
            end, full = match
            result.append(full)
            i += end + 1
        else:
            result.append(text[i])
            i += 1
    return result

def get_initials(result):
    return ''.join(item[0] for item in result)


initials = ['b', 'p', 'm', 'f', 'd', 't', 'n', 'l', 'g', 'k', 'h', 'j', 'q', 'x', 'zh', 'ch', 'sh', 'r', 'z', 'c', 's', 'y', 'w']

finals = [
    '', 'a', 'o', 'e', 'i', 'u', 'v', 
    'ai', 'ei', 'ui', 'ao', 'ou', 'iu', 'ie', 've', 'er', 
    'an', 'en', 'in', 'un', 'vn', 
    'ang', 'eng', 'ing', 'ong', 
    'ia', 'iao', 'ian', 'iang',
    'iong', 'ua', 'uo', 'uai', 'uan', 'uang',
    'ue', 'van', 've', 'ueng',
    'ong', 'iong'
]

valid_pinyin = [
    (initial + final, initial[0], initial + final)
    for initial in initials
    for final in finals
]

special_cases = ['a', 'o', 'e', 'i', 'u', 'v', 'ai', 'ei', 'ui', 'ao', 'ou', 'an', 'en', 'er', 'ang', 'eng']
valid_pinyin.extend((case, case[0], case) for case in special_cases)

pinyin_trie = TrieNode()
for pinyin, initial, full in valid_pinyin:
    insert(pinyin_trie, pinyin, full)

test_cases = ["zhongguorenmin", "beijingdaxue", "aiwozhonghua", "qiaoersi", "changsha", "liangjiang", "fangyt"]
for case in test_cases:
    result = extract_initials_and_full(case, pinyin_trie)
    initials = get_initials(result)
    print(f"Input: {case}")
    print(f"Full result: {result}")
    print(f"Initials: {initials}")
    print()

输出

Input: zhongguorenmin
Full result: ['zhong', 'guo', 'ren', 'min']
Initials: zgrm

Input: beijingdaxue
Full result: ['bei', 'jing', 'da', 'xue']
Initials: bjdx

Input: aiwozhonghua
Full result: ['ai', 'wo', 'zhong', 'hua']
Initials: awzh

Input: qiaoersi
Full result: ['qiao', 'er', 'si']
Initials: qes

Input: changsha
Full result: ['chang', 'sha']
Initials: cs

Input: liangjiang
Full result: ['liang', 'jiang']
Initials: lj

Input: fangyt
Full result: ['fang', 'y', 't']
Initials: fyt