实现多项式相加或相减
我的多项式相加或相减算法Java实现。
实现多项式相加或相减(Poly1-Ploy2 或 Poly2-Poly1):符合逻辑是输入方式实现。
教师要求:多项式加法(任意输入两个多项式,实现其加减,多项式的幂次不定)。要求:选用合适的数据结构,实现算法,并将结果输出。
此程序用了一个界面来进行操作,截图如下:
程序如下:
View Code
1 /* 2 * fuction:实现多项式相加或相减(Poly1-Ploy2 或 Poly2-Poly1):符合逻辑是输入方式实现 3 * 教师要求:多项式加法(任意输入两个多项式,实现其加减,多项式的幂次不定)。要求:选用合适的数据结构,实现算法,并将结果输出。 4 * author:iGeneral 5 * date:2013.04.22 6 * 7 * idea:分别取出每一个项,再从项中取出系数和幂,添加到链表中 8 * 9 * expe: 10 * 1.String s="+55"; 11 int a=Integer.parseInt(s); 12 System.out.println(a); 13 2.String s="3x^3+2x^2+x^1-4"; 14 int point=s.indexOf('x', 0); 15 System.out.println(point); 16 System.out.println(s.charAt(point)); 17 3.String s="igmhqukq"; 18 System.out.println(s.substring(0, 8)); 19 succeed! 20 4.String s="111"; 21 System.out.println(s.length());==3 22 5.String s="iGeneral"; 23 System.out.println(s.substring(0,0));=="" 24 25 * caution: 26 * 1.系数可或幂能是一个需要运算的表达式 27 * 2.常数项的位置:最前/中间/最后 28 * 3.一次项中没有符号'^',常数项中没有符号'x' & '^' 29 * 4.多项式结束 30 * 5.可能存在多个同幂的项 31 * 6.实现排除错误输入 32 * 7.判断多项式是否为空 33 * 8.可能多项式只有一项,而且是常数项-----特殊处理 34 * 9.运算结果格式化:去掉式子中的"+0"/"-0",运算结果有一项时将可能存在的 "+0"->"0" 35 */ 36 package part03.chapter10; 37 38 import java.awt.Button; 39 import java.awt.GridLayout; 40 import java.awt.event.ActionEvent; 41 import java.awt.event.ActionListener; 42 import java.awt.event.KeyEvent; 43 import java.awt.event.KeyListener; 44 import java.awt.image.BufferedImage; 45 import java.io.IOException; 46 47 import javax.imageio.ImageIO; 48 import javax.swing.JFrame; 49 import javax.swing.JLabel; 50 import javax.swing.JPanel; 51 import javax.swing.JTextField; 52 53 public class _1exercise2 extends JFrame implements ActionListener, KeyListener { 54 55 // 定义组件 56 // 第一个多项式需要的组件 57 JLabel name_poly1; 58 JTextField contents_poly1; 59 Button clear_poly1; 60 JPanel panel_poly1; 61 // 第二个多项式需要的组件 62 JLabel name_poly2; 63 JTextField contents_poly2; 64 Button clear_poly2; 65 JPanel panel_poly2; 66 // 对多项式进行操作需要的组件 67 Button addBtn; 68 Button one_twoBtn; 69 Button two_oneBtn; 70 JPanel panel_manager; 71 // 显示结果需要的组件 72 JLabel result_name; 73 JTextField result_contents; 74 JPanel panel_result; 75 76 // 重写构造函数:初始化界面和组件 77 public _1exercise2() { 78 // 对第一个多项式的组件进行初始化 79 name_poly1 = new JLabel(); 80 name_poly1.setText("PolyOne = "); 81 contents_poly1 = new JTextField("1-2x+3x^2+4x^3+5x^4", 20); 82 contents_poly1.setEditable(true); 83 clear_poly1 = new Button("clear"); 84 panel_poly1 = new JPanel(); 85 panel_poly1.add(name_poly1); 86 panel_poly1.add(contents_poly1); 87 panel_poly1.add(clear_poly1); 88 // 对 clear_poly1 注册监听 89 clear_poly1.addActionListener(this); 90 clear_poly1.setActionCommand("clear_poly1"); 91 // 对 contents_poly1 注册监听 92 contents_poly1.addKeyListener(this); 93 // 对第二个多项式的组件进行初始化 94 name_poly2 = new JLabel(); 95 name_poly2.setText(" PolyTwo = "); 96 contents_poly2 = new JTextField("1+2x+3x^2", 20); 97 contents_poly2.setEditable(true); 98 clear_poly2 = new Button("clear"); 99 panel_poly2 = new JPanel(); 100 panel_poly2.add(name_poly2); 101 panel_poly2.add(contents_poly2); 102 panel_poly2.add(clear_poly2); 103 // 对 clear_poly2 注册监听 104 clear_poly2.addActionListener(this); 105 clear_poly2.setActionCommand("clear_poly2"); 106 // 对 contents_poly2 注册监听 107 contents_poly2.addKeyListener(this); 108 // 对操作的组件进行初始化 109 addBtn = new Button("PolyOne + PolyOne"); 110 one_twoBtn = new Button("PolyOne - PolyOne"); 111 two_oneBtn = new Button("PolyTwo - PolyOne"); 112 panel_manager = new JPanel(); 113 panel_manager.add(addBtn); 114 panel_manager.add(one_twoBtn); 115 panel_manager.add(two_oneBtn); 116 // 注册监听 117 addBtn.addActionListener(this); 118 addBtn.setActionCommand("addBtn"); 119 one_twoBtn.addActionListener(this); 120 one_twoBtn.setActionCommand("one_twoBtn"); 121 two_oneBtn.addActionListener(this); 122 two_oneBtn.setActionCommand("two_oneBtn"); 123 // 对显示结果的组件进行初始化 124 result_name = new JLabel(); 125 result_name.setText("result = "); 126 result_contents = new JTextField(20); 127 result_contents.setEditable(false); 128 panel_result = new JPanel(); 129 panel_result.add(result_name); 130 panel_result.add(result_contents); 131 // 对窗体进行设置 132 this.setLayout(new GridLayout(4, 1)); 133 this.add(panel_poly1); 134 this.add(panel_poly2); 135 this.add(panel_manager); 136 this.add(panel_result); 137 this.setTitle("两个多项式的加减运算"); 138 BufferedImage image = null; 139 try { 140 image = ImageIO.read(this.getClass().getResource("/colors.png")); 141 } catch (IOException e) { 142 e.printStackTrace(); 143 } finally { 144 145 } 146 this.setIconImage(image); 147 this.setSize(400, 300); 148 this.setLocation(300, 100); 149 this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 150 this.setVisible(true); 151 } 152 153 public static void main(String[] args) { 154 _1exercise2 computingTowPolys = new _1exercise2(); 155 } 156 157 // 判断多项式是否为空 158 public boolean isNull() { 159 160 if (contents_poly1.getText().equals("") 161 && contents_poly2.getText().equals("")) { 162 result_name.setText("result = "); 163 result_contents.setText("多项式不能为空!"); 164 return true; 165 } 166 if (contents_poly1.getText().equals("")) { 167 result_name.setText("result = "); 168 result_contents.setText("多项式 PolyOne 不能为空!"); 169 return true; 170 } 171 if (contents_poly2.getText().equals("")) { 172 result_name.setText("result = "); 173 result_contents.setText("多项式 PolyTwo 不能为空!"); 174 return true; 175 } 176 return false; 177 } 178 179 @Override 180 public void actionPerformed(ActionEvent e) { 181 // TODO Auto-generated method stub 182 SumTowPolynomial sumTowPolynomial = new SumTowPolynomial(); 183 // 存放运算结构 184 String result = ""; 185 String poly1 = contents_poly1.getText().toString(); 186 String poly2 = contents_poly2.getText().toString(); 187 // if(e.getActionCommand().equals("addBtn")){ 188 // if (!isNull()) { 189 // result = sumTowPolynomial.sum(poly1, poly2, '+'); 190 // result_contents.setText(result); 191 // result_name.setText(addBtn.getLabel().toString() + " = "); 192 // } 193 // } 194 switch (e.getActionCommand()) { 195 196 case "addBtn": 197 if (!isNull()) { 198 result = sumTowPolynomial.sum(poly1, poly2, '+'); 199 result_contents.setText(result); 200 result_name.setText(addBtn.getLabel().toString() + " = "); 201 } 202 break; 203 case "one_twoBtn": 204 if (!isNull()) { 205 result = sumTowPolynomial.sum(poly1, poly2, '-'); 206 result_contents.setText(result); 207 result_name.setText(one_twoBtn.getLabel().toString() + " = "); 208 } 209 break; 210 case "two_oneBtn": 211 if (!isNull()) { 212 result = sumTowPolynomial.sum(poly2, poly1, '-'); 213 result_contents.setText(result); 214 result_name.setText(two_oneBtn.getLabel().toString() + " = "); 215 } 216 break; 217 case "clear_poly1": 218 contents_poly1.setText(""); 219 break; 220 case "clear_poly2": 221 contents_poly2.setText(""); 222 break; 223 default: 224 break; 225 } 226 } 227 228 @Override 229 public void keyPressed(KeyEvent e) { 230 // TODO Auto-generated method stub 231 } 232 233 @Override 234 public void keyReleased(KeyEvent e) { 235 // TODO Auto-generated method stub 236 switch (e.getKeyCode()) { 237 case KeyEvent.VK_0: 238 case KeyEvent.VK_1: 239 case KeyEvent.VK_2: 240 case KeyEvent.VK_3: 241 case KeyEvent.VK_4: 242 case KeyEvent.VK_5: 243 case KeyEvent.VK_6: 244 case KeyEvent.VK_7: 245 case KeyEvent.VK_8: 246 case KeyEvent.VK_9: 247 case KeyEvent.VK_X: 248 case KeyEvent.VK_BACK_SPACE: 249 case KeyEvent.VK_SHIFT: 250 case KeyEvent.VK_EQUALS:// '=' 251 case KeyEvent.VK_MINUS:// '-' 252 // case KeyEvent.VK_LEFT_PARENTHESIS:// '(' 253 // case KeyEvent.VK_RIGHT_PARENTHESIS:// ')' 254 case KeyEvent.VK_CONTROL: 255 case KeyEvent.VK_ENTER: 256 case KeyEvent.VK_COPY: 257 case KeyEvent.VK_CUT: 258 case KeyEvent.VK_PASTE: 259 case KeyEvent.VK_HOME: 260 case KeyEvent.VK_END: 261 case KeyEvent.VK_LEFT: 262 case KeyEvent.VK_RIGHT: 263 case KeyEvent.VK_PERIOD:// '.' 264 265 break; 266 267 default: 268 if (this.getFocusOwner() == contents_poly1) { 269 contents_poly1 270 .setText(contents_poly1 271 .getText() 272 .toString() 273 .substring( 274 0, 275 contents_poly1.getText().toString() 276 .length() - 1)); 277 } 278 if (this.getFocusOwner() == contents_poly2) { 279 contents_poly2 280 .setText(contents_poly2 281 .getText() 282 .toString() 283 .substring( 284 0, 285 contents_poly2.getText().toString() 286 .length() - 1)); 287 } 288 result_contents.setText("请输入数字,'+','_','x','^'!"); 289 break; 290 } 291 } 292 293 @Override 294 public void keyTyped(KeyEvent e) { 295 // TODO Auto-generated method stub 296 297 } 298 299 } 300 301 // 多项式的项--类 302 class Term { 303 // 系数 304 int coefficient = 0; 305 // 幂 306 int power = 0; 307 // 下一个Term的指针 308 Term next = null; 309 310 // 重写构造函数:初始化 311 public Term(int coefficient, int power) { 312 this.coefficient = coefficient; 313 this.power = power; 314 } 315 } 316 317 // 多项式--类 318 class SumTowPolynomial { 319 320 // 格式化多项式成链表形式:使容易处理 321 public Term formatPolynomial(String polynomial) { 322 // 创建两个指针,用来构建链表 323 // 多项式链表头指针(是多项式的第一项) 324 Term head = new Term(0, 0); 325 // 多项式链表当前指针(是多项式的当前项) 326 Term point = new Term(0, 0); 327 // 当前项的系数 328 int coefficient = 0; 329 // 当前项的幂 330 int power = 0; 331 // 多项式的长度 332 int polynomualLenth = polynomial.length(); 333 // 定义两个下标,来标志多项是中某一项的开始下标和结束下标 334 int firstIndex = 0; 335 int laterIndex = 0; 336 // 定义两个下标,用来标识多项式中某个系数或幂在字符串中的开始下标和结束下标 337 // 开始下标 338 int beginIndex = 0; 339 // 结束下标 340 int endIndex = 0; 341 // 如果多项式只有一项常数项-----特殊情况特殊处理 342 if (polynomial.indexOf('+', 1) == -1 343 && polynomial.indexOf('-', 1) == -1 344 && polynomial.indexOf('x', 1) == -1) { 345 head.coefficient = Integer.parseInt(polynomial); 346 head.power = 0; 347 return head; 348 } 349 // 循环取出多项式中的每一项,再从项中取出其系数和幂,添加到链表中 350 // 当前项的字符串表示 351 String currentTerm = ""; 352 for (int i = 1; i < polynomualLenth; i++) {// i 从 1 开始-------- 353 // 遇到 '+' / '-' / "i == polynomualLenth-1---最后一项的结束标识" 表示某一项的结束标识 354 if (polynomial.charAt(i) == '+' 355 || (polynomial.charAt(i) == '-' && polynomial.charAt(i - 1) != '^') 356 || i == (polynomualLenth - 1)) { 357 if (i != (polynomualLenth - 1)) { 358 laterIndex = i; 359 } else { 360 laterIndex = i + 1; 361 } 362 // 获取某一项 363 currentTerm = polynomial.substring(firstIndex, laterIndex); 364 firstIndex = i; 365 // 判断该项是常数项还是非常数项:不同情况不同处理方案----------注意 366 endIndex = currentTerm.indexOf('x'); 367 // 该项为非常数项(非常数项包括一次项和多次项)的处理方案 368 if (endIndex != -1) { 369 beginIndex = 0; 370 // 取出系数 371 // 系数可能为 1 ,存在情况有:-x;+x;+x^2;-x^2;第一项的情况:x; 372 if (currentTerm.substring(beginIndex, endIndex).equals("+") 373 || currentTerm.substring(beginIndex, endIndex) 374 .equals("-") 375 || currentTerm.substring(beginIndex, endIndex) 376 .equals("")) { 377 coefficient = 1; 378 } else { 379 coefficient = Integer.parseInt(currentTerm.substring( 380 beginIndex, endIndex)); 381 } 382 // 取出幂 383 // 如果该项为多次项 384 if (currentTerm.indexOf('^') != -1) { 385 beginIndex = endIndex + 2; 386 endIndex = currentTerm.length(); 387 power = Integer.parseInt(currentTerm.substring( 388 beginIndex, endIndex)); 389 } else {// 如果该项为一次项 390 power = 1; 391 } 392 // 该项为常数项的处理方案 393 } else { 394 coefficient = Integer.parseInt(currentTerm); 395 power = 0; 396 } 397 // 将该项的系数和幂添加到链表中 398 Term term = new Term(coefficient, power); 399 if (head.coefficient != 0) { 400 point.next = term; 401 point = term; 402 } else { 403 head = term; 404 point = head; 405 } 406 } 407 } 408 return head; 409 } 410 411 // 对多项式的幂按非降序排序:冒泡排序 412 public Term sortPolynomial(Term head) { 413 Term point = head; 414 // 计算出链表的长度 415 int linkLength = 0; 416 while (point != null) { 417 linkLength++; 418 point = point.next; 419 } 420 // 重置 point,使其指向链表头 head 421 point = head; 422 // 用于数据的临时变量 423 int temp = 0; 424 for (int i = 0; i < (linkLength - 1); i++) { 425 for (int j = 0; j < linkLength - i - 1; j++, point = point.next) { 426 if (point.power > point.next.power) { 427 // 交换系数 428 temp = point.coefficient; 429 point.coefficient = point.next.coefficient; 430 point.next.coefficient = temp; 431 // 交换幂 432 temp = point.power; 433 point.power = point.next.power; 434 point.next.power = temp; 435 } 436 } 437 // 重置 point 至链表头 head 438 point = head; 439 } 440 // 合并同幂项 441 // ---------------------------- 442 return head; 443 } 444 445 // 两个多项式相加 446 public String sum(String polynomial1, String polynomial2, char sign) { 447 448 // 判断多项式是否为空 449 if (polynomial1.equals("") && polynomial2.equals("")) { 450 return "多项式不能为空!"; 451 } 452 if (polynomial1.equals("")) { 453 return "多项式 PolyOne 不能为空!"; 454 } 455 if (polynomial2.equals("")) { 456 return "多项式 PolyTwo 不能为空!"; 457 } 458 // 对两个多项式进行格式化处理 459 Term polynomial_1_head = formatPolynomial(polynomial1); 460 Term polynomial_2_head = formatPolynomial(polynomial2); 461 // 将第二个多项式与第一个多项式相加:通过判断项的幂来判断是否为同一次项,若是,使其系数相加;若不是,直接将其链接到第一个多项式的链表中 462 // 先对两个多项式按多项式的幂按非降序排序 463 polynomial_1_head = sortPolynomial(polynomial_1_head); 464 polynomial_2_head = sortPolynomial(polynomial_2_head); 465 // 两个多项式相加 466 // 定义两个指针,指向第一个多项式当前项的前后项 467 Term point1 = polynomial_1_head; 468 Term prevPoint1 = new Term(0, 0); 469 prevPoint1.next = polynomial_1_head; 470 // 定义一个指针,指向第二个多项式的当前项 471 Term point2 = polynomial_2_head; 472 // 将第二个多项式添加到第一个多项式中 473 while (point2 != null && point1 != null) { 474 if (point2.power == point1.power) { 475 // 系数相加 476 if (sign == '+') { 477 point1.coefficient += point2.coefficient; 478 } else if (sign == '-') { 479 point1.coefficient -= point2.coefficient; 480 } 481 // point2 指针下移一项, 不移动point1的原因:point2的下一项的幂可能与该 point1 482 // 项的幂相等,因为没有对同幂项进行预合并处理 483 point2 = point2.next; 484 } else if (point2.power > point1.power) { 485 point1 = point1.next; 486 prevPoint1 = prevPoint1.next; 487 } else if (point2.power < point1.power) { 488 // 用 point2 489 // 的系数和幂创建一个新项,并将其链接到point1与prePoint1中间 490 // ------------注意,并不是直接用point2来初始化tempTerm,因为tempTerm.next = 491 // point1;会让 point2.next = point1; 492 Term tempTerm = new Term(point2.coefficient, point2.power); 493 tempTerm.next = point1; 494 if (prevPoint1.next != polynomial_1_head) { 495 prevPoint1.next = tempTerm; 496 } else { 497 polynomial_1_head = tempTerm; 498 prevPoint1.next = polynomial_1_head; 499 } 500 prevPoint1 = prevPoint1.next; 501 // point2 移动到下一项 502 point2 = point2.next; 503 } 504 } 505 // 如果还多项式2中存在幂比多项式1中最大幂还大的项,则将这些项全部添加到多项式1的后面(注意两个多项式都已排序) 506 if (point2 != null) {// 从上面的while{}可以判断,该条件语句隐含着 && point1==null 507 Term point2_point = point2; 508 if (sign == '-') { 509 while (point2_point != null) { 510 point2_point.coefficient *= (-1); 511 point2_point = point2_point.next; 512 } 513 } 514 // 注意------此处不能用point1=point2;因为point1==null,已不具有指针性质 515 prevPoint1.next = point2; 516 } 517 // 得到相加后的多项式字符串 518 String result = getResult(polynomial_1_head); 519 return result; 520 } 521 522 // 得到相加后的多项式字符串 523 public String getResult(Term polynomial_1_head) { 524 String result = ""; 525 Term point1 = polynomial_1_head; 526 while (point1 != null) { 527 // 幂大于1或小于0 的输出格式 528 if (point1.power > 1 || point1.power < 0) { 529 if (point1.coefficient > 0) { 530 if (point1 != polynomial_1_head) { 531 // System.out.print("+" + point1.coefficient + "x^" 532 // + point1.power); 533 result += "+" + point1.coefficient + "x^" 534 + point1.power; 535 } else { 536 // System.out.print(point1.coefficient + "x^" 537 // + point1.power); 538 result += point1.coefficient + "x^" + point1.power; 539 } 540 } else if (point1.coefficient < 0) { 541 // System.out.print(point1.coefficient + "x^" + 542 // point1.power); 543 result += point1.coefficient + "x^" + point1.power; 544 } else if (point1.coefficient == 0) { 545 result += "+0"; 546 } 547 } else if (point1.power == 1) {// 幂等于1 的输出格式 548 if (point1.coefficient > 0) { 549 if (point1 != polynomial_1_head) { 550 // System.out.print("+" + point1.coefficient + "x"); 551 result += "+" + point1.coefficient + "x"; 552 } else { 553 // System.out.print(point1.coefficient + "x"); 554 result += point1.coefficient + "x"; 555 } 556 } else if (point1.coefficient < 0) { 557 // System.out.print(point1.coefficient + "x"); 558 result += point1.coefficient + "x"; 559 } else if (point1.coefficient == 0) { 560 result += "+0"; 561 } 562 } else if (point1.power == 0) {// 幂等于0 的输出格式 563 if (point1.coefficient > 0) { 564 if (point1 != polynomial_1_head) { 565 // System.out.print("+" + point1.coefficient); 566 result += "+" + point1.coefficient; 567 } else { 568 // System.out.print(point1.coefficient); 569 result += point1.coefficient; 570 } 571 } else if (point1.coefficient < 0) { 572 // System.out.print(point1.coefficient); 573 result += point1.coefficient; 574 } else if (point1.coefficient == 0) { 575 result += "+0"; 576 } 577 } 578 point1 = point1.next; 579 } 580 // 去掉式子中的"+0"/"-0"/将仅有一项时的"+0"->"0" 581 if (result.length() != 2) { 582 for (int i = 0; i < result.length();) { 583 if ((result.charAt(i) == '+' && result.charAt(i + 1) == '0') 584 || (result.charAt(i) == '-' && result.charAt(i + 1) == '0')) { 585 result = result.substring(0, i) 586 + result.substring(i + 2, result.length()); 587 } else { 588 i++; 589 } 590 } 591 } 592 // 不能用else if(){} 因为上面的处理可能使多项式出现下面这种情况 593 if (result.equals("+0") || result.equals("")) { 594 result = "0"; 595 } 596 // 结果式子可能第一位为'+'号,比如出现这种结果"+3+2x^4",需要将'+'号去掉 597 if (result.charAt(0) == '+') { 598 result = result.substring(1, result.length()); 599 } 600 return result; 601 } 602 }
欢迎转载,欢迎批评指正!
转载请注明:
转自博客园,转载地址:http://www.cnblogs.com/igeneral/