C/C++小案例:汉语自动分词器
文章目录
- 成果
- 一、模型设计
- 1.1 汉语自动分词:
- 1.1.1 基本理论:
- 1.1.2 算法基本思想:
- 1.1.3 算法评价:
- 二、系统设计
- 2.1 汉语自动分词:
- 2.1.1 数据结构:
- 2.1.2 算法实现:
- 2.1.3 算法评估:
- 三、开发环境
- 四、源码
成果
一、模型设计
1.1 汉语自动分词:
1.1.1 基本理论:
词是自然语言中能够独立运用的最小单位,是自然语言处理的基本单位。自动词法分析就是利用计算机对自然语言的形态 (morphology) 进行分析,判断词的结构和类别等。词性或称词类(Part-of-Speech, POS)是词汇最重要的特性,是连接词汇到句法的桥梁。
1.1.2 算法基本思想:
正向最大匹配算法 (Forward MaxMatch, FMM) 描述:
假设句子:S = c1c2…cn ,某一词:w = c1c2…cm,m 为词典中最长词的字数。
(1)令 i=0,当前指针 pi 指向输入字串的初始位置,执行下面的操作。
(2)计算当前指针 pi 到字串末端的字数(即未被切分字串的长度)n,如果 n=1,转 第四步,结束算法。否则,令 m=词典中最长单词的字数,如果 n<m, 令 m=n;
(3)从当前 pi 起取 m 个汉字作为词 wi,判断:a.如果 wi 确实是词典中的词,则在 wi 后添加一个切分标志,转(c);b.如果 wi 不是词典中的词且 wi 的长度大于 1,将wi 从右端去掉一个字,转(a)步;否则(wi 的长度等于 1),则在 wi 后添加一个切分标志(单字),执行 (c)步;c.根据 wi 的长度修改指针 pi 的位置,如果 pi 指向字串末端,转(4),否则,i=i+1,返回第二步;
(4)输出切分结果,结束分词程序。
1.1.3 算法评价:
优点:
- 程序简单易行,开发周期短;
- 仅需要很少的语言资源(词表),不需要任何词法、句法、语义资源;
缺点:
歧义消解的能力差;
切分正确率不高,一般在 95%左右。
二、系统设计
2.1 汉语自动分词:
2.1.1 数据结构:
unordered_map<string, int> StrInt_Hash : 哈希表存储词典(便于查询)
2.1.2 算法实现:
对词典进行预处理,截取出所有中文汉字。
循环读入字符串(遇到空格刚好读出一个字符串),直到文件结束。在此过程中,记录下词典中最长词的字节数。
实现函数:
void InitText(string infile);
正向最大匹配算法。
对汉语自动分词的正向匹配算法的实现(模型方法中有详细叙述),并将生成好的分词结果写入到文件中。
实现函数:
void PositiveMaxMatch(string _infile, string _outfile);
2.1.3 算法评估:
理论上,时间复杂度最差为:(Maxlen*Maxlen) (Maxlen 代表词典中最长词的字节数)
三、开发环境
操作系统:Windows 10
编程语言:C/C++
开发工具:Visual Studio 2017
四、源码
项目链接:
https://download.csdn.net/download/weixin_45525272/65216294
源代码:
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <string>
#include <fstream>
#include <sstream>
#include <unordered_map>
#include <ctime>using namespace std;
/// 预处理
#define MAX(a,b) a>b?a:b // 获取两个值中最大的
#define MIN(a,b) a<b?a:b // 获取两个值中最小的
#define ERROR_0 cerr << "Open error !!!" << endl; exit(1); // 文件打开出错提示int MaxLen; // 词典中最长词的字节数
unordered_map<string, int> StrInt_Hash; // 哈希表存储词典(便于查询)const string ini_file = "1998-01-2003版-带音.txt"; // 词典
const string infile = "in.txt"; // 需要分词的文件
const string outfile = "out.txt"; // 分词后的文件
string project_time = "project_time.txt"; // 存储整个程序所运行的时间的文件// 对词典进行预处理,截取出所有中文汉字
void InitText(string _infile)
{// 打开文件ifstream file_in;file_in.open(_infile);if (!file_in){ERROR_0;}string str_tmp, str;int pos;MaxLen = 0;// 循环读入字符串(遇到空格刚好读出一个字符串),直到文件结束。// 在此过程中,记录下词典中最长词的字节数while (file_in >>str_tmp){pos = str_tmp.find("/");str = str_tmp.substr(0,pos);if (str.size() > MaxLen) {MaxLen = str.size();}StrInt_Hash[str] = 1;}// 关闭文件file_in.close();file_in.clear();
}/// 正想最大匹配算法
void PositiveMaxMatch(string _infile, string _outfile)
{// 初始化InitText(ini_file);// 打开文件ifstream file_in;ofstream file_out;file_in.open(_infile);file_out.open(_outfile);if (!file_in){ ERROR_0;}if (!file_out){ERROR_0;}// 开始计时ofstream file_out_time;file_out_time.open(project_time);if (!file_out_time){ERROR_0;}clock_t myStart, myFinish;double time_total;myStart = clock();/// 匹配算法std::ostringstream tmp;tmp << file_in.rdbuf();string text_tmp = tmp.str();int myBegin = 0;int myEnd = text_tmp.size();while (myBegin< myEnd){string str;int num;// 从最大长度的哈希元素进行查找,找不到长度-1,直到找到匹配的for (num=MIN(MaxLen,(text_tmp.size()-myBegin));num>0;num--){str = text_tmp.substr(myBegin,num);// 如果在哈希表中能找到并且,那么就写进去if (StrInt_Hash.find(str)!=StrInt_Hash.end()){file_out << str;myBegin += num;break;}}// 如果没找到,那么不构成词,单独划分if (0 == num) {file_out << text_tmp.substr(myBegin, 1);myBegin += 1;}file_out << "/";}// 结束计时myFinish = clock();time_total = (double)(myFinish - myStart) / CLOCKS_PER_SEC; // 计算运行总时间file_out_time << "运行时间为: " << time_total << " 秒。" << endl;// 关闭文件file_out_time.close();file_out_time.clear();file_out.close();file_out.clear();file_in.close();file_in.clear();
}int main()
{PositiveMaxMatch(infile,outfile);return 0;
}
C/C++小案例:汉语自动分词器相关推荐
- SpringMVC简单小案例
SpringMVC简单小案例 导入spring-webmvc下的所有包 采用Maven导入 <dependency><groupId>org.springframework&l ...
- vue3.0网易云音乐及入门小案例
前言 之前学习vue3.0时做了几个小案例,近段时间又找了几个案例想着把之前做的那些和现在做的放在一起于是休息的时候就搭建了一个vue3的项目.这个项目所用的数据都是页面上写死的,音乐播放器数据是调用 ...
- 前端实战小案例--canvas实战之FlappyBird小游戏
前端实战小案例--canvas实战之FlappyBird小游戏 想练习更多前端案例,请进个人主页,点击前端实战案例->传送门 觉得不错的记得点个赞?支持一下我0.0!谢谢了! 不积跬步无以至千里 ...
- 基因组层次聚类实战小案例
基因组层次聚类实战小案例 预处理数据集 层次聚类 聚类结果分析 预处理数据集 提供的数据集是字符串形式,且不符合聚类的要求,需要进行转置,因此对数据进行预处理. 1.读入103个基因组的名称 原数据格 ...
- 汉语自动分词研究评述
汉语自动分词研究评述 [作者]孙茂松/邹嘉彦 [作者简介]孙茂松,清华大学 邹嘉彦,香港城市大学 孙茂松,100084 北京.清华大学计算机系 Email:lkc-dcs@mail. ...
- SSM实现登录注册的小案例(手把手喂饭)
SSM实现登录注册的小案例 温馨提示 为了您有更好的阅读体验,原文链接如下,长理小生:https://lixingweiblog.github.io/Pages SpringMVC+Spring+My ...
- 抖音怎么上热门网红 火山小视频md5修改器
抖音怎么上热门网红 火山小视频md5修改器 除了电商和新零售之外,抖音在社交领域的尝试让我们看到了短视频在社交化道路上的诸多可能性.可以预见的是未来随着基于短视频 ...
- Flink入门第十二课:DataStream api/Flink sql实现每隔5分钟统计最近一小时热门商品小案例
用到的数据文件 用到的数据文件 链接:https://pan.baidu.com/s/1uCk-IF4wWVfUkuuTAKaD0w 提取码:2hmu 1.需求 & 数据 用户行为数据不断写入 ...
- 通道注意力:pytorch小案例
一.通道注意力机制简介 下面的图形象的说明了通道注意力机制 二.通道注意力机制 class ChannelAttention(nn.Module):def __init__(self, in_plan ...
最新文章
- 堆(heap)与栈(stack)的区别(二)
- 微型计算机原理指令系统问题,微机原理复习题(指令系统).doc
- ADO.NET Entity Framework -Code Fisrt (二)
- Spring任务调度之Spring-Task
- 二:Go编程语言规范-类型
- python 有什么一般人不知道的缺点_关于python,你知道它的优缺点吗?
- 最详细的 Spring Boot 多模块开发与排坑指南
- PyTorch 入坑四 梯度、链式法则、计算图与反向传播
- SVN 使用hooks 自动更新到远程的web目录下
- c# 调用jtts_Java与C#开发上的一些差异与转换方法
- 分享:20 本优秀的 Python 电子书
- kafka分布式消息系统集群搭建-- 详细过程
- jquery和ajax实战教程电子书,《jQuery和Ajax实战教程》邵山欢_孔网
- javascript 使用zlib发送wss请求,接收blob,并解压
- 合宙 air720 模块通过串口助手连接到阿里云 IOT
- 记一次oracle通过dblink连接mysql实施
- 关于echarts自定义合并中国地图分区展示的问题
- EditPlus正则表达式替换字符串详解
- thingsboard使用地图和表可视化资产数据~看完还不会 你pan我
- 2020最流行的JavaScript库-js库