课堂派题库格式转换程序

一、背景

这个学期开设的Java程序设计课程,需要用课堂派来签到和平常练习,老师苦于课堂派后台的课堂测试需要人工填入题目,好在课堂派运行符合格式的题目直接从word文档中导入,于是让我们来写一个小程序来实现这个格式转换。老师用的源题库是有特殊格式的,这样我们就可以通过一些特殊的标记来实现对源题库的读取,我最开始使用C++来实现的,后来补充的Java的版本。该程序主要是对string的操作,二者之中有许多相同的函数方法,但具体的写法却有所不同,同时Java的限制数组越界、不能更改String的一些特点,也让有些头疼,Java写的还是太少了!

二、格式要求

源题库样例:

目标题库格式:

具体要求:

1.第一行为题干,中间不要换号(课堂派后台只能识别一行题干),可以加题号,也可以不加题号,编写程序时可以通过一个选项开关让使用者决定是否需要保留题号。

2.答案要写在题目开头或者结尾,用括号括起来,大小写括号均可。在题干末尾添加本题的类型和分数,用大括号括起来。题目的类型需要通过答案的个数自己判断,题目的分数需要程序的使用者来输入。

3.题干之后是选项行,选项中不要空行,一个选项是单独的一行,选项字母需要英文大写。

4.每一道题与下一道题目之间需要空三行作为标志。

5.源题库中的有些题目可能会有解析,这里解析不需要提取处理。

6.源题库中出现的Chapter和Section的内容可以输出到控制台,目标文件中不要出现。

三、C++源代码

#include<fstream>  //ifstream
#include<iostream>
#include<string>
#include<map>
using namespace std;

struct subject
{
    int id;//题目序号
    int type;//题目类型
    string stem;//题干内容
    map<string,string>options;//选项与答案的map键值对
    int num;//选项个数
    string score;//题目分数
    string key;//答案
    string analysis;//有些题目需要解析
};

int main()
{
    string s,temp;
    string path;
    ofstream outf;
    ifstream inf;
    int cnt=0;//记录题目的个数
    int num1=0;//单选题个数
    int num2=0;//多选题个数
    int flag=0;//默认保留原题号
    char select;//是否保留题号的选项
    string score;
    struct subject sbj[100];
    string::size_type pos(0);
    cout << "请输入需要转换的文本文件路径:(例:C://in.txt)" <<endl;
    cin >> path;
    if(inf)
    {
        cout << "打开文本文件成功!" <<endl;
    }
    else
    {
        cout << "打开文本文件失败!" <<endl;
    }
    inf.open(path);//打开文本文件I://chapter1.txt
    cout << "请输入转换输出的文本文件路径:(例:C://out.txt)" <<endl;
    cin >> path;
    outf.open(path);//需要写入的文本文件

    //目标文本的读取
    cout << "转换完成后的题目是否保留原题号?(y/n)" <<endl;
    while(1)
    {
        cin >> select;
        if(select==‘y‘)
        {
            flag=1;
            break;
        }
        else if(select==‘n‘)
        {
            flag=0;
            break;
        }
        else
        {
            cout << "只能输入y或n,请重新输入!" <<endl;
        }
    }
    while (getline(inf, s))
    {
        if(s.substr(0,7)=="Chapter")
        {
            cout<<s<<endl;
        }
        else if(s.substr(0,7)=="Section")
        {
            cout<<s<<endl;
        }
        //提取选项信息
        else if(s.substr(0,1)>="0"&&s.substr(0,1)<="9") //提取题干信息
        {
            cnt++;
            if(flag==1)
            {
                pos =s.find(".");
                temp=s.substr(pos+1,s.length()-pos);
                sbj[cnt].stem = temp;//保存题干内容
            }
            else if(flag==0)
            {
                sbj[cnt].stem = s;
            }
            sbj[cnt].id = cnt;
            sbj[cnt].num = 0;
            while (getline(inf, s))
            {
                if(s.substr(0,4)=="Key:")//提取答案信息
                {
                    temp=s.substr(4,s.length()-4);
                    pos =temp.find(" ");
                    sbj[cnt].key=temp.substr(0,pos);
                    cout<<sbj[cnt].key<<endl;
                    for(int i=0; i<sbj[cnt].key.length(); i++)//答案替换为大写字母
                    {
                        if(sbj[cnt].key[i]>=‘a‘&&sbj[cnt].key[i]<=‘z‘)
                        {
                            sbj[cnt].key[i]=sbj[cnt].key[i]-32;
                        }
                    }
                    pos=sbj[cnt].key.length()-1;
                    if(temp.length()>sbj[cnt].key.length())
                    {
                        sbj[cnt].analysis=temp.substr(pos,temp.length()-pos);
                    }

                }
                else if((s[0]>=‘a‘&&s[0]<=‘z‘)||(s[0]>=‘A‘&&s[0]<=‘Z‘))//提取选项信息
                {
                    if(s[0]>=‘a‘&&s[0]<=‘z‘)//选项是小写字母,转为大写字母
                    {
                        s[0]=s[0]-32;
                    }
                    sbj[cnt].options.insert(pair<string,string>(s.substr(0,1),s.substr(2,s.length()-2)));//保存选项
                    sbj[cnt].num++;
                }
                else if(s.substr(0,1)=="#")//分隔符,下一道题
                {
                    break;
                }
            }
            cout<<"第"<<cnt<<"道题识别成功!!"<<endl;
            cout<<sbj[cnt].stem<<endl;
            cout<<"答案:"<<sbj[cnt].key<<endl<<endl;
        }
    }
    cout<<"读取文本文件成功!"<<endl;

    //目标文本的处理
    for(int i=1; i<=cnt; i++)
    {
        pos=0;
        sbj[i].stem.insert(pos,"( "+sbj[i].key+" )");//答案的插入
        if(sbj[i].key.length()==1)
        {
            sbj[i].stem=sbj[i].stem+"[单选题]";
            num1++;
        }
        else if(sbj[i].key.length()>1)
        {
            sbj[i].stem=sbj[i].stem+"[多选题]";
            num2++;
        }
    }
    cout<<"检测到单选题"<<num1<<"道,多选题"<<num2<<"道"<<endl;
    cout<<"请输入题目的分数:[1~100]"<<endl;
    cin>>score;

    for(int i=1; i<=cnt; i++)
    {
        sbj[i].score=score;
        sbj[i].stem=sbj[i].stem+"["+score+"分]";
    }
    for(int i=1; i<=cnt; i++)//文本写入
    {
        outf<<sbj[i].stem<< ‘\n‘;//写入题干
        map<string,string>::iterator iter;
        for(iter = sbj[i].options.begin(); iter != sbj[i].options.end(); iter++)
        {
            outf<<iter->first<<"."<<iter->second<< ‘\n‘;//写入选项
        }
        outf<< ‘\n‘<< ‘\n‘<< ‘\n‘;
    }
    inf.close();
    outf.close();
    cout<<"文本转换完成!"<<endl;
    return 0;
}

四、Java源代码

import java.io.*;
import java.util.*;
//import java.util.Map;
//import java.util.HashMap;
class subject
{
     int id;//题目序号
     int type;//题目类型
     int num;//选项个数
     String stem;//题干内容
     int score;//题目分数
     String key;//答案
     String analysis;//有些题目需要解析
     Map<String,String>options=new LinkedHashMap<String,String>();//map映射,LinkedHashSet正序输出
     public subject()//构造函数
     {
         id = 0;
         type = 1;
         num = 0;
         score =1;
         stem = null;
         key = null;
         analysis = null;
     }
}

public class Main {

    public static void main(String args[]) {
        int cnt = 0;
        int num1=0;//单选题个数
        int num2=0;//多选题个数
        int flag=0;//默认保留原题号
        char select;//是否保留题号的选项
        int score;
        String pathname_in;
        String pathname_out;
        Scanner in=new Scanner(System.in);
        subject [] sbj;
        sbj = new subject[1000];
        for(int i=0;i<sbj.length;i++){
            sbj[i]= new subject();
        }
        //String pathname = "I://chapter1.txt";
        System.out.println("请输入需要转换的文本文件路径:(例:C://in.txt)");
        pathname_in =in.nextLine();
        System.out.println("请输入转换输出的文本文件路径:(例:C://out.txt)");
        pathname_out =in.nextLine();
        System.out.println("转换完成后的题目是否保留原题号?(y/n)");
        while(true){
            select =in.nextLine().charAt(0);
            if(select==‘y‘){
                flag=1;
                break;
            }
            else if(select==‘n‘){
                flag=0;
                break;
            }
            else
            {
                System.out.println("只能输入y或n,请重新输入!");
            }
        }

        try (FileReader reader = new FileReader(pathname_in);
             BufferedReader br = new BufferedReader(reader) // 建立一个对象,它把文件内容转成计算机能读懂的语言
        ) {
            String line;
            //网友推荐更加简洁的写法
            while ((line = br.readLine()) != null) {
                if(line.length()==0){
                    continue;
                }
                else if(line.substring(0,7).equals("Chapter")){
                    System.out.println(line);
                }
                else if(line.substring(0,7).equals("Section")){
                    System.out.println(line);
                }
                else if((line.charAt(0)>=‘0‘)&&(line.charAt(0)<=‘9‘)){
                    cnt++;
                    String temp;
                    int pos;
                    if(flag==1){
                        pos =line.indexOf(‘.‘);
                        temp=line.substring(pos+1,line.length());
                        sbj[cnt].stem = temp;//保存题干内容
                    }
                    else if(flag==0){
                        sbj[cnt].stem = line;
                    }
                    sbj[cnt].id=cnt;
                    sbj[cnt].num=0;
                    while ((line = br.readLine()) != null) {
                        System.out.println(line);
                        if(line.length()==0){
                            continue;
                        }
                        else if(line.charAt(0)==‘#‘){
                            break;//分隔符
                        }
                        else if(line.length()<=4)
                        {
                            continue;
                        }
                        else if(line.substring(0,4).equals("Key:")){
                            temp = line.substring(4,line.length());//答案和解析的内容
                            pos = temp.indexOf(‘ ‘);
                            if(pos==-1){//没有解析说明
                                sbj[cnt].key= temp.toUpperCase();//写回
                                System.out.println(sbj[cnt].key);
                            }
                            else {
                                sbj[cnt].key=temp.substring(0,pos);//答案选项
                                sbj[cnt].key=sbj[cnt].key.toUpperCase();//写回
                                pos=sbj[cnt].key.length()-1;
                                if(temp.length()>sbj[cnt].key.length()){
                                    sbj[cnt].analysis=temp.substring(pos,temp.length()-pos);
                                }
                            }
                        }
                        else if(((line.charAt(0)>=‘a‘&&line.charAt(0)<=‘z‘)||(line.charAt(0)>=‘A‘&&line.charAt(0)<=‘Z‘))&&(line.charAt(1)==‘.‘)){
                            String opt = line.substring(0,2);//选项
                            String detail = line.substring(2,line.length());//选项描述
                            sbj[cnt].options.put(opt,detail);
                            sbj[cnt].num++;
                        }
                        else
                        {
                            continue;
                        }
                    }
                    System.out.println("第"+cnt+"道题识别成功!!");
                    System.out.println(sbj[cnt].stem);
                    System.out.println("答案:"+sbj[cnt].key+"\n");
                }
                else
                {
                    continue;
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        System.out.println("读取文本文件成功!");
        for(int i=1;i<=cnt;i++){
            sbj[i].stem="( "+sbj[i].key+" )"+sbj[i].stem;
            if(sbj[i].key.length()==1){
                sbj[i].stem=sbj[i].stem+"[单选题]";
                num1++;
            }
            else if(sbj[i].key.length()>1){
                sbj[i].stem=sbj[i].stem+"[多选题]";
                num2++;
            }

        }
        System.out.println("检测到单选题"+num1+"道,多选题"+num2+"道");
        System.out.println("请输入题目的分数:[1~100]");
        score =in.nextInt();
        for(int i=1; i<=cnt; i++){
            sbj[i].score=score;
            sbj[i].stem=sbj[i].stem+"["+score+"分]";
        }
        try {
            File writeName = new File(pathname_out); // 相对路径,如果没有则要建立一个新的output.txt文件
            writeName.createNewFile(); // 创建新文件,有同名的文件的话直接覆盖
            try (FileWriter writer = new FileWriter(writeName);
                 BufferedWriter out = new BufferedWriter(writer)
            ) {
                for(int i=1; i<=cnt; i++){//文本写入
                    out.write(sbj[i].stem+"\r\n");
                    Iterator<Map.Entry<String, String>> entries = sbj[i].options.entrySet().iterator();
                    while(entries.hasNext()){
                        Map.Entry<String, String> entry = entries.next();
                        out.write(entry.getKey()+entry.getValue()+"\r\n");
                    }
                    out.write("\r\n"+"\r\n"+"\r\n");
                }
                out.flush(); // 把缓存区内容压入文件
            }
        } catch (IOException e){
            e.printStackTrace();
        }
        System.out.println("文本转换完成!");
    }
}

五、遇到的一些问题

原文地址:https://www.cnblogs.com/wkfvawl/p/11515110.html

时间: 2024-10-07 12:52:07

课堂派题库格式转换程序的相关文章

051 题库

序号 OCP 051题库 1 :  OCP-1Z0-051 第1题 CTAS语句建表注意事项 2 :  OCP-1Z0-051 第2题 视图的WITH CHECK OPTION选项 3 :  OCP-1Z0-051 第3题 转义字符 4 :  OCP-1Z0-051 第4题 单行函数 5 :  OCP-1Z0-051 第5题 to_char的数字的格式 6 :  OCP-1Z0-051 第6题 case when和decode的用法 7 :  OCP-1Z0-051 第7题 ON和USING子句

一站到底题库

一站到底题库 bella 来自: bella(要有强大的内心) 2012-11-09 13:10:12 文学常识 1. 第一位女诗人是:蔡琰(文姬) 2. 第一部纪传体通史:史记 3. 第一部词典是:尔雅 4. 第一部大百科全书是:永乐大典 5. 第一部诗歌总集是:诗经 6. 第一部文选:昭明文选 7. 第一部字典:说文解字 8. 第一部神话集:山海经 9. 第一部文言志人小说集:世说新语 10. 第一部文言志怪小说集:搜神记 11. 第一部语录体著作:论语 12. 第一部编年体史书是:春秋 1

[黑科技] 使用Word和Excel自制题库自判断答题系统

这篇文章是LZY老师告诉我的一个方法,如果你需要做题库,并且喜欢电子答题的方法,这篇文章或许会对你有所帮助.反正李老师班级的平均成绩高出其他班级的14分,这就是它的好处,希望这篇文章对我今后的学生有所帮助吧!        注意:这篇文章涉及到Word特殊字符.通配符.Excel设置等常见问题.如果文章存在不足或错误的地方,还请海涵~        运行结果如下图所示,正确答案第一列,模拟做题的时候学生将它藏着,然后在E列进行答题,D列是在线判断系统,反复训练从而提升学生的考试分数.哈哈~哎,确

国学题库整理

1.六艺:一曰五礼,二曰六乐,三曰五射,四曰五御,五曰六书,六曰九数. 其中,“御”不仅指驾驶,还指驾驭下属乃至国家的知识. 2.竹林七贤:嵇康.阮籍.山涛.向秀.刘伶.王戎及阮咸七人. 3.乡试录取者称为“举人”,会试录取者称为“贡生”,殿试录取者称为“进士”. 4.乡试第一名称“解元”.明.清科举分为三甲.头甲三人,即状元.榜眼和探花,赐进士及第:二甲第一名,称“传胪”(起初,三甲头名亦称传胪,后仅限于二甲头名),中二甲赐进士出身:三甲人数最多,赐同进士出身. 5.襁褓:未满周岁的婴儿 孩提

[NOI题库]1.3编程基础之算术表达式与顺序执行 题解(一)

01 A+B问题 经典的A+B Problem——各大题库上的首题.读入$a,b$,输出$a+b$. #include <iostream> using namespace std; int main() { int a,b; cin>>a>>b; cout<<a+b<<endl; return 0; } 01.cpp 02 计算(a+b)*c的值 读入$a,b,c$,输出$c(a+b)$. #include <iostream> u

OnlineJudge 离线题库采集

过段时间要把以前的OJ换掉,我负责VirtualJudge的部分.需要用C与PHP写一个Linux下的VJudge. 在此之前,将以前写给自己学弟学妹用的OJ离线题库的采集程序改进了一下.支持国内一些知名高校的OJ,为之后VJudge的开发练练手,熟悉下各个OJ的结构,免去以后再在LINUX上进行一些繁琐的测试. 题目的采集没有使用任何OJ的API,直接采取从HTML页面采集数据并处理的方式.下载HTTP文件使用的是WinINet函数集,用起来比CURL还方便.正则表达式使用的ATL库里的reg

我是如何用单机实现亿级规模题库去重的?

背景 最近工作中遇到了一个问题:如何对大规模题库去重?公司经过多年的积累,有着近亿道题目的题库,但是由于题目来源不一导致题库中有很多重复的题目,这些重复的题目在检索时,除了增加搜索引擎的计算量外,并不会提高准确率.此外由于题目过多,搜索引擎往往采取了截断策略,只对一部分题目进行计算,这导致了某些正确的题目反而得不到计算,拍搜准确率甚至不增反降.所以对于一个搜索引擎来说,虽然初期增加题目数量往往可以大幅提高拍搜准确率,但是当题目量大到一定程度时,反而会由于计算量跟不上导致准确率下降.如何尽可能的去

菁优网(jyeoo.com)题库数据(题目数据超102万组题数据超2100万含图片)

本文原创作者:数据超市(http://www.data-shop.net) 本文原始链接:http://www.data-shop.net/2016/03/jyeoo_com_20160321/ 数据说明:菁优网(http://www.jyeoo.com/)的题库数据.是按网站上的学科.教材组题来采集的,数据总数21,125,850条.数据包括以下学科:小学 – 数学初中 – 数学,物理,化学,生物,地理高中 – 数学,物理,化学,生物 特别说明:本次采集内容包括菁优网上初中.高中.小学的所有的

猿题库 iOS 客户端架构设计(原文地址:http://gracelancy.com/blog/2016/01/06/ape-ios-arch-design/)

猿题库 iOS 客户端架构设计 序 猿题库是一个拥有数千万用户的创业公司,从2013年题库项目起步到2015年,团队保持了极高的生产效率,使我们的产品完成了五个大版本和数十个小版本的高速迭代.在如此快速的开发过程中,如何保证代码的质量,降低后期维护的成本,以及为项目越来越快的版本迭代速度提供支持,成为了我们关注的重要问题.这篇文章将阐明我们在猿题库 iOS 客户端的架构设计. MVC MVC,Model-View-Controller,我们从这个古老而经典的设计模式入手.采用 MVC 这个架构的