`

续上一篇文章,用栈来实现:按照用户输入的rule,经过并、交、差运算后,输出字符串结果。

 
阅读更多

废话不说了,

文件:

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. packagecom.lim.test;
  10. importjava.io.BufferedReader;
  11. importjava.io.FileInputStream;
  12. importjava.io.IOException;
  13. importjava.io.InputStreamReader;
  14. importjava.lang.reflect.InvocationTargetException;
  15. importjava.lang.reflect.Method;
  16. importjava.util.ArrayList;
  17. importjava.util.List;
  18. importjava.util.Stack;
  19. /**
  20. *@authorbzwm
  21. *
  22. */
  23. publicclassEditorStringV2{
  24. //保存住集合A中的数据
  25. privateTypetypeA=null;
  26. //保存住集合B中的数据
  27. privateTypetypeB=null;
  28. //保存住集合C中的数据
  29. privateTypetypeC=null;
  30. privateStackstack=newStack();
  31. publicEditorStringV2(Stringpath){
  32. readFile(path);
  33. }
  34. /**
  35. *读入指定的文件
  36. *
  37. *@parampath
  38. */
  39. privatevoidreadFile(Stringpath){
  40. BufferedReaderreader=null;
  41. try{
  42. reader=newBufferedReader(newInputStreamReader(
  43. newFileInputStream(path)));
  44. Stringstr=null;
  45. //保存已经写好的文件中A,B,C的集合
  46. while((str=reader.readLine())!=null){
  47. //保存集合A
  48. if(str.substring(0,1).equals("A")){
  49. typeA=newType(str);
  50. }
  51. //保存集合B
  52. elseif(str.substring(0,1).equals("B")){
  53. typeB=newType(str);
  54. }
  55. //保存集合C
  56. elseif(str.substring(0,1).equals("C")){
  57. typeC=newType(str);
  58. }else{
  59. System.out.println("nosuchtype!");
  60. return;
  61. }
  62. }
  63. }catch(Exceptione){
  64. e.printStackTrace();
  65. return;
  66. }
  67. }
  68. /**
  69. *处理并、交、差操作,显示结果
  70. *
  71. *@paramrule
  72. *例:C-((C+B)-A)*B
  73. *@throwsInvocationTargetException
  74. *@throwsIllegalAccessException
  75. *@throwsNoSuchMethodException
  76. *@throwsIllegalArgumentException
  77. *@throwsSecurityException
  78. */
  79. publicStackdisplayResult(StackorgStack)throwsSecurityException,
  80. IllegalArgumentException,NoSuchMethodException,
  81. IllegalAccessException,InvocationTargetException{
  82. //左括号"("的计数器
  83. intleftBracket=0;
  84. //是否存在操作符标志符
  85. booleanhasOpe=false;
  86. //输入的rule的长度
  87. intlength=orgStack.size();
  88. Objectobj=null;
  89. if(length<3){
  90. System.out.println("inputruleisillegal.");
  91. returnnull;
  92. }else{
  93. for(inti=0;i<length;i++){
  94. //截取rule的每个字符
  95. obj=orgStack.pop();
  96. //如果是左括号,则leftBracket加1
  97. if(isLeftBracket(obj)){
  98. leftBracket+=1;
  99. stack.push(obj);
  100. continue;
  101. }
  102. //如果是操作符,则将操作符标志符置为true
  103. if(isOperator(obj)){
  104. hasOpe=true;
  105. stack.push(obj);
  106. continue;
  107. }
  108. //如果不是左括号和操作符则入栈
  109. stack.push(obj);
  110. //如果左括号存在,且本次字符为右括号
  111. if(leftBracket>0&&isRightBracket(obj)){
  112. //将右括号弹出栈
  113. stack.pop();
  114. //将形如typeA.bing(typeB)的方法调用的参数标志弹出
  115. Typearg=(Type)stack.pop();
  116. //将形如typeA.bing(typeB)的方法调用的操作符标志弹出:+/bing*/jiao-/cha
  117. Stringope=stack.pop().toString();
  118. //将形如typeA.bing(typeB)的方法调用的主调对象标志弹出
  119. TypeinvokeObj=(Type)stack.pop();
  120. //通过对象工厂,构造出Type对象,进行并、交、差操作,返回得到的新Type对象
  121. TypetypeTmp=execute(invokeObj,ope,arg);
  122. //将左括号弹出栈
  123. stack.pop();
  124. //左括号计数器减1
  125. leftBracket-=1;
  126. //栈中加入临时的Type对象标志T,T代表本次操作后得到的新集合
  127. stack.push(typeTmp);
  128. //当栈中还有运算时,进行递归
  129. if(stack.size()>2){
  130. StacktmpStack=newStack();
  131. while(stack.size()>0){
  132. tmpStack.push(stack.pop());
  133. }
  134. stack=displayResult(tmpStack);
  135. }
  136. continue;
  137. }
  138. //如果1.栈中还没有左括号2.栈有操作符3.本次字符是集合标志A、B、C
  139. //则进行并、交、差操作
  140. if(leftBracket==0&&hasOpe&&isType(obj)){
  141. //将形如typeA.bing(typeB)的方法调用的参数标志弹出
  142. Typearg=(Type)stack.pop();
  143. //将形如typeA.bing(typeB)的方法调用的操作符标志弹出:+/bing*/jiao-/cha
  144. Stringope=stack.pop().toString();
  145. //将形如typeA.bing(typeB)的方法调用的主调对象标志弹出
  146. TypeinvokeObj=(Type)stack.pop();
  147. //通过对象工厂,构造出Type对象,进行并、交、差操作,返回得到的新Type对象
  148. TypetypeTmp=execute(invokeObj,ope,arg);
  149. //栈中加入临时的Type对象标志T,T代表本次操作后得到的新集合
  150. stack.push(typeTmp);
  151. //将操作符标志符置为false
  152. hasOpe=false;
  153. //当栈中还有运算时,进行递归
  154. if(stack.size()>2){
  155. StacktmpStack=newStack();
  156. while(stack.size()>0){
  157. tmpStack.push(stack.pop());
  158. }
  159. stack=displayResult(tmpStack);
  160. }
  161. continue;
  162. }
  163. }
  164. //循环结束,得到最后结果
  165. returnstack;
  166. }
  167. }
  168. /**
  169. *判断对象o是否为Type的实例
  170. *
  171. *@paramo
  172. *@return
  173. */
  174. privatebooleanisType(Objecto){
  175. returnoinstanceofType;
  176. }
  177. /**
  178. *判断对象o是否为操作符*,+,-
  179. *
  180. *@paramo
  181. *@return
  182. */
  183. privatebooleanisOperator(Objecto){
  184. return!isType(o)&&((String)o).matches("[+//*-]");
  185. }
  186. /**
  187. *判断对象o是否左括号"("
  188. *
  189. *@paramo
  190. *@return
  191. */
  192. privatebooleanisLeftBracket(Objecto){
  193. return!isType(o)&&((String)o).equals("(");
  194. }
  195. /**
  196. *判断对象o是否右括号")"
  197. *
  198. *@paramo
  199. *@return
  200. */
  201. privatebooleanisRightBracket(Objecto){
  202. return!isType(o)&&((String)o).equals(")");
  203. }
  204. /**
  205. *利用反射机制,根据ope的不同,调用不同的方法
  206. *
  207. *@paramobj
  208. *@paramarg
  209. *@paramope
  210. *@return
  211. *@throwsSecurityException
  212. *@throwsNoSuchMethodException
  213. *@throwsIllegalArgumentException
  214. *@throwsIllegalAccessException
  215. *@throwsInvocationTargetException
  216. */
  217. privateTypeexecute(Typeobj,Stringope,Typearg)
  218. throwsSecurityException,NoSuchMethodException,
  219. IllegalArgumentException,IllegalAccessException,
  220. InvocationTargetException{
  221. Classc=obj.getClass();
  222. Class[]args=newClass[1];
  223. args[0]=arg.getClass();
  224. Methodm=null;
  225. //如果操作符为"+",则执行bing方法
  226. if(ope.equals("+")){
  227. m=c.getMethod("bing",args);
  228. }
  229. //如果操作符为"*",则执行jiao方法
  230. elseif(ope.equals("*")){
  231. m=c.getMethod("jiao",args);
  232. }
  233. //如果操作符为"-",则执行cha方法
  234. elseif(ope.equals("-")){
  235. m=c.getMethod("cha",args);
  236. }else{
  237. System.out.println("NoSuchMethod");
  238. returnnull;
  239. }
  240. return(Type)m.invoke(obj,newObject[]{arg});
  241. }
  242. /**
  243. *读入用户输入的匹配规则如:((C+B)*A)-B
  244. *
  245. *@return
  246. */
  247. privateStackreadInput(){
  248. Stackret=newStack();
  249. Stringstr=null;
  250. Stringo=null;
  251. BufferedReaderbr=newBufferedReader(newInputStreamReader(System.in));
  252. try{
  253. str=br.readLine();
  254. }catch(IOExceptione){
  255. e.printStackTrace();
  256. returnnull;
  257. }
  258. for(inti=str.length();i>0;i--){
  259. o=str.substring(i-1,i);
  260. //当遇到A,B,C时,生成Type对象存入栈中
  261. if(o.matches("[ABC]")){
  262. ret.push(typeFactory(o));
  263. continue;
  264. }
  265. ret.push(o);
  266. }
  267. returnret;
  268. }
  269. /**
  270. *构造工厂根据传入的type构造Type对象保存住原集合
  271. *
  272. *@paramtype
  273. *@return
  274. */
  275. privateTypetypeFactory(Stringtype){
  276. if(type.equals("A")){
  277. returnnewType(typeA.getArray());
  278. }elseif(type.equals("B")){
  279. returnnewType(typeB.getArray());
  280. }elseif(type.equals("C")){
  281. returnnewType(typeC.getArray());
  282. }else{
  283. returnnull;
  284. }
  285. }
  286. /**
  287. *把如{13,2,1,20,30,50}的集合抽象成一个类,提供并、交、差操作
  288. *
  289. *@authorbzwm
  290. *
  291. */
  292. classType{
  293. //保存数据集合的List
  294. privateListarray=newArrayList();
  295. publicType(Stringsrt){
  296. this.array=createList(srt);
  297. }
  298. publicType(Listlist){
  299. this.array.addAll(list);
  300. }
  301. publicListgetArray(){
  302. returnthis.array;
  303. }
  304. /**
  305. *并操作
  306. *
  307. *@paramarg
  308. *@return
  309. */
  310. publicTypebing(Typearg){
  311. //是否加入到集合中的标志
  312. booleanadd=true;
  313. //取出传入的Type对象的List
  314. Listlist=arg.getArray();
  315. //遍历传入的Type对象的List
  316. for(inti=0;i<list.size();i++){
  317. add=true;
  318. //与array里的值一一进行比较,如果全都不等,则加入到原array中,否则不加入
  319. for(intj=0;j<array.size();j++){
  320. if(((Integer)list.get(i)).intValue()==((Integer)array
  321. .get(j)).intValue()){
  322. add=false;
  323. }
  324. }
  325. if(add){
  326. array.add(list.get(i));
  327. }
  328. }
  329. //返回新的Type对象
  330. returnnewType(array);
  331. }
  332. /**
  333. *交操作
  334. *
  335. *@paramarg
  336. *@return
  337. */
  338. publicTypejiao(Typearg){
  339. //是否加入到集合中的标志
  340. booleanadd=false;
  341. //存放交集数据的List
  342. Listret=newArrayList();
  343. //取出传入的Type对象的List
  344. Listlist=arg.getArray();
  345. //遍历传入的Type对象的List
  346. for(inti=0;i<list.size();i++){
  347. add=false;
  348. //与array里的值一一进行比较,如果有相等的,则加入到ret中,否则不加入
  349. for(intj=0;j<array.size();j++){
  350. if(((Integer)list.get(i)).intValue()==((Integer)array
  351. .get(j)).intValue()){
  352. add=true;
  353. }
  354. }
  355. if(add){
  356. ret.add(list.get(i));
  357. }
  358. }
  359. //返回新的Type对象
  360. returnnewType(ret);
  361. }
  362. /**
  363. *差操作
  364. *
  365. *@paramarg
  366. *@return
  367. */
  368. publicTypecha(Typearg){
  369. //是否加入到集合中的标志
  370. booleanadd=true;
  371. //存放交集数据的List
  372. Listlist=arg.getArray();
  373. //遍历传入的Type对象的List
  374. for(inti=0;i<list.size();i++){
  375. add=true;
  376. //与array里的值一一进行比较,如果有相等的,则从原array中将其删除,如果全都不等,则加入到原array中
  377. for(intj=0;j<array.size();j++){
  378. if(((Integer)list.get(i)).intValue()==((Integer)array
  379. .get(j)).intValue()){
  380. add=false;
  381. //删除相等的数据
  382. array.remove(j);
  383. }
  384. }
  385. if(add){
  386. array.add(list.get(i));
  387. }
  388. }
  389. //返回新的Type对象
  390. returnnewType(array);
  391. }
  392. /**
  393. *解析字符串,将数字加入到List中
  394. *
  395. *@paramstr
  396. *@return
  397. */
  398. privateListcreateList(Stringstr){
  399. //将字符串解析成字符串数组A{13,2,1,20,30,50}-->newString[]{13,2,1,20,30,50}
  400. Strings[]=str.replaceAll(str.substring(0,1),"").replace("{",
  401. "").replace("}","").split(",");
  402. Listlist=newArrayList();
  403. for(inti=0;i<s.length;i++){
  404. list.add(newInteger(s[i]));
  405. }
  406. returnlist;
  407. }
  408. }
  409. /**
  410. *测试程序
  411. *
  412. *@paramargs
  413. *@throwsInvocationTargetException
  414. *@throwsIllegalAccessException
  415. *@throwsNoSuchMethodException
  416. *@throwsIllegalArgumentException
  417. *@throwsSecurityException
  418. */
  419. publicstaticvoidmain(Stringargs[])throwsSecurityException,
  420. IllegalArgumentException,NoSuchMethodException,
  421. IllegalAccessException,InvocationTargetException{
  422. EditorStringV2es=newEditorStringV2("input.txt");
  423. Stacks=es.readInput();
  424. Stackresult=es.displayResult(s);//((C+B)*A)-B
  425. Listlist=((Type)result.pop()).getArray();
  426. System.out.println("操作运算后结果为:");
  427. for(inti=0;i<list.size();i++)
  428. System.out.print(list.get(i)+"");
  429. }
  430. }
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics