Project 1题目要求分析:

实现多项式的加减运算,主要问题是解决输入格式的判断问题。

输入实例:

{(3,0), (2,2), (12,3)} + {(3,1), (-5,3)} – {(-199,2), (29,3),(10,7)}

{}表示多项式,其中的小括号第一个参数是系数,第二个是指数。同一个多项式指数要求不同。

程序实现的重点总结

1.去除空白字符

s = s.replaceAll("\\s*", "");

2.初步判断合法性(有有效输入字符且没有中文)

Pattern p = Pattern.compile("[\u4e00-\u9fa5]+"); //匹配中文字符
Matcher m = p.matcher(s);
if (s.trim().isEmpty()) { //判断是不是空串,或者字符串只由空白字符组成。trim方法去除字符串前后的空白字符
System.out.println("ERROR");
System.out.println("#The string is empty!");
}
else if(m.find()){
System.out.println("ERROR");
System.out.println("#The string has Chinese character!");
}

3.多项式格式检查

public static boolean CheckSyntax(String s){
String str;
if(s.charAt(0) != '-' && s.charAt(0) != '+'){
str = '+' + s;
}
else{
str = s;
} //如果第一个多项式前面没有符号,添加+,以方便匹配
Pattern p1 = Pattern.compile("([+-]\\{[^\\}]+}){0,20}");
Matcher m1 = p1.matcher(str);
boolean flag = m1.matches(); //先进行整体检查(逻辑清晰,且不会爆栈),匹配整体是否为+{...}-{...}格式,match方法要完全匹配才返回true
if(flag){
Pattern p2 = Pattern.compile("(\\{[^\\}]+})");
Matcher m2 = p2.matcher(str); //外部多项式大括号匹配成功,再进一步看大括号里面的是否符合格式
Pattern p3 = Pattern.compile("\\{\\([+-]?\\d{1,6},([+]?\\d{1,6}|-0{1,6})\\)(,\\([+-]?\\d{1,6},([+]?\\d{1,6}|-0{1,6})\\)){0,49}\\}");
while(m2.find()){ //匹配大括号里面的(c, n),(c,n)...
Matcher m3 = p3.matcher(m2.group(1));
if(m3.matches() == false){
return false;
}
}
return true;
}
else{
return false;
}
}

注意:

正则表达式的具体含义请参考后面的博客

不支持空多项式,{}会被报错。

3.字符串中数字的提取以及符号的提取

因为前面已经做过格式检查,如果格式是对的,只要非贪婪式匹配(...,就能提取系数,匹配,...)就能提取指数。(?表示非贪婪匹配)

同理,匹配{前面的字符就能得到运算符

正则表达式的提取数字过程如下:

Pattern p = Pattern.compile("(?<=\\{)(.*?)(?=\\})");
Matcher matcher = p.matcher(s);
while(matcher.find()){
list.add(matcher.group());
} //提取每个{}多项式里面的内容并放进list容器里面
Pattern p1 = Pattern.compile("(?<=\\()([\\+|\\-]?[0-9]*?)(?=\\,)");
Matcher m1 = p1.matcher(str); //匹配系数
Pattern p2 = Pattern.compile("(?<=\\,)([\\+|\\-]?[0-9]*?)(?=\\))");
Matcher m2 = p2.matcher(str); //匹配指数

将字符串转化为数字:

int c = Integer.parseInt(m1.group());
int d = Integer.parseInt(m2.group());

注意,当parseInt方法不能转化字符换为整数的时候会抛出异常,最好使用try+catch方法对异常进行捕捉,以方便debug和避免程序的crash。

附:异常处理

异常处理的具体方法见后面的博客总结。

try{
... ...
}catch(IOException e){
//处理IO异常的代码
}catch(NumberFormatException e){
//处理parseInt不能转换时的异常代码
}catch(StringIndexOutOfBoundsException e){
//处理数组越界的异常代码
}catch(Exception e) {
//总异常(父类)
}

正则表达式匹配运算符:

Pattern p = Pattern.compile("([\\+|\\-])(?=\\{)");
Matcher matcher = p.matcher(str);

当然,也可以使用split方法提取,会更加简洁。

抽到的测试程序

第一次抽到同学的代码整体写的不错,除了正则表达式爆栈了有点小遗憾。里面有很多值得学习的地方。

1.程序的结束与退出

System.exit(0); //程序结束,相当于C语言的return 0;正常结束时程序exitcode == 0。
System是一个Java类,调用exit(0)方法终止虚拟机也就是退出你的Java程序,括号里面的是参数,进程结束的返回值。

2.正则表达式太长,在数据压力大的时候可能会爆栈

public void formatCheck() {//正则表达式匹配格式
String regex = "[+-]{0,1}\\{{1}\\({1}[+-]{0,1}[0-9]{1,6},{1}((\\+{0,1}[0-9]{1,6})|(-{1}0{1,6}))\\){1}(,{1}\\({1}[+-]{0,1}[0-9]{1,6},{1}((\\+{0,1}[0-9]{1,6})|(-{1}0{1,6}))\\){1}){0,}\\}{1}([+-]{1}\\{{1}\\({1}[+-]{0,1}[0-9]{1,6},{1}((\\+{0,1}[0-9]{1,6})|(-{1}0{1,6}))\\){1}(,{1}\\({1}[+-]{0,1}[0-9]{1,6},{1}((\\+{0,1}[0-9]{1,6})|(-{1}0{1,6}))\\){1}){0,}\\}{1}){0,}";
Pattern p = Pattern.compile(regex);
Matcher m = p.matcher(input);
if(m.matches() == false && input.length() != 0) {
System.out.println("ERROR");
System.out.println("#输入格式错误");
System.exit(0);
}
}

oo_project_1的更多相关文章

随机推荐

  1. securecrt(CRT)导入会话

    securecrt是个非常流行的远程管理维护工具,支持fssh.ssh2.telnet等多种协议,也支持中文.设备管理多了,自行手工添加也是很累的活.偷下懒,从别人那复制下文件,倒入到自己的secur ...

  2. vue-router 路由元信息 终于搞明白了路由元信息是个啥了

    vue-router 路由元信息:https://blog.csdn.net/wenyun_kang/article/details/70987840 终于搞明白了路由元信息是个啥了:https:// ...

  3. 细聊Spring Cloud Bus

    细聊Spring Cloud Bus Spring 事件驱动模型 因为Spring Cloud Bus的运行机制也是Spring事件驱动模型所以需要先了解相关知识点: 上面图中是Spring事件驱动模 ...

  4. python小学堂1

    sun=0 start=1 while True: start1=start%2 if start1==1: sun = start + sun elif start1==0: sun=sun-sta ...

  5. DevExpress Winform使用单例运行程序方法和非DevExpress使用Mutex实现程序单实例运行且运行则激活窗体的方法

    原文:DevExpress Winform使用单例运行程序方法和非DevExpress使用Mutex实现程序单实例运行且运行则激活窗体的方法 版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA ...

  6. Vue / keep-alive使用

    keep-alive keep-alive是Vue提供的一个抽象组件,用来对组件进行缓存,从而节省性能,由于是一个抽象组件,所以在v页面渲染完毕后不会被渲染成一个DOM元素 <keep-aliv ...

  7. IDEA中添加自定义的方法快捷方式

    IDEA中快速添加自己自定义的方法方法,想要什么快捷方法都行 作为一个从MyEclipse转IDEA的程序员,原来写main就能补全main方法,写syso就能补全System.out.println ...

  8. 1.报表TIBCO Jaspersoft Studio工具教程入门--生成jrxml和jasper文件 然后拖拽到项目中 跟ireport一样

    转自:https://blog.csdn.net/KingSea168/article/details/42553781 2. 在接下来的教程中,我们将实现一个简单的JasperReports示例,展 ...

  9. 【知识强化】第三章 存储系统 3.4 主存储器与CPU的连接

    我们这节课来看一下关于主存的一些知识.我们将要讲解主存的简单的模型和主存与CPU连接的连接原理. 我们之前呢在第一章已经学过了存储器的构成,包括了存储体.MAR(也就是地址寄存器).MDR(也就是数据 ...

  10. 创建工程时出现 A project with this name already exists 提示

    https://segmentfault.com/a/1190000018513060 创建项目时没注意,后来发现放错了位置或其他问题,想要重新创建同名项目,只在文件夹处删除是不行的.会出现以下提示 ...