续上一篇文章,用栈来实现:按照用户输入的rule,经过并、交、差运算后,输出字符串结果。
来源:互联网 发布:windows平板不好用 编辑:程序博客网 时间:2024/03/29 07:40
废话不说了,
文件:
A{1,2,3,4,5,6}
B{7,4,5,6,8}
C{2,3,12,14,4,11}
测试时输入到控制台的字符串为:
C+B-(A*(C-A))+B
结果:
2 3 12 14 4 11 7 8 1 5 6
自己算了一下,是正确的!
代码如下,注释也写的蛮多的:
- /**
- * 从事先写好的Input.txt文件中读取数,
- * Input.txt 内容
- * A{13,2,1,20,30,50}
- * B{1,2,34,5,6}
- * C{2,3,12,23,14,11}
- * 用户在键盘随意敲入...例如((A*B))+B-C,((C+B)*A)-B期中+,*,-,分别代表集合的并交差运算,控制台打印输出。
- */
- package com.lim.test;
- import java.io.BufferedReader;
- import java.io.FileInputStream;
- import java.io.IOException;
- import java.io.InputStreamReader;
- import java.lang.reflect.InvocationTargetException;
- import java.lang.reflect.Method;
- import java.util.ArrayList;
- import java.util.List;
- import java.util.Stack;
- /**
- * @author bzwm
- *
- */
- public class EditorStringV2 {
- // 保存住集合A中的数据
- private Type typeA = null;
- // 保存住集合B中的数据
- private Type typeB = null;
- // 保存住集合C中的数据
- private Type typeC = null;
- private Stack stack = new Stack();
- public EditorStringV2(String path) {
- readFile(path);
- }
- /**
- * 读入指定的文件
- *
- * @param path
- */
- private void readFile(String path) {
- BufferedReader reader = null;
- try {
- reader = new BufferedReader(new InputStreamReader(
- new FileInputStream(path)));
- String str = null;
- // 保存已经写好的文件中A,B,C的集合
- while ((str = reader.readLine()) != null) {
- // 保存集合A
- if (str.substring(0, 1).equals("A")) {
- typeA = new Type(str);
- }
- // 保存集合B
- else if (str.substring(0, 1).equals("B")) {
- typeB = new Type(str);
- }
- // 保存集合C
- else if (str.substring(0, 1).equals("C")) {
- typeC = new Type(str);
- } else {
- System.out.println("no such type!");
- return;
- }
- }
- } catch (Exception e) {
- e.printStackTrace();
- return;
- }
- }
- /**
- * 处理并、交、差操作,显示结果
- *
- * @param rule
- * 例:C-((C+B)-A)*B
- * @throws InvocationTargetException
- * @throws IllegalAccessException
- * @throws NoSuchMethodException
- * @throws IllegalArgumentException
- * @throws SecurityException
- */
- public Stack displayResult(Stack orgStack) throws SecurityException,
- IllegalArgumentException, NoSuchMethodException,
- IllegalAccessException, InvocationTargetException {
- // 左括号"("的计数器
- int leftBracket = 0;
- // 是否存在操作符标志符
- boolean hasOpe = false;
- // 输入的rule的长度
- int length = orgStack.size();
- Object obj = null;
- if (length < 3) {
- System.out.println("input rule is illegal.");
- return null;
- } else {
- for (int i = 0; i < length; i++) {
- // 截取rule的每个字符
- obj = orgStack.pop();
- // 如果是左括号,则leftBracket加1
- if (isLeftBracket(obj)) {
- leftBracket += 1;
- stack.push(obj);
- continue;
- }
- // 如果是操作符,则将操作符标志符置为true
- if (isOperator(obj)) {
- hasOpe = true;
- stack.push(obj);
- continue;
- }
- // 如果不是左括号和操作符则入栈
- stack.push(obj);
- // 如果左括号存在,且本次字符为右括号
- if (leftBracket > 0 && isRightBracket(obj)) {
- // 将右括号弹出栈
- stack.pop();
- // 将形如typeA.bing(typeB)的方法调用的参数标志弹出
- Type arg = (Type) stack.pop();
- // 将形如typeA.bing(typeB)的方法调用的操作符标志弹出:+/bing */jiao -/cha
- String ope = stack.pop().toString();
- // 将形如typeA.bing(typeB)的方法调用的主调对象标志弹出
- Type invokeObj = (Type) stack.pop();
- // 通过对象工厂,构造出Type对象,进行并、交、差操作,返回得到的新Type对象
- Type typeTmp = execute(invokeObj, ope, arg);
- // 将左括号弹出栈
- stack.pop();
- // 左括号计数器减1
- leftBracket -= 1;
- // 栈中加入临时的Type对象标志T,T代表本次操作后得到的新集合
- stack.push(typeTmp);
- // 当栈中还有运算时,进行递归
- if (stack.size() > 2) {
- Stack tmpStack = new Stack();
- while (stack.size() > 0) {
- tmpStack.push(stack.pop());
- }
- stack = displayResult(tmpStack);
- }
- continue;
- }
- // 如果1.栈中还没有左括号 2.栈有操作符 3.本次字符是集合标志A、B、C
- // 则进行并、交、差操作
- if (leftBracket == 0 && hasOpe && isType(obj)) {
- // 将形如typeA.bing(typeB)的方法调用的参数标志弹出
- Type arg = (Type) stack.pop();
- // 将形如typeA.bing(typeB)的方法调用的操作符标志弹出:+/bing */jiao -/cha
- String ope = stack.pop().toString();
- // 将形如typeA.bing(typeB)的方法调用的主调对象标志弹出
- Type invokeObj = (Type) stack.pop();
- // 通过对象工厂,构造出Type对象,进行并、交、差操作,返回得到的新Type对象
- Type typeTmp = execute(invokeObj, ope, arg);
- // 栈中加入临时的Type对象标志T,T代表本次操作后得到的新集合
- stack.push(typeTmp);
- // 将操作符标志符置为false
- hasOpe = false;
- // 当栈中还有运算时,进行递归
- if (stack.size() > 2) {
- Stack tmpStack = new Stack();
- while (stack.size() > 0) {
- tmpStack.push(stack.pop());
- }
- stack = displayResult(tmpStack);
- }
- continue;
- }
- }
- // 循环结束,得到最后结果
- return stack;
- }
- }
- /**
- * 判断对象o是否为Type的实例
- *
- * @param o
- * @return
- */
- private boolean isType(Object o) {
- return o instanceof Type;
- }
- /**
- * 判断对象o是否为操作符*,+,-
- *
- * @param o
- * @return
- */
- private boolean isOperator(Object o) {
- return !isType(o) && ((String) o).matches("[+//*-]");
- }
- /**
- * 判断对象o是否左括号"("
- *
- * @param o
- * @return
- */
- private boolean isLeftBracket(Object o) {
- return !isType(o) && ((String) o).equals("(");
- }
- /**
- * 判断对象o是否右括号")"
- *
- * @param o
- * @return
- */
- private boolean isRightBracket(Object o) {
- return !isType(o) && ((String) o).equals(")");
- }
- /**
- * 利用反射机制,根据ope的不同,调用不同的方法
- *
- * @param obj
- * @param arg
- * @param ope
- * @return
- * @throws SecurityException
- * @throws NoSuchMethodException
- * @throws IllegalArgumentException
- * @throws IllegalAccessException
- * @throws InvocationTargetException
- */
- private Type execute(Type obj, String ope, Type arg)
- throws SecurityException, NoSuchMethodException,
- IllegalArgumentException, IllegalAccessException,
- InvocationTargetException {
- Class c = obj.getClass();
- Class[] args = new Class[1];
- args[0] = arg.getClass();
- Method m = null;
- // 如果操作符为"+",则执行bing方法
- if (ope.equals("+")) {
- m = c.getMethod("bing", args);
- }
- // 如果操作符为"*",则执行jiao方法
- else if (ope.equals("*")) {
- m = c.getMethod("jiao", args);
- }
- // 如果操作符为"-",则执行cha方法
- else if (ope.equals("-")) {
- m = c.getMethod("cha", args);
- } else {
- System.out.println("NoSuchMethod");
- return null;
- }
- return (Type) m.invoke(obj, new Object[] { arg });
- }
- /**
- * 读入用户输入的匹配规则 如:((C+B)*A)-B
- *
- * @return
- */
- private Stack readInput() {
- Stack ret = new Stack();
- String str = null;
- String o = null;
- BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
- try {
- str = br.readLine();
- } catch (IOException e) {
- e.printStackTrace();
- return null;
- }
- for (int i = str.length(); i > 0; i--) {
- o = str.substring(i - 1, i);
- // 当遇到A,B,C时,生成Type对象存入栈中
- if (o.matches("[ABC]")) {
- ret.push(typeFactory(o));
- continue;
- }
- ret.push(o);
- }
- return ret;
- }
- /**
- * 构造工厂 根据传入的type构造Type对象 保存住原集合
- *
- * @param type
- * @return
- */
- private Type typeFactory(String type) {
- if (type.equals("A")) {
- return new Type(typeA.getArray());
- } else if (type.equals("B")) {
- return new Type(typeB.getArray());
- } else if (type.equals("C")) {
- return new Type(typeC.getArray());
- } else {
- return null;
- }
- }
- /**
- * 把如{13,2,1,20,30,50}的集合抽象成一个类,提供并、交、差操作
- *
- * @author bzwm
- *
- */
- class Type {
- // 保存数据集合的List
- private List array = new ArrayList();
- public Type(String srt) {
- this.array = createList(srt);
- }
- public Type(List list) {
- this.array.addAll(list);
- }
- public List getArray() {
- return this.array;
- }
- /**
- * 并操作
- *
- * @param arg
- * @return
- */
- public Type bing(Type arg) {
- // 是否加入到集合中的标志
- boolean add = true;
- // 取出传入的Type对象的List
- List list = arg.getArray();
- // 遍历传入的Type对象的List
- for (int i = 0; i < list.size(); i++) {
- add = true;
- // 与array里的值一一进行比较,如果全都不等,则加入到原array中,否则不加入
- for (int j = 0; j < array.size(); j++) {
- if (((Integer) list.get(i)).intValue() == ((Integer) array
- .get(j)).intValue()) {
- add = false;
- }
- }
- if (add) {
- array.add(list.get(i));
- }
- }
- // 返回新的Type对象
- return new Type(array);
- }
- /**
- * 交操作
- *
- * @param arg
- * @return
- */
- public Type jiao(Type arg) {
- // 是否加入到集合中的标志
- boolean add = false;
- // 存放交集数据的List
- List ret = new ArrayList();
- // 取出传入的Type对象的List
- List list = arg.getArray();
- // 遍历传入的Type对象的List
- for (int i = 0; i < list.size(); i++) {
- add = false;
- // 与array里的值一一进行比较,如果有相等的,则加入到ret中,否则不加入
- for (int j = 0; j < array.size(); j++) {
- if (((Integer) list.get(i)).intValue() == ((Integer) array
- .get(j)).intValue()) {
- add = true;
- }
- }
- if (add) {
- ret.add(list.get(i));
- }
- }
- // 返回新的Type对象
- return new Type(ret);
- }
- /**
- * 差操作
- *
- * @param arg
- * @return
- */
- public Type cha(Type arg) {
- // 是否加入到集合中的标志
- boolean add = true;
- // 存放交集数据的List
- List list = arg.getArray();
- // 遍历传入的Type对象的List
- for (int i = 0; i < list.size(); i++) {
- add = true;
- // 与array里的值一一进行比较,如果有相等的,则从原array中将其删除,如果全都不等,则加入到原array中
- for (int j = 0; j < array.size(); j++) {
- if (((Integer) list.get(i)).intValue() == ((Integer) array
- .get(j)).intValue()) {
- add = false;
- // 删除相等的数据
- array.remove(j);
- }
- }
- if (add) {
- array.add(list.get(i));
- }
- }
- // 返回新的Type对象
- return new Type(array);
- }
- /**
- * 解析字符串,将数字加入到List中
- *
- * @param str
- * @return
- */
- private List createList(String str) {
- // 将字符串解析成字符串数组A{13,2,1,20,30,50}-->new String[]{13,2,1,20,30,50}
- String s[] = str.replaceAll(str.substring(0, 1), "").replace("{",
- "").replace("}", "").split(",");
- List list = new ArrayList();
- for (int i = 0; i < s.length; i++) {
- list.add(new Integer(s[i]));
- }
- return list;
- }
- }
- /**
- * 测试程序
- *
- * @param args
- * @throws InvocationTargetException
- * @throws IllegalAccessException
- * @throws NoSuchMethodException
- * @throws IllegalArgumentException
- * @throws SecurityException
- */
- public static void main(String args[]) throws SecurityException,
- IllegalArgumentException, NoSuchMethodException,
- IllegalAccessException, InvocationTargetException {
- EditorStringV2 es = new EditorStringV2("input.txt");
- Stack s = es.readInput();
- Stack result = es.displayResult(s);// ((C+B)*A)-B
- List list = ((Type) result.pop()).getArray();
- System.out.println("操作运算后结果为:");
- for (int i = 0; i < list.size(); i++)
- System.out.print(list.get(i) + " ");
- }
- }
- 续上一篇文章,用栈来实现:按照用户输入的rule,经过并、交、差运算后,输出字符串结果。
- 一道笔试题:按照用户输入的rule,经过并、交、差运算后,输出字符串结果。
- 2、从键盘上输入两个整数,由用户回答它们的和,差,积,商和取余运算结果,并统计出正确答案的个数。
- 集合的交 并 差 补 运算
- 集合的交、并、差运算
- 集合的并、交和差运算
- 在以单链表表示的正整数的有序集合上,实现集合的并、交和差运算
- 对输入的字符串按照字母序列排序并输出
- 集合交、并、差运算
- 集合的基本运算: 依据集合运算规则,实现任意给定两个集合的交、并、差、笛卡儿积运算,和第一个集合的幂集,并显示运算结果。
- 集合的交、并、差的实现
- 集合的交、并、差的实现
- 从键盘上输入两个整数_由用户回答它们的和_差_积_商和取余运算结果_并统计出正确答案的个数
- 实现两个集合的相等判定、并、交和差运算
- 用CDate类成员函数实现对用户按照年月日格式输入的日期加一天后按照年/月/日格式输出
- 集合的并、交和差运算的程序
- multiset集合容器的集合运算:并、交、差
- c++项目--集合的并差交综合运算
- 算符优先分析为何不支持单目负号
- linux 技巧:使用 screen 管理你的远程会话
- 计算EAN-13校验位
- S3C2440Camera驱动调试笔记
- 在vs2005中集成QT4.4.3的编译方式
- 续上一篇文章,用栈来实现:按照用户输入的rule,经过并、交、差运算后,输出字符串结果。
- 字符串转换_BSTR/LPSTR/LPWSTR/Char
- Java_JDK环境变量的设置
- AD-hoc测试介绍
- psptoolchain下载地址和安装方法
- IE 里面的activeX控件的打印预览问题
- DOS批处理实现SQLServer2000数据库自动备份
- 成都狼窝java项目笔记(2)
- asp数组随机排序