多项式输出不正确
我正在编写一个程序,打算接收最多两个用户输入的多项式(输入格式对用户友好,例如“2x^2+3x-4”),将它们存储到两个双向链表中,然后允许用户将多项式相加并输出结果。我已经实现了程序以接收用户输入并解析多项式,但在某些测试中,我只是让程序再次输出多项式时,发现它输出得不正确。
下面是我当前用于创建节点、将它们排序到各自的列表,以及用于打印这些列表的方法的类:
package polynomialAdder;
public class PolyList {
private PolyNode head;
public PolyList()
{
this.head = null;
}
public PolyList(String poly)
{
this.head = null;
String[] component = poly.split("\\+\\-"); //split based on "+" and "-" operators
for(String term : component)
{
term = term.trim();
int coe, exp;
if(term.contains("x")) //check if given term has an exponent and set it as such, otherwise set exp to 0 and omit "x^"
{
String[] parts = term.split("x\\^?");
coe = Integer.parseInt(parts[0]);
exp = (parts.length == 2) ? Integer.parseInt(parts[1]) : 1;
}
else
{
coe = Integer.parseInt(term);
exp = 0;
}
insertionSort(new PolyNode(coe, exp));
}
}
private void insertionSort(PolyNode newNode)
{
if(head == null || newNode.exp > head.exp) //sets the new node as the head if the list is empty or if its exponent is higher than that of the head
{
newNode.next = head;
head = newNode;
}
else //traverses through the list, adding coefficients together if they share an exponent
{
PolyNode current = head;
while(current.next != null && current.next.exp >= newNode.exp)
{
if(current.next.exp == newNode.exp)
{
newNode.coe += current.next.coe;
newNode.next = current.next.next;
current.next.next.prev = newNode;
current.next = newNode;
}
current = current.next;
}
newNode.next = current.next;
current.next = newNode;
}
}
public void print()
{
PolyNode current = head;
StringBuilder result = new StringBuilder();
while(current != null)
{
result.append(current.coe).append("x^").append(current.exp);
if(current.next != null && current.coe < 0)
{
result.append("-");
}
else if(current.next != null && current.coe > 0)
{
result.append("+");
}
current = current.next;
}
System.out.println(result);
}
}
这是我当前的 main 方法:
package polynomialAdder;
import java.util.*;
public class Main
{
public static void main(String[] args)
{
Scanner polyScan = new Scanner(System.in);
System.out.println("Enter first polynomial. Please use ^ to indicate exponents");
String polyA = polyScan.nextLine();
PolyList poly1 = new PolyList(polyA);
System.out.println("Enter second polynomial. Please use ^ to indicate exponents");
String polyB = polyScan.nextLine();
PolyList poly2 = new PolyList(polyB);
polyScan.close();
poly1.print();
poly2.print();
}
}
Node 类:
package polynomialAdder;
public class PolyNode {
int coe;
int exp;
PolyNode next;
PolyNode prev;
PolyNode(int coe, int exp)
{
this.coe = coe;
this.exp = exp;
this.next = null;
this.prev = null;
}
}
需要说明的是,在 main 的 print() 方法的两次调用并非最终版本。我在测试中使用它们来确保列表已正确填充。
我遇到的问题是 print() 方法输出不正确。
例如输入“2x^2+3x-4”,得到的输出却是“2x^1”,我注意到这与我的条件运算符中的 else 有关,但我还没有办法弄清楚为什么会给出这个输出。
解决方案
正如你所正确猜测的,主要问题出在构造函数上,特别是在使用 split 方法。你试图基于两个字符来分割字符串,而你作为参数传入的字符串 "\+\-",在实际应用中并不会产生任何分隔。
需要注意的是,除了前述问题之外,当应用到字符串 "HEYxJUDE" 时,使用 split( "x" ); 会返回这样的数组:{ "HEY", "JUDE" },正如你所看到的,作为分隔符使用的字符串会消失。
我之所以提及这点,是因为在尝试(未成功)用 \"+\" 和 \"-\" 来分割字符串之后,如果我真的成功了,这些分隔符本来会被“丢失”,如果我没弄错的话,它们其实是方程的一部分 :)
在把它们用作分隔符时丢失“元素”的问题,迫使我们创建我们自己的“输入处理器”。
我不确定你打算如何使用这个,但在我看来,在 PolyNode 中应当存储方程的“全部”分量,因此我对该类提出了一些修改:
public class PolyNode {
public PolyNode() { }
public PolyNode( String operator ) {
this.operator = operator;
}
String operator;
String variable;
int coe;
int exp = -1;
PolyNode next;
PolyNode prev;
}
正如你所见,修改很小:我添加了一个接收字符串的构造函数(用于确定运算的节点),以及用于存储相应数值的运算符和变量属性。
public class PolyList {
private PolyNode head;
private void process( PolyNode node, String poly ) {
int indexOfExponent = poly.indexOf( "^" );
int indexOfVariable = poly.indexOf( "x" );
if( indexOfVariable == -1 ) {
indexOfVariable = poly.indexOf( "y" );
}
if( indexOfExponent == -1 ) {
if( indexOfVariable == -1 ) {
node.coe = Integer.parseInt( poly );
}
else {
node.coe = Integer.parseInt( poly.substring( 0, indexOfVariable ) );
node.variable = poly.substring( indexOfVariable, poly.length() );
}
}
else {
if( indexOfVariable == -1 ) {
node.coe = Integer.parseInt( poly.substring( 0, indexOfExponent ) );
node.exp = Integer.parseInt( poly.substring( indexOfExponent + 1, poly.length() ) );
}
else {
node.coe = Integer.parseInt( poly.substring( 0, indexOfVariable ) );
node.variable = poly.substring( indexOfVariable, indexOfExponent );
node.exp = Integer.parseInt( poly.substring( indexOfExponent + 1, poly.length() ) );
}
}
}
public PolyList( String poly ) {
/// 1x^2+3x-4
head = new PolyNode();
PolyNode current = head;
boolean isOperator = false;
String operator = "";
int indexOfOperator = 0;
// we traverse the received string until we find a **+**
// or a **-**; when we do, we call **process**, passing
// it the current node and the portion of the string
// preceding the operator we found as parameters.
for( int i = 0; i < poly.length(); i ++ ) {
char character = poly.charAt( i );
isOperator = true;
if( character == '+' ) {
operator = "+";
}
else if( character == '-' ) {
operator = "-";
}
else {
isOperator = false;
}
// since there is no operator after the last term,
// we use this *if* statement to end the operation
if( i == poly.length() - 1 ) {
process( current, poly.substring( indexOfOperator, i + 1 ) );
}
// after calling *process*, we create the next node,
// which will contain the operator, and then we
// create the node following that one; finally, we
// update the assignment of **current** to the last
// node
if( isOperator ) {
process( current, poly.substring( indexOfOperator, i ) );
current.next = new PolyNode( operator );
current.next.next = new PolyNode();
current = current.next.next;
indexOfOperator = i + 1;
}
}
show();
}
// used only to “display” the result
void show() {
PolyNode current = head;
while( current != null ) {
if( current.operator != null ) {
System.out.println( current.operator );
}
else {
System.out.print( current.coe );
if( current.variable != null ) {
System.out.print( current.variable );
}
if( current.exp != -1 ) {
System.out.print( current.exp );
}
System.out.println();
}
current = current.next;
}
}
}
process 方法接收一个 PolyNode 对象和一个包含单项式的字符串,将其分解成基本分量,并把结果赋给该 PolyNode 对象。
我相信这个方法还可以简化……就交给你来处理吧 :)