用C++做数据分析 - 唐代诗人的朋友圈
“李杜文章在,光焰万丈长”,唐诗无疑是中国古代文学最灿烂的篇章之一。现代人发表论文,会互相引用,喝酒吃饭,也经常会谈及谁谁谁是我哥们。作为当时最重要的文学形式,唐代的诗人也经常会在诗文中提及自己的好朋友。杜甫比李白小十一岁,二者相识于杜甫父亲杜闲家中,彼时正是李白因触怒权贵放归山林之时。两人一见,杜秒变小迷弟。杜在《与李十二白同寻范十隐居》中描绘了两人的亲密关系:”余亦东蒙客,怜君如兄弟。醉眠秋共被,携手日同行”。不仅如此,在两人各奔东西后,杜甫压抑不住对李白的思念,写了多首提及李白的诗。例如《梦李白》中云:”三夜频梦君,情亲见君意”。能连续三个晚上做梦都梦到李白,可见交情不浅。
通过分析全唐诗中各位诗人之间的“引用”关系,可以描绘出当时诗坛的大致朋友圈图景:谁跟谁熟?谁是圈子里的带头大哥?全唐诗有4万多首,人工一首一首地筛查费时费力,这种重复的统计性质的工作正是计算机最擅长的。
本文引用自作者编写的下述图书; 本文允许以个人学习、教学等目的引用、讲授或转载,但需要注明原作者"海洋饼干叔 叔";本文不允许以纸质及电子出版为目的进行抄摘或改编。
1.《Python编程基础及应用》,陈波,刘慧君,高等教育出版社。免费授课视频 Python编程基础及应用
2.《Python编程基础及应用实验教程》, 陈波,熊心志,张全和,刘慧君,赵恒军,高等教育出版社Python编程基础及应用实验教程
3. 《简明C及C++语言教程》,陈波,待出版书稿。免费授课视频
23. 数据分析 - 唐代诗人的朋友圈
同类相比,同声相应,固天理也。——庄子
本章的代码和数据整合在一个名为C23_PoetsNetwork的文件夹中。注意,本章节所依赖的全唐诗文本以及《中国历代人物传记资料库》使用了繁体中文,所以读者在运行代码查询时,如果使用简体中文输入诗人姓名,结果将与预期不符。
本章内容受开源项目poetry_analyzer的启发。为方便读者理解,作者整理了相关数据并重写了代码。
本章的代码实现依赖于Qt平台的专有特性,只能通过Qt Creator集成开发环境来编写和构建。
23.1 创建程序框架
请读者按照22.1及22.3节所介绍的方法,在Qt Creator中创建一个名为PoetsNetwork的项目,该项目的主窗口如图23-1所示,作者在该图上人工标注了各关键部件的名称。表23-1列出了该项目创建过程中的一些注意事项,以及其主窗口中部分部件的用途。
表23-1 创建PoetsNetwork项目的注意事项及主窗口的主要部件
名目 | 说明 |
---|---|
项目模板 | Application(Qt)/Qt Widgets Application (Qt窗体应用程序)。 |
主窗口 | 类名:MainWidget;基类:QWidget。 |
pbParseQTS | 类型:QPushButton;文字:全唐诗数据整理;用途:将全唐诗文本数据整理并写入到数据库。 |
pbConstructNetwork | 类型:QPushButton;文字:构建关系网络;用途:对数据库中的全唐诗文本正行分析,找出诗人与诗人之间的引用关系并写入数据库。 |
leRefPoet1,leRefPoet2 | 类型:QLineEdit,单行输入框;用途:“引用查询”时输入第一/二个诗人的姓名。 |
pbQueryReference | 类型:QPushButton;文字:引用查询;用途:查询两个诗人之间的引用数量以及相互之间的引用诗文。 |
textBrowser | 类型:QTextBrowser,简单的文字型HTML浏览器;用途:显示程序的部分执行结果。 |
lePoetFriendCycle | 类型:QLineEdit;用途:查询“朋友圈”时输入诗人的姓名。 |
pbFriendCycle | 类型:QPushButton;用途:查询单个诗人的朋友圈,即找出与指定诗人存在引用关系的全部诗人,生成关系网络图,并用浏览器显示。 |
pbNetWork50/100/200/500 | 类型:QPushButton;用途:导出引用数量的前50/100/200/500行引用关系,将由相关诗人姓名及引用箭头组成的关系网络生成出来,并用浏览器显示。 |
图23-2则展示MainWidget主窗口的对象结构以及窗口组件之间的布局关系。如图所示,主窗口自身呈现竖向布局,其内包含4个横向布局以及textBrowser。为了构造出期望的界面效果,读者可能需要:(1) 调整布局的layoutSpacing(布局间隔);(2) 修改按钮、单行输入框的minimumSize(最小尺寸)。此外,在图23-2中,我们还看到了类型为Spacer的部件,这种类型的部件仅用于占据布局空间,其在最终的结果页面上不会有任何显示,它可以把别的部件“挤”到期望的位置。
23.2 数据整理与准备
23.2.1 sqlite数据库
为了便于统计分析以及向读者简单介绍数据库的入门知识和C++访问数据库的方法,本章使用sqlite数据库来存储相关数据。
对于结构化的数据,如个人的身份信息、银行的交易流水、图书馆的借还记录等,通常都存储在数据库系统中。数据库系统通常运行在一个服务器或者由多个服务器构成的集群中,软件使用者的计算机或者终端直接或者间接地透过TCP/IP访问数据库、查询或存储数据。大型的数据库系统软件有阿里蚂蚁金服的OceanBase、华为的GaussDB、开源的MySql以及私有的Oracle。
本章使用的sqlite是一个超级mini版的数据库系统,它本质上是一个运行于软件内部的C语言包。在本章的代码中,数据库的存储文件为C22_PoetsNetwork/data子目录下的data.db。