编程能力强化(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

 

下面是参考答案:


[java]  view plain copy
  1. import java.io.*;  
  2. import java.util.*;  
  3.   
  4.   
  5. // 代表每行数据  
  6. class MyRow  
  7. {  
  8.     private String name;    // 名字  
  9.     private double length;  // 长度  
  10.     private double weight;  // 重量  
  11.     private double power;   // 威力  
  12.     private double price;   // 价格  
  13.       
  14.     public MyRow(String x)  
  15.     {  
  16.         String[] ss = x.split("/t");  
  17.         name = ss[0].trim();  
  18.         length = Double.parseDouble(ss[1]);  
  19.         weight = Double.parseDouble(ss[2]);  
  20.         power = Double.parseDouble(ss[3]);  
  21.         price = Double.parseDouble(ss[4]);  
  22.     }  
  23.       
  24.     public String toString()  
  25.     {  
  26.         return name + "/t" + length + "/t" + weight + "/t" + power + "/t" + price;  
  27.     }  
  28.       
  29.     public String getName() { return name; }  
  30.     public double getLength() { return length; }  
  31.     public double getWeight() { return weight; }  
  32.     public double getPower() { return power; }  
  33.     public double getPrice() { return price; }  
  34. }  
  35.   
  36. // 代表所有数据  
  37. class MyData  
  38. {  
  39.     // 内部类,“裁判”类,用于裁决Vector中的对象的比较大小问题    
  40.     class CaiPan implements Comparator  
  41.     {  
  42.         private int type;  
  43.           
  44.         public CaiPan(int type)  
  45.         {  
  46.             this.type = type;  
  47.         }  
  48.           
  49.         public int compare(Object o1, Object o2)      
  50.         {  
  51.             if(!(o1 instanceof MyRow)) return 0;  
  52.             if(!(o2 instanceof MyRow)) return 0;  
  53.               
  54.             MyRow r1 = (MyRow)o1;  
  55.             MyRow r2 = (MyRow)o2;  
  56.               
  57.             switch(type){  
  58.             case 1:  
  59.                 return Double.compare(r1.getLength(),r2.getLength());  
  60.             case 2:  
  61.                 return Double.compare(r1.getWeight(),r2.getWeight());  
  62.             case 3:  
  63.                 return Double.compare(r1.getPower(),r2.getPower());  
  64.             case 4:  
  65.                 return Double.compare(r1.getPrice(),r2.getPrice());  
  66.             default:  
  67.                 return 0;  
  68.             }  
  69.         }  
  70.     }  
  71.           
  72.           
  73.     private Vector _v = new Vector();  
  74.       
  75.     public void show()  
  76.     {  
  77.         System.out.println("................................");  
  78.         System.out.println("名称/t长度/t重量/t威力/t价格");  
  79.         for(int i=0; i<_v.size(); i++){  
  80.             System.out.println(_v.get(i));  
  81.         }  
  82.         System.out.println("................................");  
  83.     }  
  84.       
  85.     public boolean load(String x)  
  86.     {  
  87.         try{  
  88.             BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(x)));  
  89.             _v.clear();  
  90.             br.readLine();  // 第一行不要  
  91.             for(;;){  
  92.                 String s = br.readLine();  
  93.                 if(s==nullbreak;  
  94.                 MyRow row = new MyRow(s);  
  95.                 _v.add(row);  
  96.             }         
  97.               
  98.             show();  
  99.               
  100.             return true;      
  101.         }  
  102.         catch(Exception e){  
  103.             //e.printStackTrace();  
  104.             return false;  
  105.         }  
  106.     }  
  107.       
  108.     public boolean sort(String x)  
  109.     {  
  110.         if(x.equals("length")){  
  111.             Collections.sort(_v, new CaiPan(1));  
  112.             show();  
  113.             return true;  
  114.         }  
  115.         if(x.equals("weight")){  
  116.             Collections.sort(_v, new CaiPan(2));  
  117.             show();  
  118.             return true;  
  119.         }  
  120.         if(x.equals("power")){  
  121.             Collections.sort(_v, new CaiPan(3));  
  122.             show();  
  123.             return true;  
  124.         }  
  125.         if(x.equals("price")){  
  126.             Collections.sort(_v, new CaiPan(4));  
  127.             show();  
  128.             return true;  
  129.         }  
  130.           
  131.         return false;  
  132.     }  
  133.       
  134.     // 初步解析命令  
  135.     public boolean select(String x)  
  136.     {  
  137.         Vector sort = new Vector();  // 显示的字段  
  138.         Vector where = new Vector();  // 过滤的条件语句  
  139.           
  140.         String[] ss = x.split(" ");  
  141.           
  142.         Vector t = sort;  
  143.         for(int i=0; i<ss.length; i++){  
  144.             if(ss[i].length()==0continue;  // 防止多个空格  
  145.             if(ss[i].equals("where")){  
  146.                 t = where;  
  147.                 continue;  
  148.             }  
  149.             t.add(ss[i]);  
  150.         }  
  151.           
  152.         if(sort.size()==0return false;  // 字段必须指定  
  153.         if(sort.size()>5return false;  // 字段太多  
  154.           
  155.         return select(sort, where);   
  156.     }     
  157.       
  158.     // 执行select任务  
  159.     public boolean select(List sort, List where)  
  160.     {  
  161.     try{  
  162.         System.out.println("................................");  
  163.         //输出标题  
  164.         for(int k=0; k<sort.size(); k++){  
  165.             if(sort.get(k).equals("name"))  
  166.                 System.out.print("姓名/t");  
  167.             else if(sort.get(k).equals("length"))  
  168.                 System.out.print("长度/t");  
  169.             else if(sort.get(k).equals("weight"))  
  170.                 System.out.print("重量/t");  
  171.             else if(sort.get(k).equals("power"))  
  172.                 System.out.print("威力/t");  
  173.             else if(sort.get(k).equals("price"))  
  174.                 System.out.print("价格/t");  
  175.             else if(sort.get(k).equals("*"))  
  176.                 System.out.print("名称/t长度/t重量/t威力/t价格/t");  
  177.             else  
  178.                 return false;  
  179.         }// 枚举sort  
  180.         System.out.println("");  
  181.           
  182.           
  183.         //输出内容  
  184.         for(int i=0; i<_v.size(); i++){  
  185.             MyRow row = (MyRow)_v.get(i);  
  186.             if(checkWhere(row, where)){  
  187.                 for(int k=0; k<sort.size(); k++){  
  188.                     if(sort.get(k).equals("name"))  
  189.                         System.out.print(row.getName() + "/t");  
  190.                     else if(sort.get(k).equals("length"))  
  191.                         System.out.print(row.getLength() + "/t");  
  192.                     else if(sort.get(k).equals("weight"))  
  193.                         System.out.print(row.getLength() + "/t");  
  194.                     else if(sort.get(k).equals("power"))  
  195.                         System.out.print(row.getLength() + "/t");  
  196.                     else if(sort.get(k).equals("price"))  
  197.                         System.out.print(row.getLength() + "/t");  
  198.                     else if(sort.get(k).equals("*"))  
  199.                         System.out.print(row + "/t");  
  200.                     else  
  201.                         return false;  
  202.                 }// 枚举sort  
  203.                 System.out.println("");  
  204.             }//检查过滤条件     
  205.         }//对每个行处理  
  206.           
  207.         System.out.println("................................");  
  208.         return true;  
  209.     }  
  210.     catch(Exception e){  
  211.         //e.printStackTrace();  
  212.         return false;  
  213.     }  
  214.     }  
  215.       
  216.       
  217.     // 返回true 则该行记录显示,返回false,则不显示  
  218.     public boolean checkWhere(MyRow row, List where) throws Exception  
  219.     {  
  220.         boolean op=true;  // true: 表示比较符号为 > , 否则为 <  
  221.         String field = "";  // 过滤条件的字段  
  222.         String value = "";  // 过滤值  
  223.       
  224.         // 对每一个条件处理   
  225.         for(int i=0; i<where.size(); i++){  
  226.             String s = (String)where.get(i);  
  227.             String[] ss = s.split(">");  
  228.             if(ss.length==2){  
  229.                 field = ss[0];  
  230.                 op = true;  
  231.                 value = ss[1];  
  232.             }  
  233.             else{  
  234.                 ss = s.split("<");  
  235.                 if(ss.length==2){  
  236.                     field = ss[0];  
  237.                     op = false;  
  238.                     value = ss[1];  
  239.                 }  
  240.                 else  
  241.                     return false;  // 既没有"<"也没有">"的情况  
  242.             }  
  243.               
  244.             double d_value = Double.parseDouble(value);  
  245.               
  246.             if(field.equals("length")){  
  247.                 if(op){  
  248.                     if(row.getLength() <= d_value)   return false;  
  249.                 }         
  250.                 else{  
  251.                     if(row.getLength() >= d_value) return false;  
  252.                 }  
  253.             }  
  254.             else if(field.equals("weight")){  
  255.                 if(op){  
  256.                     if(row.getWeight() <= d_value) return false;  
  257.                 }  
  258.                 else{  
  259.                     if(row.getWeight() >= d_value) return false;  
  260.                 }  
  261.             }  
  262.             else if(field.equals("power")){  
  263.                 if(op){  
  264.                     if(row.getPower() <= d_value) return false;  
  265.                 }  
  266.                 else{  
  267.                     if(row.getPower() >= d_value) return false;  
  268.                 }  
  269.             }  
  270.             else if(field.equals("price")){  
  271.                 if(op){  
  272.                     if(row.getPrice() <= d_value) return false;  
  273.                 }  
  274.                 else{  
  275.                     if(row.getPrice() >= d_value) return false;  
  276.                 }  
  277.             }  
  278.             else  
  279.                 throw new Exception("valid field name!");  // 无法识别的 field,则算错表达式错  
  280.         }  
  281.           
  282.         return true;  
  283.     }  
  284. }  
  285.   
  286. // 负责解释用户输入的命令  
  287. class MyCommand  
  288. {  
  289.     private MyData data;  
  290.       
  291.     public MyCommand(MyData x)  
  292.     {  
  293.         data = x;  
  294.     }  
  295.       
  296.     public boolean execute(String x)  
  297.     {  
  298.         int d = x.indexOf(" ");  // 找第一个空格的位置  
  299.         if(d<0return false;  
  300.           
  301.         String x1 = x.substring(0,d);    
  302.         String x2 = x.substring(d+1);    
  303.           
  304.         if(x1.equals("load")){  
  305.             if(!data.load(x2.trim()))  
  306.                 System.out.println("装入文件出错!");  
  307.             return true;  
  308.         }  
  309.               
  310.         if(x1.equals("sort"))  
  311.             return data.sort(x2.trim());  
  312.           
  313.         if(x1.equals("select"))  
  314.             return data.select(x2);  
  315.           
  316.         return false;  
  317.     }  
  318. }  
  319.   
  320.   
  321. public class My  
  322. {  
  323.     private static BufferedReader br_keyboard;    
  324.       
  325.     static  
  326.     {  
  327.         br_keyboard = new BufferedReader(new InputStreamReader(System.in));  // 将它用于从键盘读入  
  328.     }  
  329.       
  330.     public static void main(String[] args) throws Exception  
  331.     {  
  332.         MyData data = new MyData();  
  333.         MyCommand cmd = new MyCommand(data);  // cmd 服务于 data  
  334.           
  335.         for(;;){  
  336.             System.out.print("请输入命令(输入help显示帮助信息):");  
  337.             String s = br_keyboard.readLine();  
  338.               
  339.             if(s.equals("exit")) break;  
  340.               
  341.             if(s.equals("help")){  
  342.                 System.out.println("----------------------------");  
  343.                 System.out.println("load data.txt");  
  344.                 System.out.println("从当前目录装入文件data.txt,并显示");  
  345.                 System.out.println("sort weight");  
  346.                 System.out.println("按“重量”排序,并显示");  
  347.                 System.out.println("类似地,还可以是 sort length, sort price,sort power等");  
  348.                 System.out.println("select weight length");  
  349.                 System.out.println("只显示 重量,长度两列");  
  350.                 System.out.println("select weight length where price > 50");  
  351.                 System.out.println("只显示 重量,长度两列, 只包含价格 > 50 的行");  
  352.                 System.out.println("select * where price>50 length<30");  
  353.                 System.out.println("显示所有列, 只包含价格>50 且 长度<30 的行");  
  354.                 System.out.println("其它的组合,从上边类推");  
  355.                 System.out.println("exit");  
  356.                 System.out.println("退出程序");  
  357.                 System.out.println("----------------------------");  
  358.                 continue;  
  359.             }  
  360.               
  361.             if(!cmd.execute(s)){  
  362.                 System.out.println("无效的命令");  
  363.             }  
  364.         }  
  365.           
  366.     }  
  367. }  

相关文章
|
28天前
|
算法 Linux C++
【Linux系统编程】解析获取和设置文件信息与权限的Linux系统调用
【Linux系统编程】解析获取和设置文件信息与权限的Linux系统调用
29 0
|
28天前
|
算法 Linux C++
【Linux系统编程】深入解析Linux中read函数的错误场景
【Linux系统编程】深入解析Linux中read函数的错误场景
202 0
|
29天前
|
SQL Perl
PL/SQL编程基本概念
PL/SQL编程基本概念
13 0
|
29天前
|
机器学习/深度学习 算法 编译器
【C++ 泛型编程 中级篇】深度解析C++:类型模板参数与非类型模板参数
【C++ 泛型编程 中级篇】深度解析C++:类型模板参数与非类型模板参数
47 0
|
29天前
|
存储 JSON 安全
【C++ 泛型编程 综合篇】泛型编程深度解析:C++中的五种类型泛型策略综合对比
【C++ 泛型编程 综合篇】泛型编程深度解析:C++中的五种类型泛型策略综合对比
65 1
|
29天前
|
设计模式 算法 数据安全/隐私保护
【C++ 引用 】C++深度解析:引用成员变量的初始化及其在模板编程中的应用(二)
【C++ 引用 】C++深度解析:引用成员变量的初始化及其在模板编程中的应用
25 0
【C++ 引用 】C++深度解析:引用成员变量的初始化及其在模板编程中的应用(二)
|
29天前
|
存储 算法 编译器
【C++ 引用 】C++深度解析:引用成员变量的初始化及其在模板编程中的应用(一)
【C++ 引用 】C++深度解析:引用成员变量的初始化及其在模板编程中的应用
39 0
|
1天前
|
SQL 分布式计算 资源调度
一文解析 ODPS SQL 任务优化方法原理
本文重点尝试从ODPS SQL的逻辑执行计划和Logview中的执行计划出发,分析日常数据研发过程中各种优化方法背后的原理,覆盖了部分调优方法的分析,从知道怎么优化,到为什么这样优化,以及还能怎样优化。
|
6天前
|
API Python
Python模块化编程:面试题深度解析
【4月更文挑战第14天】了解Python模块化编程对于构建大型项目至关重要,它涉及代码组织、复用和维护。本文深入探讨了模块、包、导入机制、命名空间和作用域等基础概念,并列举了面试中常见的模块导入混乱、不适当星号导入等问题,强调了避免循环依赖、合理使用`__init__.py`以及理解模块作用域的重要性。掌握这些知识将有助于在面试中自信应对模块化编程的相关挑战。
19 0
|
11天前
|
Java 数据库 Spring
切面编程的艺术:Spring动态代理解析与实战
切面编程的艺术:Spring动态代理解析与实战
25 0
切面编程的艺术:Spring动态代理解析与实战

推荐镜像

更多