尝试将序列存储为链表中的链表 - Java

时间:2015-10-24 06:20:35

标签: java singly-linked-list

所以这是一个班级项目,我遇到了一个问题,我不知道我是怎么造成的。我正在编写一种方法,假设采用一系列RNA或DNA,将其解析为char数组,验证所有字符是否适合序列类型,然后将数组转换为单链表,其中每个节点包含一个字母,然后我想将该列表传递给外链表的fList节点。

    //if sequence is valid fill frag with base sequence and pass the list to 
    //fragment list (fList) at position of insert
    if(validSeq){
        fList.moveTo(pos);
        frag.moveToStart();
        for(int count = 0;count < sequence.length(); count++){            
            frag.insert(seq[count]);
        }

        fList.insert(frag);
        System.out.print(fList.getValue());
    }
    else{
        System.out.print("Invalid Sequence: not stored   ");
    }

但我得到的输出是:

  • [cccccccccccccccccccccc] for attacgatctgcacaagatcct
  • [tttttttt] for ggggtttt
  • [aaaaa] for aaccaa

它似乎重复了整个事情的倒数第二个字母,但我不知道为什么。我确定是什么导致它在上面的方法块中。如果我没有正确地做到这一点或者遗漏了一些明显的东西,那么第一次在这里发帖很抱歉。

编辑:这是我正在使用的单链表

    /**  
 * Singly Linked list implementation which
 * uses package private {@link Node} to store node values.
 * @see List
 */
public class SLList<E> implements List<E> {
  private transient Node<E> head;      // Pointer to list header
  private transient Node<E> tail;      // Pointer to last element
  private transient Node<E> curr;      // Access to current element
  private transient int listSize;      // Size of list

  /**
   * Create a new empty singly linked list.
   */
  public SLList() { 
    curr = tail = new Node<E>(null);
    head = new Node<E>(tail);
    listSize = 0;
  }

  /**
   * {@inheritDoc}
   */
  @Override
  public void clear() {
    curr = tail = new Node<E>(null);
    head = new Node<E>(tail);
    listSize = 0;
  }

  /**
   * {@inheritDoc}
   */
  @Override
  public boolean insert(E it) {
    curr.setNext(new Node<E>(curr.element(), curr.next()));
    curr.setElement(it);
    if (tail == curr) {
      tail = curr.next();
    }
    listSize++;
    return true;
  }

  /**
   * {@inheritDoc}
   * This append operatoin will not increment the current element reference.
   */
  @Override
  public boolean append(E it) {
    tail.setNext(new Node<E>(null));
    tail.setElement(it);
    tail = tail.next();
    listSize++;
    return true;
  }

  /**
   * {@inheritDoc}
   */
  @Override
  public E remove () {
    if (curr == tail) {
      return null;          // Nothing to remove
    }
    E it = curr.element();                  // Remember value
    curr.setElement(curr.next().element()); // Pull forward the next element
    if (curr.next() == tail) {
      tail = curr;   // Removed last, move tail
    }
    curr.setNext(curr.next().next());       // Point around unneeded link
    listSize--;                             // Decrement element count
    return it;                              // Return value
  }

  /**
   * Move the current element reference to the head of the list.
   */
  @Override
  public void moveToStart() { 
    curr = head; 
  }

  /**
   * Move the current element reference to the tail of the list.
   */
  @Override
  public void moveToEnd() { 
    curr = tail; 
  }

  /**
   * Move the current element reference one step closer to the
   * list head.
   * If the current element is already at the head, this method
   * does nothing.
   * <dl>
   * <  dt>Note:</dt>
   *   <dd>As this is a singly linked list, the {@link #prev} operation 
   *   can be expensive - up to O(n^2) on large lists.</dd>
   * </dl>
   * @return the value of the previous node in the list.
   */
  @Override
  public E prev() {
    if (head == curr) {
      return null; // No previous element
    }
    Node<E> temp = head;
    // March down list until we find the previous element
    while (temp.next() != curr) {
      temp = temp.next();
    }
    curr = temp;
    return curr.element();
  }

  /**
   * Move the current element reference one step closer to the
   * list tail.
   * If the current element is already at the tail, this method
   * returns null.
   * @return the value of the next node in the list.
   */
  @Override
  public E next() { 
    if (curr != tail) {
      curr = curr.next(); 
    }
    return curr.element();
  }


  /**
   * {@inheritDoc}
   */
  @Override
  public int length() { 
    return listSize; 
  }


  /**
   * {@inheritDoc}
   */
  @Override
  public int position() {
    Node<E> temp = head;
    int i;
    for (i=0; curr != temp; i++) {
      temp = temp.next();
    }
    return i;
  }

  /**
   * {@inheritDoc}
   * @return null if pos does not refer to a valid position in the list
   */
  @Override
  public E moveTo(int pos) {
    if ((pos < 0) || (pos > listSize)) {
      return null;
    }
    curr = head;
    for(int i=0; i<pos; i++) {
      curr = curr.next();
    }
    return curr.element();
  }

  /**
   * {@inheritDoc}
   */
  @Override
  public boolean isAtEnd() { 
    return curr.next() == tail; 
  }

  /**
   * {@inheritDoc}
   * Note that null gets returned if the current reference is at the tail
   */
  @Override
  public E getValue() {
    return curr.element();
  }

  /**
   * Display the string representation of the value stored within 
   * each element in the list.
   * The entire list is bounded by square brackets.
   */
  @Override
  public String toString() {
    StringBuilder sb = new StringBuilder();
    curr = head;
    for(int i=0; i<listSize; i++) {
      sb.append(curr.next().toString());
    }
    return "[" + sb.toString() + "]";
  }

}

编辑:这是导致我麻烦的整个方法

//sends sequence to flist after verifying their validity
    public static void sendToFlist(String sequence, sequenceType stype, int pos, 
            SLList fList){

        char[] seq = new char[sequence.length()];
        boolean validSeq = true;
        SLList frag = new SLList();
        frag.clear();

        //turn sequence into an array for validity parsing
        for(int count = 0;count < sequence.length(); count++){
            seq[count] = sequence.charAt(count);                       
        }

        //check sequence validity based on sequence type enum
        switch(stype){
                case RNA: 
                    for(int count = 0;count < sequence.length(); count++){
                        if(!(Character.valueOf(seq[count]).equals('a'))&&
                                !(Character.valueOf(seq[count]).equals('g'))&&
                                !(Character.valueOf(seq[count]).equals('c'))&&
                                !(Character.valueOf(seq[count]).equals('u'))){
                          validSeq = false;
                        }
                    }
                    break;

                case DNA: 
                    for(int count = 0;count < sequence.length(); count++){
                        if(!(Character.valueOf(seq[count]).equals('a'))&&
                                !(Character.valueOf(seq[count]).equals('g'))&&
                                !(Character.valueOf(seq[count]).equals('c'))&&
                                !(Character.valueOf(seq[count]).equals('t'))){
                            validSeq = false;
                        }
                    }
                    break;
        }

        //if sequence is valid fill frag with base seqence and pass the list to 
        //fragment list (fList) at position of insert
        if(validSeq){
            fList.moveTo(pos);
            frag.moveToStart();
            for(int count = 0;count < sequence.length(); count++){            
                frag.insert(seq[count]);
            }

            fList.insert(frag);
            System.out.print(fList.getValue());
        }
        else{
            System.out.print("Invalid Sequence: not stored   ");
        }
    }

但是我检查了数组,似乎正确地存储了序列

1 个答案:

答案 0 :(得分:0)

这实际上很有趣:

%output application/csv separator='\\t'

您没有递增 StringBuilder sb = new StringBuilder(); curr = head; for(int i=0; i<listSize; i++) { sb.append(curr.next().toString()); } return "[" + sb.toString() + "]"; ,因此一遍又一遍地打印相同的元素curr

你也可能在那里订购错误,因此curr.next()在最后一个之前是一个,而在第一个之后是一个,但这是另一个问题。

我相信它应该是这样的:

curr.next

所以可能列表几乎没问题,只是输出错误。