废话不说了,
文件:
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
自己算了一下,是正确的!
代码如下,注释也写的蛮多的:
1/** *//**
2 * 从事先写好的Input.txt文件中读取数,
3 * Input.txt 内容
4 * A{13,2,1,20,30,50}
5 * B{1,2,34,5,6}
6 * C{2,3,12,23,14,11}
7 * 用户在键盘随意敲入例如((A*B))+B-C,((C+B)*A)-B期中+,*,-,分别代表集合的并交差运算,控制台打印输出。
8 */
9package com.lim.test;
10
11import java.io.BufferedReader;
12import java.io.FileInputStream;
13import java.io.IOException;
14import java.io.InputStreamReader;
15import java.lang.reflect.InvocationTargetException;
16import java.lang.reflect.Method;
17import java.util.ArrayList;
18import java.util.List;
19import java.util.Stack;
20
21/** *//**
22 * @author bzwm
23 *
24 */
25public class EditorStringV2 {
26 // 保存住集合A中的数据
27 private Type typeA = null;
28
29 // 保存住集合B中的数据
30 private Type typeB = null;
31
32 // 保存住集合C中的数据
33 private Type typeC = null;
34
35 private Stack stack = new Stack();
36
37 public EditorStringV2(String path) {
38 readFile(path);
39 }
40
41 /** *//**
42 * 读入指定的文件
43 *
44 * @param path
45 */
46 private void readFile(String path) {
47 BufferedReader reader = null;
48 try {
49 reader = new BufferedReader(new InputStreamReader(
50 new FileInputStream(path)));
51 String str = null;
52 // 保存已经写好的文件中A,B,C的集合
53 while ((str = reader.readLine()) != null) {
54 // 保存集合A
55 if (str.substring(0, 1).equals("A")) {
56 typeA = new Type(str);
57 }
58 // 保存集合B
59 else if (str.substring(0, 1).equals("B")) {
60 typeB = new Type(str);
61 }
62 // 保存集合C
63 else if (str.substring(0, 1).equals("C")) {
64 typeC = new Type(str);
65 } else {
66 System.out.println("no such type!");
67 return;
68 }
69 }
70 } catch (Exception e) {
71 e.printStackTrace();
72 return;
73 }
74 }
75
76 /** *//**
77 * 处理并、交、差操作,显示结果
78 *
79 * @param rule
80 * 例:C-((C+B)-A)*B
81 * @throws InvocationTargetException
82 * @throws IllegalAccessException
83 * @throws NoSuchMethodException
84 * @throws IllegalArgumentException
85 * @throws SecurityException
86 */
87 public Stack displayResult(Stack orgStack) throws SecurityException,
88 IllegalArgumentException, NoSuchMethodException,
89 IllegalAccessException, InvocationTargetException {
90 // 左括号"("的计数器
91 int leftBracket = 0;
92 // 是否存在操作符标志符
93 boolean hasOpe = false;
94 // 输入的rule的长度
95 int length = orgStack.size();
96 Object obj = null;
97 if (length < 3) {
98 System.out.println("input rule is illegal.");
99 return null;
100 } else {
101 for (int i = 0; i < length; i++) {
102 // 截取rule的每个字符
103 obj = orgStack.pop();
104 // 如果是左括号,则leftBracket加1
105 if (isLeftBracket(obj)) {
106 leftBracket += 1;
107 stack.push(obj);
108 continue;
109 }
110 // 如果是操作符,则将操作符标志符置为true
111 if (isOperator(obj)) {
112 hasOpe = true;
113 stack.push(obj);
114 continue;
115 }
116 // 如果不是左括号和操作符则入栈
117 stack.push(obj);
118 // 如果左括号存在,且本次字符为右括号
119 if (leftBracket > 0 && isRightBracket(obj)) {
120 // 将右括号弹出栈
121 stack.pop();
122 // 将形如typeA.bing(typeB)的方法调用的参数标志弹出
123 Type arg = (Type) stack.pop();
124 // 将形如typeA.bing(typeB)的方法调用的操作符标志弹出:+/bing */jiao -/cha
125 String ope = stack.pop().toString();
126 // 将形如typeA.bing(typeB)的方法调用的主调对象标志弹出
127 Type invokeObj = (Type) stack.pop();
128 // 通过对象工厂,构造出Type对象,进行并、交、差操作,返回得到的新Type对象
129 Type typeTmp = execute(invokeObj, ope, arg);
130 // 将左括号弹出栈
131 stack.pop();
132 // 左括号计数器减1
133 leftBracket -= 1;
134 // 栈中加入临时的Type对象标志T,T代表本次操作后得到的新集合
135 stack.push(typeTmp);
136 // 当栈中还有运算时,进行递归
137 if (stack.size() > 2) {
138 Stack tmpStack = new Stack();
139 while (stack.size() > 0) {
140 tmpStack.push(stack.pop());
141 }
142 stack = displayResult(tmpStack);
143 }
144 continue;
145 }
146
147 // 如果1.栈中还没有左括号 2.栈有操作符 3.本次字符是集合标志A、B、C
148 // 则进行并、交、差操作
149 if (leftBracket == 0 && hasOpe && isType(obj)) {
150 // 将形如typeA.bing(typeB)的方法调用的参数标志弹出
151 Type arg = (Type) stack.pop();
152 // 将形如typeA.bing(typeB)的方法调用的操作符标志弹出:+/bing */jiao -/cha
153 String ope = stack.pop().toString();
154 // 将形如typeA.bing(typeB)的方法调用的主调对象标志弹出
155 Type invokeObj = (Type) stack.pop();
156 // 通过对象工厂,构造出Type对象,进行并、交、差操作,返回得到的新Type对象
157 Type typeTmp = execute(invokeObj, ope, arg);
158 // 栈中加入临时的Type对象标志T,T代表本次操作后得到的新集合
159 stack.push(typeTmp);
160 // 将操作符标志符置为false
161 hasOpe = false;
162 // 当栈中还有运算时,进行递归
163 if (stack.size() > 2) {
164 Stack tmpStack = new Stack();
165 while (stack.size() > 0) {
166 tmpStack.push(stack.pop());
167 }
168 stack = displayResult(tmpStack);
169 }
170 continue;
171 }
172 }
173 // 循环结束,得到最后结果
174 return stack;
175 }
176 }
177
178 /** *//**
179 * 判断对象o是否为Type的实例
180 *
181 * @param o
182 * @return
183 */
184 private boolean isType(Object o) {
185 return o instanceof Type;
186 }
187
188 /** *//**
189 * 判断对象o是否为操作符*,+,-
190 *
191 * @param o
192 * @return
193 */
194 private boolean isOperator(Object o) {
195 return !isType(o) && ((String) o).matches("[+\\*-]");
196 }
197
198 /** *//**
199 * 判断对象o是否左括号"("
200 *
201 * @param o
202 * @return
203 */
204 private boolean isLeftBracket(Object o) {
205 return !isType(o) && ((String) o).equals("(");
206 }
207
208 /** *//**
209 * 判断对象o是否右括号")"
210 *
211 * @param o
212 * @return
213 */
214 private boolean isRightBracket(Object o) {
215 return !isType(o) && ((String) o).equals(")");
216 }
217
218 /** *//**
219 * 利用反射机制,根据ope的不同,调用不同的方法
220 *
221 * @param obj
222 * @param arg
223 * @param ope
224 * @return
225 * @throws SecurityException
226 * @throws NoSuchMethodException
227 * @throws IllegalArgumentException
228 * @throws IllegalAccessException
229 * @throws InvocationTargetException
230 */
231 private Type execute(Type obj, String ope, Type arg)
232 throws SecurityException, NoSuchMethodException,
233 IllegalArgumentException, IllegalAccessException,
234 InvocationTargetException {
235 Class c = obj.getClass();
236 Class[] args = new Class[1];
237 args[0] = arg.getClass();
238 Method m = null;
239 // 如果操作符为"+",则执行bing方法
240 if (ope.equals("+")) {
241 m = c.getMethod("bing", args);
242 }
243 // 如果操作符为"*",则执行jiao方法
244 else if (ope.equals("*")) {
245 m = c.getMethod("jiao", args);
246 }
247 // 如果操作符为"-",则执行cha方法
248 else if (ope.equals("-")) {
249 m = c.getMethod("cha", args);
250 } else {
251 System.out.println("NoSuchMethod");
252 return null;
253 }
254 return (Type) m.invoke(obj, new Object[] { arg });
255 }
256
257 /** *//**
258 * 读入用户输入的匹配规则 如:((C+B)*A)-B
259 *
260 * @return
261 */
262 private Stack readInput() {
263 Stack ret = new Stack();
264 String str = null;
265 String o = null;
266 BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
267 try {
268 str = br.readLine();
269 } catch (IOException e) {
270 e.printStackTrace();
271 return null;
272 }
273 for (int i = str.length(); i > 0; i--) {
274 o = str.substring(i - 1, i);
275 // 当遇到A,B,C时,生成Type对象存入栈中
276 if (o.matches("[ABC]")) {
277 ret.push(typeFactory(o));
278 continue;
279 }
280 ret.push(o);
281 }
282 return ret;
283 }
284
285 /** *//**
286 * 构造工厂 根据传入的type构造Type对象 保存住原集合
287 *
288 * @param type
289 * @return
290 */
291 private Type typeFactory(String type) {
292 if (type.equals("A")) {
293 return new Type(typeA.getArray());
294 } else if (type.equals("B")) {
295 return new Type(typeB.getArray());
296 } else if (type.equals("C")) {
297 return new Type(typeC.getArray());
298 } else {
299 return null;
300 }
301 }
302
303 /** *//**
304 * 把如{13,2,1,20,30,50}的集合抽象成一个类,提供并、交、差操作
305 *
306 * @author bzwm
307 *
308 */
309 class Type {
310 // 保存数据集合的List
311 private List array = new ArrayList();
312
313 public Type(String srt) {
314 this.array = createList(srt);
315 }
316
317 public Type(List list) {
318 this.array.addAll(list);
319 }
320
321 public List getArray() {
322 return this.array;
323 }
324
325 /** *//**
326 * 并操作
327 *
328 * @param arg
329 * @return
330 */
331 public Type bing(Type arg) {
332 // 是否加入到集合中的标志
333 boolean add = true;
334 // 取出传入的Type对象的List
335 List list = arg.getArray();
336 // 遍历传入的Type对象的List
337 for (int i = 0; i < list.size(); i++) {
338 add = true;
339 // 与array里的值一一进行比较,如果全都不等,则加入到原array中,否则不加入
340 for (int j = 0; j < array.size(); j++) {
341 if (((Integer) list.get(i)).intValue() == ((Integer) array
342 .get(j)).intValue()) {
343 add = false;
344 }
345 }
346 if (add) {
347 array.add(list.get(i));
348 }
349 }
350 // 返回新的Type对象
351 return new Type(array);
352 }
353
354 /** *//**
355 * 交操作
356 *
357 * @param arg
358 * @return
359 */
360 public Type jiao(Type arg) {
361 // 是否加入到集合中的标志
362 boolean add = false;
363 // 存放交集数据的List
364 List ret = new ArrayList();
365 // 取出传入的Type对象的List
366 List list = arg.getArray();
367 // 遍历传入的Type对象的List
368 for (int i = 0; i < list.size(); i++) {
369 add = false;
370 // 与array里的值一一进行比较,如果有相等的,则加入到ret中,否则不加入
371 for (int j = 0; j < array.size(); j++) {
372 if (((Integer) list.get(i)).intValue() == ((Integer) array
373 .get(j)).intValue()) {
374 add = true;
375 }
376 }
377 if (add) {
378 ret.add(list.get(i));
379 }
380 }
381 // 返回新的Type对象
382 return new Type(ret);
383 }
384
385 /** *//**
386 * 差操作
387 *
388 * @param arg
389 * @return
390 */
391 public Type cha(Type arg) {
392 // 是否加入到集合中的标志
393 boolean add = true;
394 // 存放交集数据的List
395 List list = arg.getArray();
396 // 遍历传入的Type对象的List
397 for (int i = 0; i < list.size(); i++) {
398 add = true;
399 // 与array里的值一一进行比较,如果有相等的,则从原array中将其删除,如果全都不等,则加入到原array中
400 for (int j = 0; j < array.size(); j++) {
401 if (((Integer) list.get(i)).intValue() == ((Integer) array
402 .get(j)).intValue()) {
403 add = false;
404 // 删除相等的数据
405 array.remove(j);
406 }
407 }
408 if (add) {
409 array.add(list.get(i));
410 }
411 }
412 // 返回新的Type对象
413 return new Type(array);
414 }
415
416 /** *//**
417 * 解析字符串,将数字加入到List中
418 *
419 * @param str
420 * @return
421 */
422 private List createList(String str) {
423 // 将字符串解析成字符串数组A{13,2,1,20,30,50}-->new String[]{13,2,1,20,30,50}
424 String s[] = str.replaceAll(str.substring(0, 1), "").replace("{",
425 "").replace("}", "").split(",");
426 List list = new ArrayList();
427 for (int i = 0; i < s.length; i++) {
428 list.add(new Integer(s[i]));
429 }
430 return list;
431 }
432 }
433
434 /** *//**
435 * 测试程序
436 *
437 * @param args
438 * @throws InvocationTargetException
439 * @throws IllegalAccessException
440 * @throws NoSuchMethodException
441 * @throws IllegalArgumentException
442 * @throws SecurityException
443 */
444 public static void main(String args[]) throws SecurityException,
445 IllegalArgumentException, NoSuchMethodException,
446 IllegalAccessException, InvocationTargetException {
447 EditorStringV2 es = new EditorStringV2("input.txt");
448 Stack s = es.readInput();
449 Stack result = es.displayResult(s);// ((C+B)*A)-B
450
451 List list = ((Type) result.pop()).getArray();
452 System.out.println("操作运算后结果为:");
453 for (int i = 0; i < list.size(); i++)
454 System.out.print(list.get(i) + " ");
455 }
456}
457
----2008年11月26日