基于逻辑表达式的集合运算
来源:互联网 发布:淘宝手写披露函 编辑:程序博客网 时间:2024/06/06 17:39
课题:基于逻辑表达式的集合运算
需求:
实际项目开发中,我们可能会有这样的需求,有A、B、C、D四个集合,需要对这四个集合进行一定的逻辑运算,从而得到经过该表达式运算之后的最终的集合情况。
实例:
1、假设现在有四个集合元素分别为:
A集合:20,50,60
B集合:70,80
C集合:90,100
D集合:30,70,80
2、运算表达式为:(A∪B)∩(C∪D)
3、我们想要的最终集合为:70,80.
A∪B = 20,50,60,70,80
C∪D = 90,100,70,80,30
(A∪B)∩(C∪D)= 70,80
步骤:
1、建立操作模型。
逻辑表达式的解析,一般思路就是依据运算符号(包括括号)优先级下坠,构建成树状结构。所以我们建立的模型如下:
LogicExpression{
LogicExpression left;//左分支
LogicExpression right;//右分支
Collection data;//数据集合
}
2、解析逻辑表达式,根据表达式初始化操作模型的树状结构。
3、根据集合索引,向树状结构的操作模型中各个节点分发数据集合。
4、根据树模型的中序遍历规则,将各个节点的左右俩分支的数据集合进行运算。
5、最后得到根节点的数据集合,即为所求。
源码:
package tools;import java.util.ArrayList;import java.util.Collection;import java.util.HashMap;import java.util.List;import java.util.Map;import java.util.StringTokenizer;/** * 逻辑表达式或数值表达式的解析成表达式树结构 * * @author 高伟 * @date May 29, 2012 8:51:49 AM * @description: */public class LogicExpression { private String separators = "∩∪()"; private String[] operators = { "∩", "∪" }; /* * 树节点数据 */ private String data = null; /* * 树节点左分支 */ private LogicExpression left = null; /* * 树节点右分支 */ private LogicExpression right = null; /* * 树节点集合数据 */ private Collection<Object> dataList = new ArrayList<Object>(); private String exp = ""; private List<String> parts = new ArrayList<String>(); private int numOperators = 0; public LogicExpression(String exp) throws RuntimeException { this(exp, "∩∪()", new String[]{ "∩", "∪" }); } private LogicExpression(String exp, String separators, String[] operators) throws RuntimeException { this.separators = separators; this.operators = operators; this.exp = exp; splitExpression(exp); parseSyntax(); } /** * 打印解析后表达式树结构,按照前序遍历。 * * printTree * 高伟 * May 29, 2012 8:59:43 AM */ public void printTree() { System.out.println(data); if ( left !=null ) left.printTree(); if ( right != null ) right.printTree(); } /** * 将集合Map分发到树的每个节点 * * walkMap * @param map * 高伟 * May 29, 2012 9:00:26 AM */ public void walkMap(Map<String, Collection<Object>> map) { if ( left != null ) left.walkMap(map); if("∩".equals(data) || "∪".equals(data) || "(".equals(data) || ")".equals(data)){ }else{ dataList = map.get(data); } if ( right != null ) right.walkMap(map); } /** * 按照先左后右的顺序合并所有节点的集合 * * combin * 高伟 * May 29, 2012 9:00:55 AM */ public void combin() { if(left != null ){ left.combin(); dataList.addAll(left.dataList); } if(right != null ){ right.combin(); if("∩".equals(data)){ dataList.retainAll(right.dataList); }else if("∪".equals(data)){ dataList.addAll(right.dataList); } } } /** * 分隔表达式 * * splitExpression * @param Expression * 高伟 * May 29, 2012 9:03:55 AM */ private void splitExpression(String Expression) { StringTokenizer statements = new StringTokenizer(Expression, separators, true); String tempToken; parts.clear(); numOperators = 0; while (statements.hasMoreElements()) { tempToken = (String) statements.nextElement(); for (int i = 0; i < operators.length; i++) if (tempToken.equals(operators[i])) numOperators++; parts.add(tempToken); } } /** * 解析表达式为树结构 * * parseSyntax * @throws RuntimeException * 高伟 * May 29, 2012 9:04:07 AM */ private void parseSyntax() throws RuntimeException { String actToken = ""; int level = 0; int foundPriority = Integer.MAX_VALUE; int foundLevel = Integer.MAX_VALUE; int foundPosition = -1; String foundOperator = ""; if (numOperators == 0) { setData((String) parts.get(0)); return; } for (int position = 0; position < parts.size(); position++) { actToken = (String) parts.get(position); if (actToken.equals("(")) { level++; continue; } if (actToken.equals(")")) { level--; continue; } for (int prior = 0; prior < operators.length; prior++) if (actToken.equals(operators[prior])) if (level < foundLevel || (level == foundLevel && prior < foundPriority)) { foundLevel = level; foundPriority = prior; foundPosition = position; foundOperator = actToken; break; } } if (level != 0) throw new RuntimeException("parseSyntax error"); if (foundLevel != Integer.MAX_VALUE && foundLevel > 0) { if (!((String) parts.get(0)).equals("(") || !((String) parts.get(parts.size() - 1)).equals(")")) throw new RuntimeException("parseSyntax error"); exp = exp.substring(1, exp.length() - 1); splitExpression(exp); parseSyntax(); return; } String leftPart = ""; String rightPart = ""; for (int i = 0; i < parts.size(); i++) if (i < foundPosition) leftPart = leftPart.concat((String) parts.get(i)); else if (i != foundPosition) rightPart = rightPart.concat((String) parts.get(i)); setData(foundOperator); if (leftPart.equals("") && !foundOperator.equals("")) { setRight(new LogicExpression(rightPart)); } else { setLeft(new LogicExpression(leftPart)); setRight(new LogicExpression(rightPart)); } } //get set method public String getData() { return data; } public void setData(String data) { this.data = data; } public LogicExpression getLeft() { return left; } public void setLeft(LogicExpression left) { this.left = left; } public LogicExpression getRight() { return right; } public void setRight(LogicExpression right) { this.right = right; } public Collection<Object> getDataList() { return dataList; } public void setDataList(Collection<Object> dataList) { this.dataList = dataList; } @Override public String toString() { return data; }}
测试:
public static void main(String[] args) { {//多层次测试 LogicExpression logExp = new LogicExpression("(A∪B)∩(C∪D)");//1、建立操作模型。2、解析逻辑表达式 logExp.printTree();//打印操作模型。 Map<String, Collection<Object>> map = new HashMap<String, Collection<Object>>(); { List<Object> list = new ArrayList<Object>(); list.add(new Integer(20)); list.add(new Integer(50)); list.add(new Integer(60)); map.put("A", list); } { List<Object> list = new ArrayList<Object>(); list.add(new Integer(70)); list.add(new Integer(80)); map.put("B", list); } { List<Object> list = new ArrayList<Object>(); list.add(new Integer(90)); list.add(new Integer(100)); map.put("C", list); } { List<Object> list = new ArrayList<Object>(); list.add(new Integer(30)); list.add(new Integer(70)); list.add(new Integer(80)); map.put("D", list); } logExp.walkMap(map);//3、根据集合索引,向树状结构的操作模型中各个节点分发数据集合。 logExp.combin();//4、根据树模型的中序遍历规则,将各个节点的左右俩分支的数据集合进行运算。 Collection<Object> list = logExp.getDataList();//5、最后得到根节点的数据集合,即为所求。 for (Object obj : list) { System.out.println(obj); } }}
结果:
7080
总结:
godway
com.gaowei@msn.com
2012-07-04
- 基于逻辑表达式的集合运算
- SQL 基于列的逻辑表达式 (CASE)
- T-SQL查询进阶--基于列的逻辑表达式
- T-SQL查询进阶--基于列的逻辑表达式(CASE)
- T-SQL查询进阶--基于列的逻辑表达式
- [Happy Coding] 一个正则表达式,支持逻辑和关系运算符组成的表达式计算
- jsf EL 表达式逻辑操作运算
- Linux shell运算符、逻辑表达式详解
- 逻辑表达式的运用
- 基于栈运算的算术表达式(纠错判错)
- 基于列的逻辑
- 基于行的逻辑
- Java中逻辑表达式的短路(先理解运算符的优先级)
- 逻辑代数的基本运算
- QT学习笔记之十五 BooleanParser 基于Qt4的逻辑表达式分析工具
- 离散--第一节--逻辑符号 + 集合及其运算 + 证明方法概述
- 集合的运算
- 集合的运算
- myeclipse与eclipse利用tomcat发布web工程的区别
- onSaveInstanceState和onRestoreInstanceState触发的时机
- C++ - 实现strstr函数
- 无意看见的几句话
- typeid与typedef
- 基于逻辑表达式的集合运算
- Stanford机器学习---第三讲. 逻辑回归和过拟合问题的解决 logistic Regression & Regularization
- 字符串练习2:输出一个子串在整串中出现的次数
- 解决ubuntu下filezilla登录ftp看不到中文目录和文件的问题
- C++ - 实现strcmp函数
- 心态和想法,是提高编程水平的关键
- 大学毕业后拉开差距的原因
- vim configure
- CMD 注释用法