编程能力强化(4)——模拟SQL语句解析

这是2010年软件大赛的样题,用到的知识点比较多,也比较实用。

 

题目:

数据库中有“表”的概念。“表”由若干“行”组成,每“行”由许多“列”组成。一般的数据库都提供了对SQL的支持。

我们可以模拟一个最简单版的SQL,只能实现简单的排序,简单的选择条件,列的显示顺序等功能。

具体如下:

(1)输入help,会输出帮助信息

(2)输入load data.txt,会输出文件中的内容

(3)输入sort weight,会根据重量排序,然后输出,也可以根据其他几个属性排序,每次指定一个

(4)输入select *,显示所有的数据

(5)输入select name,显示某一列,如果要显示多列,多列之间使用空格隔开

(6)输入select * where price>50,条件只能使用大于或者小于,单个条件不用空格,多个条件之间使用空格隔开

(7)输入exit,程序退出

自己看看能不能做出来,如果做不出来,看看后面的参考答案。

数据文件(data.txt)内容如下:

名称 长度 重量 威力 价格
A 25.1 12.3 24.6 105.3
B 180.5 11.6 41.2 36.5
C 103.6 33.1 28.4 78
D 21.5 18.6 17.6 38.5
E 33.6 28.5 11.9 27.0
F 31.6 19.8 23.5 36.3
G 88.3 17.9 16.4 22.9

 

下面是参考答案:


import java.io.*; import java.util.*; // 代表每行数据 class MyRow { private String name; // 名字 private double length; // 长度 private double weight; // 重量 private double power; // 威力 private double price; // 价格 public MyRow(String x) { String[] ss = x.split("/t"); name = ss[0].trim(); length = Double.parseDouble(ss[1]); weight = Double.parseDouble(ss[2]); power = Double.parseDouble(ss[3]); price = Double.parseDouble(ss[4]); } public String toString() { return name + "/t" + length + "/t" + weight + "/t" + power + "/t" + price; } public String getName() { return name; } public double getLength() { return length; } public double getWeight() { return weight; } public double getPower() { return power; } public double getPrice() { return price; } } // 代表所有数据 class MyData { // 内部类,“裁判”类,用于裁决Vector中的对象的比较大小问题 class CaiPan implements Comparator { private int type; public CaiPan(int type) { this.type = type; } public int compare(Object o1, Object o2) { if(!(o1 instanceof MyRow)) return 0; if(!(o2 instanceof MyRow)) return 0; MyRow r1 = (MyRow)o1; MyRow r2 = (MyRow)o2; switch(type){ case 1: return Double.compare(r1.getLength(),r2.getLength()); case 2: return Double.compare(r1.getWeight(),r2.getWeight()); case 3: return Double.compare(r1.getPower(),r2.getPower()); case 4: return Double.compare(r1.getPrice(),r2.getPrice()); default: return 0; } } } private Vector _v = new Vector(); public void show() { System.out.println("................................"); System.out.println("名称/t长度/t重量/t威力/t价格"); for(int i=0; i<_v.size(); i++){ System.out.println(_v.get(i)); } System.out.println("................................"); } public boolean load(String x) { try{ BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(x))); _v.clear(); br.readLine(); // 第一行不要 for(;;){ String s = br.readLine(); if(s==null) break; MyRow row = new MyRow(s); _v.add(row); } show(); return true; } catch(Exception e){ //e.printStackTrace(); return false; } } public boolean sort(String x) { if(x.equals("length")){ Collections.sort(_v, new CaiPan(1)); show(); return true; } if(x.equals("weight")){ Collections.sort(_v, new CaiPan(2)); show(); return true; } if(x.equals("power")){ Collections.sort(_v, new CaiPan(3)); show(); return true; } if(x.equals("price")){ Collections.sort(_v, new CaiPan(4)); show(); return true; } return false; } // 初步解析命令 public boolean select(String x) { Vector sort = new Vector(); // 显示的字段 Vector where = new Vector(); // 过滤的条件语句 String[] ss = x.split(" "); Vector t = sort; for(int i=0; i<ss.length; i++){ if(ss[i].length()==0) continue; // 防止多个空格 if(ss[i].equals("where")){ t = where; continue; } t.add(ss[i]); } if(sort.size()==0) return false; // 字段必须指定 if(sort.size()>5) return false; // 字段太多 return select(sort, where); } // 执行select任务 public boolean select(List sort, List where) { try{ System.out.println("................................"); //输出标题 for(int k=0; k<sort.size(); k++){ if(sort.get(k).equals("name")) System.out.print("姓名/t"); else if(sort.get(k).equals("length")) System.out.print("长度/t"); else if(sort.get(k).equals("weight")) System.out.print("重量/t"); else if(sort.get(k).equals("power")) System.out.print("威力/t"); else if(sort.get(k).equals("price")) System.out.print("价格/t"); else if(sort.get(k).equals("*")) System.out.print("名称/t长度/t重量/t威力/t价格/t"); else return false; }// 枚举sort System.out.println(""); //输出内容 for(int i=0; i<_v.size(); i++){ MyRow row = (MyRow)_v.get(i); if(checkWhere(row, where)){ for(int k=0; k<sort.size(); k++){ if(sort.get(k).equals("name")) System.out.print(row.getName() + "/t"); else if(sort.get(k).equals("length")) System.out.print(row.getLength() + "/t"); else if(sort.get(k).equals("weight")) System.out.print(row.getLength() + "/t"); else if(sort.get(k).equals("power")) System.out.print(row.getLength() + "/t"); else if(sort.get(k).equals("price")) System.out.print(row.getLength() + "/t"); else if(sort.get(k).equals("*")) System.out.print(row + "/t"); else return false; }// 枚举sort System.out.println(""); }//检查过滤条件 }//对每个行处理 System.out.println("................................"); return true; } catch(Exception e){ //e.printStackTrace(); return false; } } // 返回true 则该行记录显示,返回false,则不显示 public boolean checkWhere(MyRow row, List where) throws Exception { boolean op=true; // true: 表示比较符号为 > , 否则为 < String field = ""; // 过滤条件的字段 String value = ""; // 过滤值 // 对每一个条件处理 for(int i=0; i<where.size(); i++){ String s = (String)where.get(i); String[] ss = s.split(">"); if(ss.length==2){ field = ss[0]; op = true; value = ss[1]; } else{ ss = s.split("<"); if(ss.length==2){ field = ss[0]; op = false; value = ss[1]; } else return false; // 既没有"<"也没有">"的情况 } double d_value = Double.parseDouble(value); if(field.equals("length")){ if(op){ if(row.getLength() <= d_value) return false; } else{ if(row.getLength() >= d_value) return false; } } else if(field.equals("weight")){ if(op){ if(row.getWeight() <= d_value) return false; } else{ if(row.getWeight() >= d_value) return false; } } else if(field.equals("power")){ if(op){ if(row.getPower() <= d_value) return false; } else{ if(row.getPower() >= d_value) return false; } } else if(field.equals("price")){ if(op){ if(row.getPrice() <= d_value) return false; } else{ if(row.getPrice() >= d_value) return false; } } else throw new Exception("valid field name!"); // 无法识别的 field,则算错表达式错 } return true; } } // 负责解释用户输入的命令 class MyCommand { private MyData data; public MyCommand(MyData x) { data = x; } public boolean execute(String x) { int d = x.indexOf(" "); // 找第一个空格的位置 if(d<0) return false; String x1 = x.substring(0,d); String x2 = x.substring(d+1); if(x1.equals("load")){ if(!data.load(x2.trim())) System.out.println("装入文件出错!"); return true; } if(x1.equals("sort")) return data.sort(x2.trim()); if(x1.equals("select")) return data.select(x2); return false; } } public class My { private static BufferedReader br_keyboard; static { br_keyboard = new BufferedReader(new InputStreamReader(System.in)); // 将它用于从键盘读入 } public static void main(String[] args) throws Exception { MyData data = new MyData(); MyCommand cmd = new MyCommand(data); // cmd 服务于 data for(;;){ System.out.print("请输入命令(输入help显示帮助信息):"); String s = br_keyboard.readLine(); if(s.equals("exit")) break; if(s.equals("help")){ System.out.println("----------------------------"); System.out.println("load data.txt"); System.out.println("从当前目录装入文件data.txt,并显示"); System.out.println("sort weight"); System.out.println("按“重量”排序,并显示"); System.out.println("类似地,还可以是 sort length, sort price,sort power等"); System.out.println("select weight length"); System.out.println("只显示 重量,长度两列"); System.out.println("select weight length where price > 50"); System.out.println("只显示 重量,长度两列, 只包含价格 > 50 的行"); System.out.println("select * where price>50 length<30"); System.out.println("显示所有列, 只包含价格>50 且 长度<30 的行"); System.out.println("其它的组合,从上边类推"); System.out.println("exit"); System.out.println("退出程序"); System.out.println("----------------------------"); continue; } if(!cmd.execute(s)){ System.out.println("无效的命令"); } } } }

你可能感兴趣的:(sql,编程,exception,vector,String,keyboard)