`

续上一篇文章,用栈来实现:按照用户输入的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. }
分享到:
评论

相关推荐

    用C++实现BM的字符串模式匹配算法

    本篇文章将深入探讨如何使用C++实现Bad Character Rule(坏字符规则)和Good Suffix Rule(好后缀规则)来优化Boyer-Moore(BM)字符串匹配算法。BM算法以其高效的性能在文本搜索、数据挖掘等多个领域广泛应用。 ...

    Hyperledger Fabric make: *** No rule to make target问题(一)

    Hyperledger Fabric make: *** No rule to make target问题 最近一段时间,改Fabric代码,发现没法编译了!make总是报找不到target! ➜ fabric git:(master) ✗ make configtxgen make: *** No rule to make target ...

    中英文字符串分割算法C++C程序示例

    那么一段长度为N的字符串,按照存储的ASCII码可以表示为一串如下的字符串(不包含[]) "x .. x][x .. x y x .. x][x .. x", 其中 s,e表示当前正在分析的一段子串(0, 下标e-s = 期望的分割长度cut_size) ^ ^ ^ ^ ^ 0...

    模糊蕴含关系的运算方法-最小运算(Mamdani)

    这种运算方法通过取两个模糊集的最小隶属度来计算结果模糊集的隶属度,从而实现从输入模糊集到输出模糊集的转换。 模糊蕴含关系可以理解为“如果A,则B”的形式,其中A和B是模糊集合。在最小运算中,对于任意模糊...

    python实现字符串完美拆分split()的方法

    本文将深入探讨如何利用Python内置的`split()`方法来实现字符串的完美拆分,并通过一个具体示例进行详细讲解。 #### 一、`split()` 方法简介 `split()` 是Python字符串的一个内置方法,用于根据指定的分隔符将字符...

    C++信号的微分积分运算

    例如,我们可以编写一个函数,接收输入信号和差分数作为参数,输出微分结果。对于积分,我们可以创建一个递归或循环结构,逐步累加各个小段的贡献。 在"weijifen.txt"文件中,很可能是包含了某个具体信号的离散值...

    URL rule谷歌浏览器插件

    这款插件的核心功能是提供了一种方式,让用户能够根据预设的规则来重定向、拦截或者修改网页的URL,从而实现特定的浏览体验优化或自动化操作。 在实际应用中,URL rule插件可以有以下几方面的用途: 1. **网址过滤...

    drools从字符串中动态加载规则

    ### Drools从字符串中动态加载规则 在使用Drools规则引擎时,...综上所述,通过从字符串中动态加载规则的方式,我们可以更加灵活高效地管理和使用Drools规则引擎,这对于需要快速迭代业务逻辑的应用场景来说尤为重要。

    探索JUnit4扩展:深入Rule

    Rule的使用非常简单,只需在测试类中声明一个Rule字段,并在需要应用该规则的方法上使用`@Rule`注解。例如,JUnit自带的`ExpectedException` Rule可以帮助我们捕获和验证预期的异常: ```java import org.junit....

    字符串匹配算法之Horspool算法

    在此背景下,Boyer和Moore于1977年提出了一种革命性的字符串匹配算法——Boyer-Moore算法,该算法不仅在理论上具有线性时间复杂度的优势,在实际应用中也展现出极高的效率,尤其是在处理长文本和模式时。随后,R....

    C经典算法之字符串核对

    Boyer-Moore 算法是一种广泛使用的字符串匹配算法,它通过预处理模式串(即被查找的字符串)并利用两个规则(bad character rule 和 good suffix rule)来减少比较次数,从而提高搜索效率。 #### Boyer-Moore 算法...

    skope-rule 说明.docx

    Skope-Rule 模块详解 Skope-Rule 模块是 Python 中的一个重要的机器学习模块,用于处理分类问题,特别是异常检测和规则分类器。下面将对 Skope-Rule 模块进行详细的介绍,包括其原理、算法和应用。 Flash 原理 ...

    字符串匹配算法--BM算法的实现代码

    当模式串中的某个字符与文本串不匹配时,我们可以根据模式串中该字符的位置和文本串中对应位置的字符来确定一个跳跃步长。这个步长通常是文本串中坏字符(即不匹配的字符)在模式串中的索引减去坏字符在文本串中的...

    Rule34-API-Wrapper:异步简化对rule34.xxx API的访问

    Rule34.xxx API包装器 这是一个简单的模块,用于简化异步访问rule34.xxx API的过程 为了帮助机器人开发人员,该包装器根本不使用requests 。 相反,它使用aiohttp。 为了帮助异步编码人员,提供了一个名为Sync的类,...

    运算放大器的设计毕业论文

    运算放大器的设计需要考虑到许多参数,包括增益、电源电压、功耗、带宽、电路面积、噪声、失真、输入输等,需要从设计目标到版图设计的优化路径,严格按照设计程序进行电路仿真并通过版图验证和后仿真。

    Laravel开发-rule-builder

    在Laravel中,验证是通过`Validator`类进行的,它可以接收一个表单请求,并根据预定义的规则检查输入数据的有效性。规则通常是字符串,比如`'required'`、`'email'`或`'numeric'`,也可以是自定义闭包函数。Rule ...

    Design Rule 相关介绍

    Design Rule 相关介绍本篇介绍的design rule只针对CMOS技术。画版图时需要按design rule的要求来操作,所以也就有我们常提到的DRC(design rule check),对设计规则的检测工作。Design rule根据工艺,工厂设备,...

Global site tag (gtag.js) - Google Analytics