仓库源文站点原文

https://zhuanlan.zhihu.com/p/12557495920

前文 对伪代码的中文化未与实际代码联系。趁找形声字的机会尝试一下。

迭代0

算法大概描述

将每个字拆为部件
如果部件的音和字的音相同,此字为形声字

木兰相关代码实现

以下略去了文件读取数据部分,完整代码 在此,命令行下 % 木兰 测试/实用/字/取形声字.ul 运行。

func 取形声字(所有字) {
  形声字 = []
  for 字 in 所有字 {
    字音 = 字典.查单字(字)['拼音']

    for 部件 in 字典.的结构(字)['部分']{
      部件信息 = 字典.查单字(部件)
      if 部件信息 and 部件信息['拼音'] == 字音 {
        形声字.append(字)
      }
    }
  }
  return 形声字
}

迭代1

将需求精确化:

输入 所有字
输出 形声字
逐字处理,拆为部件,逐部件检查,如果与字音相同,此字为形声字

代码 API 化后,业务部分尽量消除数据格式等业务无关部分:

func 字音(字) {
  信息 = 字典.查单字(字)
  return 信息 ? 信息['拼音'] : nil
}

func 取部件(字) {
  return 字典.的结构(字)['部分']
}

// 业务部分
func 取形声字(所有字) {
  形声字 = []
  for 字 in 所有字 {
    for 部件 in 取部件(字){
      if 字音(部件) == 字音(字) {
        形声字.append(字)
      }
    }
  }
  return 形声字
}

迭代2

描述继续伪代码化,将相同语义的语法尽量一致:

输入 所有字
输出 形声字
将所有字逐个检查,将字的部件逐个检查,如果任一部件的音与字的音相同,此字为形声字

代码改个风格,顺便用一下较少用到的内置 API。

func 任一(全集) { return any(全集) }

func 取形声字(所有字) {
  return list(
    filter(
      字 -> 任一(
        map(
          部件 -> 字音(部件) == 字音(字),
          取部件(字)
        )),
    所有字)
  )
}

对比结果时,发现迭代#1中一个代码bug,在结果中‘励’字出现了两次。

此例至此步,看似从伪代码生成实际代码已近可行。