废话不说了,
文件:
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
*/
9
package com.lim.test;
10
11
import java.io.BufferedReader;
12
import java.io.FileInputStream;
13
import java.io.IOException;
14
import java.io.InputStreamReader;
15
import java.lang.reflect.InvocationTargetException;
16
import java.lang.reflect.Method;
17
import java.util.ArrayList;
18
import java.util.List;
19
import java.util.Stack;
20
21
/** *//**
22
* @author bzwm
23
*
24
*/
25
public 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日