2 回答
我建议查看Unicode "Script" property。最新的数据库可以在这里找到。
为了快速而肮脏的实现,我会尝试扫描目标文本中的所有字符并查找每个字符的脚本名称。选择具有最多字符的脚本。
使用 N-gram 模型,然后给出足够大的训练数据集。描述此技术的完整示例可在此页面中找到,其中包括:
http://phpir.com/language-detection-with-n-grams/
虽然本文假设您是用 PHP 实现的,并且“语言”是指英语、意大利语等...如果您需要,可以用 C 语言实现描述,而不是像英语等那样使用“语言” . 对于培训,只需使用您的“字母表”概念进行培训。例如,一起查看所有“拉丁字母”字符串,并考虑它们的 n-gram 为 n=2:
卓悦:“Bo”、“on”、“nj”、“jo”、“ou”、“ur”
你好:“他”、“el”、“ll”、“lo”
有了足够的训练数据,您会发现可能适用于所有拉丁文本的主要组合,例如,“Bo”和“el”可能很可能适用于用“拉丁字母”书写的文本。同样,这些组合在以“平假名字母”书写的文本中可能非常罕见。对于您可以提供足够训练数据的任何其他字母分类,也会有类似的发现。
这种技术也称为隐马尔可夫模型或马尔可夫链;搜索这些关键字将为实施提供更多想法。对于“又快又脏”,我会使用 n=2 并收集足够的训练数据,以便每个字母表中最不常见的字母至少遇到一次......例如至少一个“z”和至少一个“ぅ”*小平假名u
编辑:
对于比 N-Grams 更简单的解决方案,仅使用基本统计测试(最小值、最大值和平均值)来比较您的输入(用户给出的字符串)和字母表(您使用的一个字母表中的所有字符的字符串)感兴趣)。
步骤 1. 将 Alphabet 的所有数值(例如 utf8 代码)放入一个数组中。例如,如果要测试的字母是“Basic Latin”,则创建一个数组 DEF := {32, 33, 34, ..., 122}。
步骤 2. 将 Input 的所有数值放入一个数组中,例如,制作一个数组 INP := {73, 102, 32, ...}。
步骤 3. 根据 INP 和 DEF 计算输入的分数。如果 INP 真的来自与 DEF 相同的字母表,那么我希望以下陈述是正确的:
- 最小(INP)>= 最小(DEF)
- 最大值(INP)<=最大值(DEF)
- avg(INP) - avg(DEF) < EPS,其中 EPS 是一个合适的常数
如果所有陈述都是正确的,那么分数应该接近 1.0。如果全部为假,则分数应接近 0.0。在定义了这个“分数”例程之后,剩下的就是在您感兴趣的每个字母表上重复它,并选择一个给定输入的最高分数。