Reputation: 195
I created my own linked list in java(code below) and I was trying to store DNA?RNA sequences from a text file in an array of a custom data type that contains the enum DNA/RNA, as well as a linked list containing the actual DNA sequence. I don't know if the characters are just not being inserted into the linked list or if there is a problem with my toString but the output only prints the position and enum type, not the sequence from the list. Code is below My node class
public class Node<E> {
private Node<E> next;
protected E data;
Node(E data,Node<E> nextVal){
this.data=data;
next=nextVal;
}
Node(Node<E> nextVal){
next=nextVal;
}
Node<E> Next(){
return next;
}
Node<E>setNext(Node<E> nextVal){
return next=nextVal;
}
E data(){
return data;
}
E setData(E it){
return data=it;
}
}
My Linked List Class
public class MyLinkedList<E> implements List<E>{
private Node<E> head;
private Node<E> tail;
protected Node<E> curr;
private int size;
MyLinkedList(int size){
this();
}
MyLinkedList(){
curr=tail=head=new Node<E>(null);
size=0;
}
@Override
public void clear() {
head.setNext(null);
curr=tail=head=new Node<E>(null);
size=0;
}
@Override
public void insert(E item) {
curr.setNext(new Node<E>(item, curr.Next()));
if(tail==curr)
tail=curr.Next();
size++;
}
@Override
public void append(E item) {
tail=tail.setNext(new Node<E>(item, null));
size++;
}
@Override
public E remove() {
if(curr.Next() ==null)
return null;
E item=curr.Next().data();
if(tail==curr.Next())
tail=curr;
curr.setNext(curr.Next().Next());
size--;
return item;
}
@Override
public void moveToStart() {
curr =head;
}
@Override
public void moveToEnd() {
curr=tail;
}
@Override
public void prev() {
if(curr==head)
return;
Node<E> temp=head;
while (temp.Next()!=curr)
temp=temp.Next();
curr=temp;
}
@Override
public void next() {
if(curr!=tail)
curr=curr.Next();
}
@Override
public int length() {
return size;
}
@Override
public int currPos() {
Node<E>temp=head;
int i;
for(i=0;curr!=temp;i++)
temp.Next();
return i;
}
@Override
public void moveToPos(int pos) {
assert (pos>=0)&& (pos<=size):
"Position out of Range";
curr=head;
for(int i=0;i<pos;i++)
curr.Next();
}
@Override
public E getValue() {
if(curr.Next()==null)
return null;
return curr.Next().data();
}
@Override
public String toString() {
String result = "";
Node current = head;
while(current.Next() != null){
result += current.data();
if(current.Next() != null){
result += ", ";
}
current = current.Next();
}
return "" + result;
}
}
This is the SequenceArr class which handles the operations on the array mentioned above (not complete here but all that is used in this example)
public class SequenceArr {
private TypeSeq [] SeqArr;
private int size=0;
private int MAXSIZE;
public SequenceArr(int MAXSIZE){
this.MAXSIZE=MAXSIZE;
SeqArr =new TypeSeq[MAXSIZE];
size=0;
}
public void insert(int pos, Type t, MyLinkedList<Character> seq){
TypeSeq currentEl=new TypeSeq(t,seq);
assert pos<=MAXSIZE: "Position over maximum size of array";
SeqArr[size]=currentEl;
size++;
}
public void remove(int pos){
if(SeqArr[pos]!=null){
while(SeqArr[pos+1]!=null){
SeqArr[pos]=SeqArr[pos+1];
}
if(SeqArr[pos+1]==null){
SeqArr[pos]=null;
}
}
else
System.out.print("No sequence to remove at specified position");
}
public void print(){
int i=0;
while (SeqArr[i]!=null){
System.out.println(i+"\t"+SeqArr[i].getType()+"\t"+SeqArr[i].getBioSeq().toString());
i++;
}
}
public void print(int pos){
if(SeqArr[pos]==null)
System.out.print("No sequence to print at specified position");
else
System.out.println(SeqArr[pos].getType()+"\t"+SeqArr[pos].getBioSeq().toString());
}
The custom data type i created that the array is made of
public class TypeSeq {
private Type type;
private MyLinkedList<Character> BioSeq;
public TypeSeq(Type type, MyLinkedList<Character> BioSeq){
this.type=type;
this.BioSeq=BioSeq;
}
public MyLinkedList<Character> getBioSeq() {
return BioSeq;
}
public void setBioSeq(MyLinkedList<Character> bioSeq) {
BioSeq = bioSeq;
}
public Type getType() {
return type;
}
public void setType(Type type) {
this.type = type;
}
}
and my DNAList class which handles input and contains the main method
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
public class DNAList {
static SequenceArr seqar;
public static void main(String []args){
MyLinkedList<String> hey=new MyLinkedList<>();
hey.append("Hello");
int arraysize= Integer.parseInt(args[0]);
String filePath=args[1];
File file=new File(filePath);
seqar=new SequenceArr(arraysize);
exefromFile(file);
}
public static void exefromFile(File file){
Scanner sc;
try{
sc=new Scanner(file);
while(sc.hasNextLine()){
String cmd=sc.nextLine();
if(!cmd.equals(""))
execute(cmd);
}
}catch (FileNotFoundException e){
e.printStackTrace();
}
}
public static void execute(String s){
s=s.trim();
String [] commands=s.split("\\s+");
switch (commands[0])
{
case "insert":
int pos=Integer.parseInt(commands[1]);
Type t=Type.fromString(commands[2]);
char [] charArr=commands[3].toCharArray();
MyLinkedList<Character> seq=new MyLinkedList<>(charArr.length);
char curChar;
for(int i=0;i<seq.length();i++){
curChar=charArr[i];
if(t==Type.DNA&&(curChar=='A'||curChar=='C'||curChar=='G'||curChar=='T'))
seq.append(charArr[i]);
else
System.out.print("Error occurred while inserting");
}
seqar.insert(pos,t,seq);
break;
case "remove":
pos=Integer.parseInt(commands[1]);
seqar.remove(pos);
break;
case "print":
if(commands.length>1&&commands[1]!=null){
pos=Integer.parseInt(commands[1]);
seqar.print(pos);
}
else
seqar.print();
break;
case "clip":
pos=Integer.parseInt(commands[1]);
int start =Integer.parseInt(commands[2]);
int end =Integer.parseInt(commands[3]);
seqar.clip(pos,start,end);
break;
case "copy":
int pos1=Integer.parseInt(commands[1]);
int pos2=Integer.parseInt(commands[2]);
seqar.copy(pos1,pos2);
break;
case "transcribe":
pos=Integer.parseInt(commands[1]);
seqar.transcribe(pos);
break;
}
}
}
The input .txt file will say something like
insert 0 DNA AATTCCGGAATTCCGG
but the output will just be
0 DNA and the sequence will not be printed. Any ideas?
Upvotes: 0
Views: 220
Reputation: 134
There are quite a lot of bugs in the code, to mention some:
MyLinkedList(int size){
this();
}
MyLinkedList(){
curr=tail=head=new Node<E>(null);
size=0;
}
this always initialises your list with size 0.
char [] charArr=commands[3].toCharArray();
MyLinkedList<Character> seq=new MyLinkedList<>
(charArr.length);
I don't get the point of initialising your list with the size of 4 every-time. Also note, it's not going to initialise with the given size as you are always overriding it with 0.
@Override
public void insert(E item) {
curr.setNext(new Node<E>(item, curr.Next()));
if(tail==curr)
tail=curr.Next();
size++;
}
You are not utilising the concept of head at all, your first insert is a special case and needs to handled wisely.
@Override
public String toString() {
String result = "";
Node current = head;
while(current.Next() != null){
result += current.data();
if(current.Next() != null){
result += ", ";
}
current = current.Next();
}
return "" + result;
}
head is always going to be null, when you print it's always going to result in first element being null. Moreover, when you find a node with it's next pointing to null, you should use its data. In your code, before returning the result you need to append the data from the last element too.
Upvotes: 1