廢話不說了,
文件:
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

2

3

4

5

6

7


8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

188

189

190

191

192

193

194

195

196

197

198

199

200

201

202

203

204

205

206

207

208

209

210

211

212

213

214

215

216

217

218

219

220

221

222

223

224

225

226

227

228

229

230

231

232

233

234

235

236

237

238

239

240

241

242

243

244

245

246

247

248

249

250

251

252

253

254

255

256

257

258

259

260

261

262

263

264

265

266

267

268

269

270

271

272

273

274

275

276

277

278

279

280

281

282

283

284

285

286

287

288

289

290

291

292

293

294

295

296

297

298

299

300

301

302

303

304

305

306

307

308

309

310

311

312

313

314

315

316

317

318

319

320

321

322

323

324

325

326

327

328

329

330

331

332

333

334

335

336

337

338

339

340

341

342

343

344

345

346

347

348

349

350

351

352

353

354

355

356

357

358

359

360

361

362

363

364

365

366

367

368

369

370

371

372

373

374

375

376

377

378

379

380

381

382

383

384

385

386

387

388

389

390

391

392

393

394

395

396

397

398

399

400

401

402

403

404

405

406

407

408

409

410

411

412

413

414

415

416

417

418

419

420

421

422

423

424

425

426

427

428

429

430

431

432

433

434

435

436

437

438

439

440

441

442

443

444

445

446

447

448

449

450

451

452

453

454

455

456

457

----2008年11月26日