为什么我可以使用链接列表获取java stackoverflow错误?

时间:2015-03-28 07:36:35

标签: java linked-list singly-linked-list

我正在尝试添加以稀疏输入/输出格式输入的多个多项式。基本上代表1 + 5x + 2x^2输入将是

0,1:1,5:2,2;
; 

如果我想添加3x^2,则输入将是

2,3; 
;

电源始终从最小到最大排序,不打印0常量。我没有使用递归函数,我的算法适用于“小”(20毫秒)和“中”(50毫秒)输入大小。但是,当我测试“大”输入大小时,我只是出现堆栈溢出错误!以下是我的代码,

提前致谢!

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

class list {

    //contains the reference to the first node in the list
    private node firstNode;
    //construct an empty list called linkedList
    public list( String linkedList) {

        firstNode = null;

    }

    public list () {
        this("linkedlist");
    }

    public String toString(){
        return firstNode +"";
    }

    //where i is the power 
    public node find (int power, int coeff ) {

        node nodePos = null;
        node n = firstNode;

        while ( n!= null ) {
            if (n.pow == power) {
                nodePos = n;
                break;
            } else if (n.next == null) {
                nodePos = n;
                break;
            } else if ((n.pow < power) & (n.next.pow > power)){
                nodePos = n;
                break;
            } else if (n.pow > power) {
                nodePos = firstNode;
                break;
            } else {
                n = n.next;
            }
        }
        return nodePos; 
    }


    public void insert ( int p, int c) {

        node position = null;

        //if list is empty, add node as the first element
        if ( isEmpty ()) {
            firstNode = new node(p, c, null);
        } else {
            position = find(p, c);
            //do addition
            if (position.pow == p) {
                position.coeff = position.coeff + c;
            } else if (position.pow > p) {
                //insert before
                firstNode = new node (p, c, position);
            } else {
                //insert after
                position.next = new node(p, c, position.next);
            }
        } 
    }


    private boolean isEmpty() {
        return firstNode == null; 
    }

}

class node {

    int pow;
    int coeff;
    node next;

    public node () {
        pow = 0;
        coeff = 0;
        next = null;
    } 

    public node (int pow, int coeff) {
        this.pow = pow;
        this.coeff = coeff;
        next = null;
    }

    public node (int pow, int coeff, node next) {
        this.pow = pow;
        this.coeff = coeff;
        this.next = next;
    }

    public String toString(){
        if (next == null){
            if (coeff == 0) {
                return "";
            }
            return pow+","+coeff+";";
        } else if (coeff == 0){
            return next + "";
        }
        else {
            return pow+","+coeff+";"+next;
        }
    }
}

public class Adderv2 {

    public static void main(String[]args) throws IOException{

        //LinkedList<Integer> list = new LinkedList<Integer>();

        InputStreamReader reader = new InputStreamReader(System.in);
        BufferedReader br = new BufferedReader(reader);
        String line = br.readLine();

        list linkedList = new list();

        while (!line.equals(";")) {

            //Split string by ';'
            StringTokenizer st = new StringTokenizer(line, ";");
            while (st.hasMoreElements()) {

                //split string up by ','s
                StringTokenizer st2 = new StringTokenizer(st.nextToken(), ",");
                while(st2.hasMoreElements()) {

                    //convert tokens to integer 
                    int i1 = Integer.parseInt(st2.nextToken());
                    int i2 = Integer.parseInt(st2.nextToken());

                    //insert the integers into the list
                    linkedList.insert (i1, i2);
                }
            }

            //read next line
            line = br.readLine();
        }
        System.out.println(linkedList);
        System.out.println(";");
    }

}

1 个答案:

答案 0 :(得分:1)

toString中的node实现是递归的,可能会导致堆栈溢出更长的列表(堆栈大小通常比堆大小更有限)。

解决此问题的一种方法是将toString移至list,然后以迭代方式实施:

public String toString(){
  StringBuilder sb = new StringBuilder();
  node current = firstNode;
  while (current != null) {
    sb.append(pow + "," + coeff + ";");
    current = current.next();
  }
  return sb.toString();
}

P.S。为什么不使用TreeMap<Integer, Integer>(如果它不太稀疏,只使用数组)?这应该使插入更快(O(log n)而不是(O(n)),同时仍然保持顺序。

public class Poly {
  TreeMap<Integer,Integer> map = new TreeMap<Integer, Integer>();

  public void insert(int pow, int coeff) {
    Integer old = map.get(pow);
    int value = old == null ? 0 : old.intValue();
    map.put(pow, old + coeff);
  }

  public void toString() {
    StringBuilder sb = new StringBuilder();
    for (Map.Entry<Integer,Integer> e: map.entrySet()) {
      sb.append(e.key() + "," + e.value() + ";");
    }
    return sb.toString();
  }