:::tip 想做一个将文本处理的脚本,每次期末复习的效果感觉有点不好,在高中的时候,每天做题,感觉这样的效果会比较好一点。所以就想着能不能将期末的复习题文档转换成题库的形式。 :::
# 需求
需求很简单,给一个带有很多题的文档,然后这个应用可以将文档转换成题库,例如:假如是一道选择题,应用可以将这道选择题分解开,选项变成可以选择的按钮,假如选的是正确的答案,这个选项会有提示正确,反之则提示错误。以后努力可以支持更多的题型。
# 分析与设计
暂时先不考虑文档的多样性。文档以txt
格式,且格式是固定的。
我觉得最难的在于如何将这一道道选择题区分开,如何将选项区分开,如何提取出选项,题号,选项号,下面就围绕上述几个问题展开分析一下。
:::tip
35.在系统间提供可靠的数据传输的层次是(D)。 A、物理层 B、数据层 C、网络层 D、传输层
:::
例如我现在拿到这样一道题,首先肯定是要取出35、D、A、B、C、D这些可以唯一确定一道题类似ID
。首先要对文档要做的就是去除空格,空格又两种,中文和英文,需要注意;其次就是需要统一括号,希望就是默认的答案就在括号里,这样可以简化寻找答案。
# 如何区分每一道题
首先要做的就是如何区分每一道题,一道题是作为一个独立的个体,必须要区分正确。每一道题的开头的都是(数字点非数字),可以以此简单的区分每一道题。代码也正是这样做的,写一个正则公式,找到所有的题号,就可以找到每道题起始的位置,则可以划分每一道题。
正则公式((\\d{1,}|[一二三])[.|、|.]{1}\\D)
,对应于上边的数字点非数字。一道题就是一个独立的单位,保存在ArrayList
中。
实现代码如下
|
|
# 在一道题中提取题目
我觉得可以以遇到A
为判断条件,但是这个A
不能是题目中的单词,不能是括号中的正确答案。
在提取题目之前,我首先提取了答案,然后删掉这段答案,要不然在搜索的时候很可能与选项混淆。然后再找到第一个选项A
的位置,在此之前的都是题目,正常在题目中是不会出现单独字母的(如果出现了,现在解决不了),所以只需要保证一个字母的前后都不是字母,就可以解决了。这是对于选择题来说的,对于判断题只需要删除掉正确答案就可以了。提取完题目就删掉题目了,只剩下选项了。
正则公式:([ABCDABCDabcd]{1}[.|、|.]{1})
代码如下:
|
|
# 在题目中提取正确答案
正确答案就在括号中,所以只需要找到括号,然后取出里面的字符就可以了。
正则公式:(\\([ABCDABCDabcd]\\))
,跟之前寻找A选项正好相反。
|
|
# 提取出每一个选项
题目提取完了,那就该提取选项了,碰到字母,并且这个字母是单独存在的。因为现在一道题中只剩下了选项,所以只需要找字母加上点或顿号等。
正则公式:([ABCDABCDabcd]{1}[.|、|.]{1})
判断题代码实现
|
|
选择题代码实现
|
|
# 实现类图
采用java语言,用正则对文本进行判断,切割。
Handle+ str: String=""+ str: String=""+ out: String=""+ out: String=""~ pattern: Pattern=null~ pattern: Pattern=null~ matcher: Matcher=null~ matcher: Matcher=null~ whole: ArrayList<String> ~ whole: ArrayList<String> + Handle(s: String)+ Handle(s: String)+ Init(): void+ Init(): void+ Divition(): void+ Divition(): void+ merge(): void+ merge(): voidPrint~ file: String=null~ file: String=null+ Print(file: String)+ Print(file: String)+ out():void+ out():voidChoice+ choice: Choice+ choice: Choice~ str: String=null~ str: String=null~ ID: String=null~ ID: String=null+ out: String=""+ out: String=""~ T: char~ T: char~ position: int~ position: int~ pattern: Pattern=null~ pattern: Pattern=null~ matcher: Matcher=null~ matcher: Matcher=null+ run(s: String): String+ run(s: String): String+ TitleNumber(s: String): String+ TitleNumber(s: String): St…+ Option(s: String): String+ Option(s: String): String+ Subject(s: String): String+ Subject(s: String): String+ Result(s: String): String+ Result(s: String): String+ onClick(): String+ onClick(): StringJudgement+ judgement: Judgement+ judgement: Judgement+ ID: String=null+ ID: String=null+ str: String=null+ str: String=null~ T: char~ T: char+ out: String=""+ out: String=""~ pattern: Pattern=null~ pattern: Pattern=null~ matcher: Matcher=null~ matcher: Matcher=null+ run(s: String): String+ run(s: String): String+ TitleNumber(s: String): String+ TitleNumber(s: String): St…+ Subject(s: String): String+ Subject(s: String): String+ Result(s: String): String+ Result(s: String): String+ onClick(): String+ onClick(): StringClassification~ T: char~ T: char~ cache: String=null~ cache: String=null+ Result(s: String): void+ Result(s: String): void+ Function(s: String): String+ Function(s: String): Stri…Connect+ file: String=null+ file: String=null~ reader: BufferedReader=null~ reader: BufferedReader=null+ Connect(file: String)+ Connect(file: String)+ con(): void+ con(): voidMainMainUseUse«interface»Mold+ run(s: String): String+ run(s: String): String+ TitleNumber(s: String): String+ TitleNumber(s: String): Str…+ Option(s: String): String+ Option(s: String): String+ Subject(s: String): String+ Subject(s: String): String+ Result(s: String): String+ Result(s: String): String+ onClick(): String+ onClick(): StringUseUseUseUseUseUseUseUseUseUseViewer does not support full SVG 1.1
# 重构后的实现类图
发现有点不符合开闭原则,代码重构后去除了classification
类,这样把自己的特征都写到自己的类中。特征在Rule()
方法
Handle+ str: String=""+ str: String=""+ out: String=""+ out: String=""~ pattern: Pattern=null~ pattern: Pattern=null~ matcher: Matcher=null~ matcher: Matcher=null~ whole: ArrayList<String> ~ whole: ArrayList<String> + Handle(s: String)+ Handle(s: String)+ Init(): void+ Init(): void+ Divition(): void+ Divition(): void+ merge(): void+ merge(): voidPrint~ file: String=null~ file: String=null+ Print(file: String)+ Print(file: String)+ out():void+ out():void+ Remove(file: String): String+ Remove(file: String): Stri…Choice+ choice: Choice+ choice: Choice~ str: String=null~ str: String=null~ ID: String=null~ ID: String=null+ out: String=""+ out: String=""~ T: char~ T: char~ position: int~ position: int~ pattern: Pattern=null~ pattern: Pattern=null~ matcher: Matcher=null~ matcher: Matcher=null+ run(s: String): String+ run(s: String): String+ TitleNumber(s: String): String+ TitleNumber(s: String): St…+ Option(s: String): String+ Option(s: String): String+ Subject(s: String): String+ Subject(s: String): String+ Result(s: String): String+ Result(s: String): String+ onClick(): String+ onClick(): String+ Rule(s: String): String+ Rule(s: String): StringJudgement+ judgement: Judgement+ judgement: Judgement+ ID: String=null+ ID: String=null+ str: String=null+ str: String=null~ T: char~ T: char+ out: String=""+ out: String=""~ pattern: Pattern=null~ pattern: Pattern=null~ matcher: Matcher=null~ matcher: Matcher=null+ run(s: String): String+ run(s: String): String+ TitleNumber(s: String): String+ TitleNumber(s: String): St…+ Subject(s: String): String+ Subject(s: String): String+ Result(s: String): String+ Result(s: String): String+ onClick(): String+ onClick(): String+ Rule(s: String): String+ Rule(s: String): StringConnect+ file: String=null+ file: String=null~ reader: BufferedReader=null~ reader: BufferedReader=null+ Connect(file: String)+ Connect(file: String)+ con(): void+ con(): voidMainMainUseUseUseUseUseUseUseUse«interface»Mold+ run(s: String): String+ run(s: String): String+ TitleNumber(s: String): String+ TitleNumber(s: String): Str…+ Option(s: String): String+ Option(s: String): String+ Subject(s: String): String+ Subject(s: String): String+ Result(s: String): String+ Result(s: String): String+ onClick(): String+ onClick(): String+ Rule(s: String): String+ Rule(s: String): StringViewer does not support full SVG 1.1
# 开发环境的搭建
暂时先在本地测试
# 总结
考虑到以后可能会有其他题型添加,就把一些功能分开写了,这样就可以很好的对程序扩充了;有的文档不仅有选择题还有判断题,先开始我是以题号作为ID
的,最后我把判断和选择放到一起的时候,就出现了ID
重复的问题,所以就用1-
代表判断题,2-
代表选择题,就可以解决不同题型ID
重复的问题了,相同题型,假如说题号一样的话,就会出问题了,在现在这个代码还解决不了这样的问题。
# 样例
# 一、判断
确定
确定
确定
确定
确定
确定
确定
确定
确定
确定
确定
确定
确定
确定
确定
# 二、多项选择题(共61小题)
确定
确定
确定
确定
确定
# 三、单选题
确定
确定
确定
确定
确定
确定
确定
确定
确定
确定
确定
确定
确定
确定
确定