摘要
这算是软件创新这笨比课程的第一个项目,也算是我自己一个人用java写的第一个东西(?).虽然时间总计没写多久,但还是再次让我体会到编程这东西就是得一边做,一边学。
题目要求以及大致编写思路
题目的目的是做一个覆盖小学,初中,高中的数学计算题出题器,并能够做到不重复和文件保存。具体要求在后面分析代码时给出。
实现起来也不是很难,先通过while循环进行不断检测输入,登录通过以后,再进行相关操作检测,然后跳转到对应操作语句。代码主体为一个main主类,然后写了4个函数接口:file,mysql,question和user。
逻辑流程
登录
题目要求
也就是实现一个不同用户登录,并识别出其不同身份
具体代码及分析(user接口)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| public static void main(String[] args){ int school = -1;
while(true) { Scanner sc = new Scanner(System.in); String name = sc.next(); String pass = sc.next();
if(school==-1) { school = user.login(name, pass);
if(school!=-1) { question.promot_choose(school); school=user.loginned(school,name); } } } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| static int login(String user, String pass) {
String[] name={"张三1","张三2","张三3","李四1","李四2","李四3","王五1","王五2","王五3"};
for(int i=0;i<9;i++){ if(user.equals(name[i]) && pass.equals("123")){ return i/3; } } System.out.println("请输入正确的用户名、密码"); return -1; }
|
其实java嘛,应该以类/对象为主体,但就这个题而言,我个人觉得好像没啥必要(?),所以我全部都是用的接口实现方法,除主类外一个没有。
然后就登录而言,在主类里利用一个while循环实现重复的登录判定.利用一个school变量标记用户对应的学校(这些就应该搞个用户类)。然后通过user接口里的login方法,进行登录验证,并将获得的学校传给school,然后传入user接口的loginned方法进行登录后操作。
然后对于login方法,利用数组保存了9个用户名,并依据学校将其排序,小学为前三个,初中为中间三个,高中为后面三个。密码则都是123,就不需要另外储存。然后进行字符串匹配,未成功返回-1,说明登录失败,成功则返回用户名的数组对应位置以此标记用户对应学校。
登录后命令判断
具体要求
具体来说就是在登录后根据输入字符串实现对应操作。
具体代码及分析(user接口)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| static int loginned(int school,String user){ mysql.create(user); Scanner sc = new Scanner(System.in); while(school!=-1) { question.promot_generete(school); String execute = sc.next();
try(){ int num = Integer.parseInt(execute); if (num >= 10 && num <= 30) {question.generat()} else if (num == -1) {school = -1;} else {System.out.println("题目数量超出范围,请重新输入");} }
catch{ if(execute.length()>=4) { String inter=execute.substring(0,3); if(inter.equals("切换为")){ if (execute.equals("切换为小学")) {school = 0;} else if (execute.equals("切换为初中")) {school = 1;} else if (execute.equals("切换为高中")) {school = 2;} else System.out.println("请输入小学、初中和高中三个选项中的一个"); }else {···} }else{···}
} return -1; } }
|
成功登录后,就是对应操作。首先便是一个mysql的表单创建,然后输入对应操作语句。
首先利用try-catch语句分析该字符串是否能够转为int数。若能成功转换则说明是出题语句或者退出登录语句,然后判读其数值。
若为10-30,则通过question接口中的generate函数执行出题操作。
若为-1,则将school变量置为-1执行退出操作,其他的则输出提示语句提示输入数字偏离对应范围,需要重新输入。
若无法转换,此时转换函数就会报错,然后执行catch内语句。
先判断是否为转换语句,若是则根据对应改变更改school值即可,若不是,直接输出提示“输入非法”即可。
相关接口及函数
user接口里的函数基本在逻辑流程里解释过了,这里就主要解释mysql,file和question接口及其函数。
mysql.create
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| static void create(String user){ Connection connection = null; Statement statement = null; try { ······ statement = connection.createStatement(); String sql = "create table " + user + " ( question varchar(20) primary key )"; statement.executeUpdate(sql); }catch (Exception e) { e.printStackTrace(); } finally { ··· } }
|
本函数传入一个user字符串,然后根据此字符串创建对应名称的题目表,表的主键为题目,利用主键不可重复的规则,达到题目不重复的目的。
mysql.save
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| static boolean save(String question, String user){ Connection connection = null; Statement statement = null; boolean flag=true;
try { ···
statement = connection.createStatement(); String sql = "insert into "+ user+ " value (\""+question+"\")"; int result = statement.executeUpdate(sql);
if (result > 0) { System.out.println("题目未重复"); flag=true; } else { System.out.println("题目已重复"); flag=false; } } catch (Exception e) { e.printStackTrace(); } finally { ··· } return flag; }
|
save函数主要目的为生成题目后将其保存到数据库中。函数需要传入两个字符串,一个是题目字符串,一个是用户名字符串。
当调用函数后,根据用户名将题目字符串插入到对应表,如果能够成功插入,则说明没有重复,statement.executeUpdate函数就会返回一个大于0的int值,表示受到影响的表内行数,此时就可以将flag置为true,save函数就返回true值,表示题目没有重复,成功保存到数据库中;反之函数就会返回0表示没有行受到影响也就是没有成功插入。此时将flag置为false,表示题目重复。
file.generate
题目要求
具体代码及分析
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| static File generate(String user){ Date date = new Date(); SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss"); String time=formatter.format(date); System.out.println(time);
String Path = "···" + user; File folder = new File(Path); if (!folder.exists()) folder.mkdirs();
File x = null; try { x = new File(Path,time+".txt"); if (x.createNewFile()) { System.out.println("文件已生成: " + x.getName()); } } catch (IOException e) { e.printStackTrace(); }
return x; }
|
generate函数目的为生成文件。需要传入一个用户名字符串,然后传回一个对应文件。
函数本体较为简单,通过formatter.format函数获得当前时间作为文件名,然后保存到对应的文件夹下。然后将生成的文件传传出去。
file.save
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| static void save(Vector<String> v,File x){ try { FileWriter myWriter = new FileWriter(x);
for(int i=1;i<=v.size();i++){ String num=""; num=num+i+'.'; myWriter.write(num+v.get(i-1)+"\n"); myWriter.write("\n"); }
myWriter.close(); System.out.println("试卷已保存"); } catch (IOException e) { e.printStackTrace(); } }
|
save函数目的为将题目保存到对应文件内。需要传入一个保存题目的vector以及需要保存到的文件。
主体操作为通过一个for循环,将vector中的题目字符串保存到文件内。
question接口中有三个类似的promote函数,主要目的在于不同情况下的提示语句,比较简单就不再赘述。
question.generate
题目要求
具体代码及分析
1
| static void generate(int n,int school,String user){}
|
generate函数目的在于根据输入生成对应题目并利用函数保存到文件中。
需要传入题目数量n,学校类型school以及用户名user
函数内分为三个部分,一个if语句根据school生成三种类型题目,鉴于其基本相似,这里就拿高中题目部分函数进行解释。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
| String [] primary={"+","-","*","/"}; while (n!=0){ StringBuffer s = new StringBuffer(); String inter="";
int use=r.nextInt(6); int size=0; int before=0; if(use<2) use=2;
int flag=r.nextInt(5); if(flag>0){ if(use>2){ size=r.nextInt(use-1); if(size<2) size=2; before=r.nextInt(use-size); } else flag=0; } if(before==0&&flag!=0) s.append('(');
int num=r.nextInt(99)+1; s.append(num); for(int j=2;j<=use;j++){ int use_index=r.nextInt(3); s.append(primary[use_index]); if(j-1==before&&flag!=0) s.append('('); num=r.nextInt(99)+1; s.append(num); if(j==(before+size)) s.append(')'); }
s.append('='); inter=s.toString();
if(mysql.save(inter,user)==true) { n-=1; v.add(inter); } } for (int i=0;i<v.size();i++){ System.out.println(v.get(i)); } File x=file.generate(user); file.save(v,x);
|
小学部分先利用随机数生成题目需要的操作数以及操作符号和是否需要括号,然后根据括号位置决定是否先在题目字符串前方添加左括号,然后将第一个操作数添加到题目字符串左方。
然后进行将题目数量n是否为0作为判断条件的while循环,每次生成操作数以及操作符号添加到题目字符串末尾,并在添加操作数和操作符号之间时判断是否需要添加括号。
生成整个题目后,利用mysql.save函数判断是否重复题目,如果没有重复则n-1,继续;如果重复则n不变。
最后将题目通过file.save和file.generate函数保存到文件里。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| int junior=r.nextInt(use)+1; if(junior==1) { if(junior/2==0) s.append('√'); }
for(int j=2;j<=use;j++){ if(j==junior) { if(junior/2!=0) s.append('²'); } ··· if(j==junior) { if(junior/2==0) s.append('√'); } ··· }
|
初中部分增加要求为开根号和开方,先通过随机数决定符号位置,然后根据位置奇偶决定在操作数上添加开方或者开根。然后根据符号类型,判读添加在操作数前方或者后方。
1 2 3 4 5 6 7 8 9 10 11 12
| int senior=r.nextInt(use)+1; int type=r.nextInt(3); String [] tri={"sin","cos","tan"}; if(senior==1) { s.append(tri[type]); } for(int j=2;j<=use;j++){ ··· if (j==senior) s.append(tri[type]); ··· }
|
高中部分增加三角函数,和初中部分一样,通过随机函数生成符号位置,然后根据位置决定符号类型,然后在对应位置直接添加到操作数前方即可。
总结
这个个人项目其实也不是很难,麻烦在于好多东西自己都没有接触过,比如数据库连接,java文件生成之类的。但好在网上相关教程还是比较多的,学习学习也就会了。希望自己能够多多学习,早日走上程序猿的岗位,然后回家开摆。