I'm very close to being done, but can't quite figure out how to tie everything together. I have the separate methods responsible for their particular task, but i feel like my cohesion is really bad. not real sure how they tie together and what needs to be called in main. The goal here is to read a text file from the command line and list the words in the story lexicographically.
% java Ten < story.txt
Word Occurs
==== ======
a 21
animal 3
.
.
.
zebra 1
%
Here's my code thus far:
import java.util.Scanner;
public class Ten2
{
public static void main(String [] arg)
{
Scanner input = new Scanner(System.in);
String word;
List sortedList = new List();
word = nextWord(input);
while (word!=null) {
sortedList.insert(word);
word = nextWord(input);
}
sortedList.printWords();
}
private static String nextWord(Scanner input)
{
// return null if there are no more words
if (input.hasNext() == false )
return null;
// take next element, convert to lowercase, store in s
else {
String s = input.next().toLowerCase() ;
// empty string
String token = "";
// loop through s and concatonate chars onto token
for (int i =0; i < s.length(); i++) {
if (Character.isLetter(s.charAt(i)) == true)
token = token + s.charAt(i);
else if (s.charAt(i) == '\'' )
token = token + s.charAt(i);
else if (s.charAt(i) == '-')
token = token + s.charAt(i);
}
return token;
}
}
}
class List
{
/*
* Internally, the list of strings is represented by a linked chain
* of nodes belonging to the class ListNode. The strings are stored
* in lexicographical order.
*/
private static class ListNode
{
// instance variables for ListNode objects
public String word;
public ListNode next;
public int count;
// Listnode constructor
public ListNode(String w, ListNode nxt)
{
word = w; // token from nextWord()?
next = nxt; // link to next ListNode
count = 1; // number of word occurences
}
}
// instance variables for List object
private ListNode first;
private int numWords;
// constructor postcondition: creates new Listnode storing object
public List()
{
first = null; // pointer to ListNode?
numWords = 0; // counter for nodes in list
}
// Insert a specified word into the list, keeping the list
// in lexicographical order.
public void insert(String word)
{
// check if first is null
if (first == null) {
ListNode newNode;
newNode = addNode(word, null);
first = newNode;
}
// else if (first is not null) check if word matches first word in List
else if (word.equals(first.word)) {
// increase count
first.count++;
}
// else (first is not null && doesn't match first word)
else {
ListNode newNode;
ListNode current;
current = first;
ListNode previous;
previous = null;
int cmp = word.compareTo(current.word);
/*
* Fist two cases of empty list and word already existing
* handled in above if and else statements, now by using compareTo()
* method between the words, the insertion postion can be determined.
* Links between ListNode variables current and previous need to be
* modified in order to maintain the list
*/
// loop as long as value comparing to is positive
// when compareTo() returns positive this means the "word" parameter is greater than the word in the list
while ((cmp >0) && (current.next != null)) {
previous = current;
current = current.next;
cmp = word.compareTo(current.word);
}
// insert after current at end of list
if ((cmp >0 && current.next == null)) {
newNode = addNode(word, null);
current.next = newNode;
}
// increments count when word already exists
else if (cmp==0) {
current.count++;
}
// else (cmp < 0) we insert BEFORE current
else {
newNode = addNode(word, current);
// first node in list comes after new word
if (previous == null) {
first = newNode;
}
else {
// inserting new word in middle of list
previous.next = newNode;
}
}
}
}
// method to add new ListNode and increase counter
private ListNode addNode(String word, ListNode next)
{
ListNode newNode = new ListNode(word, next);
numWords++;
return newNode;
}
// Returns a string array that contains all the words in the list.
public String[] getWords()
{
String[] Words = new String[numWords];
ListNode current = first;
int i =0;
while (current != null) {
Words[i] = current.word;
current = current.next;
i++;
}
return Words;
}
// Returns an int array that contains the number of times
// each word occurs in the list.
public int[] getNumbers()
{
int[] Numbers = new int[numWords];
ListNode current = first;
int i =0;
while (current != null) {
Numbers[i] = current.count;
current = current.next;
i++;
}
return Numbers;
}
// Outputs the string array and int array containing all the
// words in the list and the number of times each occurs.
public void printWords()
{
int[] Numbers = getNumbers();
String[] Words = getWords();
System.out.println("Word \t \t Occurs");
System.out.println("==== \t \t ======");
for (int i =0; i < numWords; i++) {
System.out.println(Words[i] + " \t " + Numbers[i]);
}
}
}
Well, I would start by defining what you want your program to do, which you've already done:
The goal here is to read a text file from the command line and list the words in the story lexicographically.
You're main function does this almost. Basically, what you need is a loop to tie it together:
public static void main(String [] arg)
{
// print out your initial information first (i.e. your column headers)
// ...
List sortedList = new List();
String word = nextWord();
// now, the question is... what is the end condition of the loop?
// probably that there aren't any more words, so word in this case
// will be null
while (word != null)
{
sortedList.insert(word);
word = nextWord();
}
// now, your list takes care of the sorting, so let's just print the list
sortedList.printWords();
}
I think that's all there is to it. Normally, I don't like to post solutions to homework questions, but in this case, since you already had all of the code and you just needed a little nudge to drive you in the right direction, I think it's fine.
There are a few things I noticed that are incorrect with your
Your list constructor has a 'void' return type - there should be no return type on constructors:
public List() //make an empty list
{
first = null;
numWords = 0;
}
The 'else' statement in this method is unneeded:
public static String nextWord()
{
if ( keyboard.hasNext() == false )
return null;
else {
String start = keyboard.next().toLowerCase() ;
String organized = "";
for (int i =0; i < start.length(); i++) {
if (Character.isLetter(start.charAt(i)) == true)
organized = organized + start.charAt(i);
else if (start.charAt(i) == '\'' )
organized = organized + start.charAt(i);
else if (start.charAt(i) == '-')
organized = organized + start.charAt(i);
}
return organized;
}
}
So, this should be:
public static String nextWord()
{
if ( keyboard.hasNext() == false )
return null;
String start = keyboard.next().toLowerCase() ;
String organized = "";
for (int i =0; i < start.length(); i++) {
if (Character.isLetter(start.charAt(i)) == true)
organized = organized + start.charAt(i);
else if (start.charAt(i) == '\'' )
organized = organized + start.charAt(i);
else if (start.charAt(i) == '-')
organized = organized + start.charAt(i);
}
return organized;
}
If you want to use a BufferedReader, it's pretty easy. Just set it up in your main method:
if (arg.length > 0)
{
// open our file and read everything into a string buffer
BufferedReader bRead = null;
try {
bRead = new BufferedReader(new FileReader(arg[0]));
} catch(FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
System.exit(0);
}
setupScanner(bRead);
}
Then, create a new method that sets up the scanner object:
public static void setupScanner(BufferedReader rdr)
{
keyboard = new Scanner(rdr);
}
And then just pass it in on the command line (i.e. java ten2 [filename])
import java.util.Scanner;
public class Ten2
{
public static void main(String [] arg)
{
Scanner input = new Scanner(System.in);
String word;
List sortedList = new List();
word = nextWord(input);
while (word!=null) {
sortedList.insert(word);
word = nextWord(input);
}
sortedList.printWords();
}
private static String nextWord(Scanner input)
{
// return null if there are no more words
if (input.hasNext() == false )
return null;
// take next element, convert to lowercase, store in s
else {
String s = input.next().toLowerCase() ;
// empty string
String token = "";
// loop through s and concatonate chars onto token
for (int i =0; i < s.length(); i++) {
if (Character.isLetter(s.charAt(i)) == true)
token = token + s.charAt(i);
else if (s.charAt(i) == '\'' )
token = token + s.charAt(i);
else if (s.charAt(i) == '-')
token = token + s.charAt(i);
}
return token;
}
}
}
class List
{
/*
* Internally, the list of strings is represented by a linked chain
* of nodes belonging to the class ListNode. The strings are stored
* in lexicographical order.
*/
private static class ListNode
{
// instance variables for ListNode objects
public String word;
public ListNode next;
public int count;
// Listnode constructor
public ListNode(String w, ListNode nxt)
{
word = w; // token from nextWord()?
next = nxt; // link to next ListNode
count = 1; // number of word occurences
}
}
// instance variables for List object
private ListNode first;
private int numWords;
// constructor postcondition: creates new Listnode storing object
public List()
{
first = null; // pointer to ListNode?
numWords = 0; // counter for nodes in list
}
// Insert a specified word into the list, keeping the list
// in lexicographical order.
public void insert(String word)
{
// check if first is null
if (first == null) {
ListNode newNode;
newNode = addNode(word, null);
first = newNode;
}
// else if (first is not null) check if word matches first word in List
else if (word.equals(first.word)) {
// increase count
first.count++;
}
// else (first is not null && doesn't match first word)
else {
ListNode newNode;
ListNode current;
current = first;
ListNode previous;
previous = null;
int cmp = word.compareTo(current.word);
/*
* Fist two cases of empty list and word already existing
* handled in above if and else statements, now by using compareTo()
* method between the words, the insertion postion can be determined.
* Links between ListNode variables current and previous need to be
* modified in order to maintain the list
*/
// loop as long as value comparing to is positive
// when compareTo() returns positive this means the "word" parameter is greater than the word in the list
while ((cmp >0) && (current.next != null)) {
previous = current;
current = current.next;
cmp = word.compareTo(current.word);
}
// insert after current at end of list
if ((cmp >0 && current.next == null)) {
newNode = addNode(word, null);
current.next = newNode;
}
// increments count when word already exists
else if (cmp==0) {
current.count++;
}
// else (cmp < 0) we insert BEFORE current
else {
newNode = addNode(word, current);
// first node in list comes after new word
if (previous == null) {
first = newNode;
}
else {
// inserting new word in middle of list
previous.next = newNode;
}
}
}
}
// method to add new ListNode and increase counter
private ListNode addNode(String word, ListNode next)
{
ListNode newNode = new ListNode(word, next);
numWords++;
return newNode;
}
// Returns a string array that contains all the words in the list.
public String[] getWords()
{
String[] Words = new String[numWords];
ListNode current = first;
int i =0;
while (current != null) {
Words[i] = current.word;
current = current.next;
i++;
}
return Words;
}
// Returns an int array that contains the number of times
// each word occurs in the list.
public int[] getNumbers()
{
int[] Numbers = new int[numWords];
ListNode current = first;
int i =0;
while (current != null) {
Numbers[i] = current.count;
current = current.next;
i++;
}
return Numbers;
}
// Outputs the string array and int array containing all the
// words in the list and the number of times each occurs.
public void printWords()
{
int[] Numbers = getNumbers();
String[] Words = getWords();
System.out.println("Word \t \t Occurs");
System.out.println("==== \t \t ======");
for (int i =0; i < numWords; i++) {
System.out.println(Words[i] + " \t " + Numbers[i]);
}
}
}
Related
As part of an assignment, I have to write a method that will print out repeating values in a linked list, as well as how many times they occur. Below is the method printRepeats() which uses the helper method countRepeats(ListNode node).
The issue is that the output of my method prints repeating values over and over again. For example, in a list with values 1 1 1 2 3 4 5 6 7 6, the output is 1 (Occurences = 3) 1 (Occurences = 3) 1 (Occurences = 3) 6 (Occurences = 2) 6 (Occurences = 2). Any value that repeats should only print once. Any suggestions? Thanks in advance!
public class LinkedList
{
private ListNode first;
public void printRepeats()
{
String ans = "";
ListNode temp = first;
while(temp != null)
{
if(countRepeats(temp) > 1 && ans.indexOf((int)temp.getValue()) == -1)
{
ans += temp.getValue();
System.out.print(temp.getValue() + " (Occurences = " + countRepeats(temp) + ") ");
}
temp = temp.getNext();
}
if(ans.length() == 0)
System.out.print("None of the elements repeat.");
}
private int countRepeats(ListNode node)
{
ListNode temp = first;
int count = 0;
while(temp != null)
{
if((int)temp.getValue() == (int)node.getValue())
count++;
temp = temp.getNext();
}
return count;
}
}
Considering that you must not use any other data structures than a LinkedList, you could:
Create another ListNode element as the first element of a list called "repeatedElements", that must contain pairs element/repetitions of such element.
When counting the repetitions of a single element, insert the element and the number of repetitions it has in "repeatedElements" list.
Before counting the number of repetitions of an element, sweep the repeatedElements list for the element. If the element is present, DO NOT print the output. If it is not, repeat your code as usual.
The system I described will contain more information than the specifically required (the number of repetitions of each element is stored), but it is likely that it will be needed again.
For counting occurrences you need to maintain track record of visited node also like if you have already count any node then need not to pick again those come on link list. Below program clearly explains this-
import java.util.ArrayList;
public class CustomLinkList {
public static void main(String[] args) {
ListNode linkedList = new ListNode(15);
linkedList.next =new ListNode(67);
linkedList.next.next =new ListNode(15);
linkedList.next.next.next =new ListNode(65);
linkedList.next.next.next.next =new ListNode(13);
linkedList.next.next.next.next.next =new ListNode(98);
linkedList.next.next.next.next.next.next =new ListNode(33);
linkedList.next.next.next.next.next.next.next =new ListNode(29);
linkedList.next.next.next.next.next.next.next.next =new ListNode(15);
ListNode printList = linkedList;
System.out.println("Custom Link List is ::: ");
while (printList.next != null){
System.out.printf("%d ",printList.info);
printList = printList.next;
}
System.out.println();
CustomLinkList.occurancesOfElement(linkedList);
}
public static void occurancesOfElement(ListNode listNode){
ArrayList<Integer> visitedNode = new ArrayList();
while(listNode !=null){
ListNode node = listNode;
int count = 0;
while (node !=null)
{
if(listNode.info == node.info && !visitedNode.contains(node.info)) {
count++;
}
node = node.next;
}
if(!visitedNode.contains(listNode.info))
System.out.println("Occurences of : "+listNode.info+" is "+ count);
visitedNode.add(listNode.info);
listNode = listNode.next;
}
}
}
class ListNode {
int info;
ListNode next;
ListNode(int info){
this.info = info;
next = null;
}
}
class DoublyListNode {
int info;
DoublyListNode previous;
DoublyListNode next;
}
}
I have to create a linked List class from scratch for my Java project which will insert a date Object into its proper position. My format for sorting is to simply keep the year/month/day as a single string for use in comparing two Date objects. My compareTo function seems to not be the source of the problem as a simple selectionSort test yielded the proper result. My insert is simply using only the first element to compare to all the rest which is not correct. I don't know how to fix the situation after tinkering with it for some time now.
public class Date212 {
private int month;
private int day;
private int year;
public Date212(String d){
String temp;
temp = d.substring(4,6);
int theMonth = Integer.parseInt(temp);
temp = d.substring(6,8);
int theDay = Integer.parseInt(temp);
temp = d.substring(0,4);
int theYear = Integer.parseInt(temp);
setDate212(theYear, theMonth, theDay);
}
public void setDate212(int y, int m, int d){
year = y;
month = m;
day = d;
}
public int getMonth(){
return month;
}
public int getDay(){
return day;
}
public int getYear(){
return year;
}
public int compareTo(Date212 other){
if(this.toString().compareTo( ((Date212)other).toString()) < 0)
return -1; //This temp is smaller
else if(this.toString().compareTo( ((Date212)other).toString()) > 0){
return 1; //This temp is bigger
}
return 0; //Must be equal
}
public String toString(){
String s = Integer.toString(year) + "/" + Integer.toString(month) + "/" + Integer.toString(day);
return s;
}
}
public class ListNode
{
protected Date212 data;
protected ListNode next;
public ListNode(Date212 d)
{
data = d;
next = null;
} // constructor
} // class ShortNode
public class LinkedList {
/** First node in linked list - dummy node */
private ListNode first = new ListNode(null);
/** Last node in linked list */
private ListNode last = first;
/** Number of data items in the list. */
private int length = 0;
/**
* Gets the number of data values currently stored in this LinkedList.
*
* #return the number of elements in the list.
*/
public int getLength() {
return length;
}
/**
* Appends a String data element to this LinkedList.
*
* #param data
* the data element to be appended.
*/
public void append(Date212 d) {
ListNode n = new ListNode(d);
last.next = n;
last = n;
length++;
} // method append(String)
/**
* Prepends (adds to the beginning) a String data element to this
* LinkedList.
*
* #param data
* the data element to be prepended.
*/
public void insert(Date212 d) {
ListNode n = new ListNode(d);
if (length == 0) //If your list is empty
{
last = n;
first.next = n;
n.next = null;
length++;
}
else //There is element
{
ListNode p = first.next; //Start with the first element
for(int i = 0; i<length; i++){
if(p.data.compareTo(d) < 0){ //If you are smaller than the *following* element
n.next = p.next; //Insert the element after the actual
p.next = n;
return; //Return early
}
p = p.next;
}
//We are greater than any element
this.append(d);
}
}
/**
* Determines whether this ShortSequenceLinkedList is equal in value to the
* parameter object. They are equal if the parameter is of class
* ShortSequenceLinkedList and the two objects contain the same short
* integer values at each index.
*
* #param other
* the object to be compared to this ShortSequenceLinkedList
*
* #return <code>true</code> if the parameter object is a
* ShortSequenceLinkedList containing the same numbers at each index
* as this ShortSequenceLinkedList, <code>false</code> otherwise.
*/
public boolean equals(Object other) {
if (other == null || getClass() != other.getClass()
|| length != ((LinkedList) other).length)
return false;
ListNode nodeThis = first;
ListNode nodeOther = ((LinkedList) other).first;
while (nodeThis != null) {
// Since the two linked lists are the same length,
// they should reach null on the same iteration.
if (nodeThis.data != nodeOther.data)
return false;
nodeThis = nodeThis.next;
nodeOther = nodeOther.next;
} // while
return true;
} // method equals
public String printList(){
String s = "";
ListNode p = first.next;
while(p != null){
s += p.data.toString() + "\n";
p = p.next;
}
return s;
}
}// class LinkedList
Your insertion code scans up to the number of nodes recorded as the list length. That's not necessarily wrong in itself, but it would be better to just use nodes' next references to determine when you've reached the end. One reason using next would be better is that your code would be less brittle: if, say, it failed to properly manage the list length when a node was inserted before the end, then the insertion code itself would still mostly work.
Here's an alternative way your code could be written:
public void insert(Date212 d) {
ListNode n = new ListNode(d);
ListNode p = first;
// Find the insertion point
while ((p.next != null) && (p.next.data.compareTo(d) < 0)) {
p = p.next;
}
// Insert the node
n.next = p.next;
p.next = n;
if (n.next == null) {
last = n;
}
// Update the list length
length++;
}
Instead of insert at the right position I think it would be easier insert the element on the list and after sort the list like Collections.sort(myList,myComparator) does.
In a singly linked list, insertion requires a reference to the node after which the element is to be inserted. So we start with p = first, and traverse the list until we find a p.next which is greater than the element to be inserted. This means we should insert our new element after p and before p.next. This is achieved using a slightly modified version of your code as seen below.
Please note that this is for a list sorted in ascending order. For one sorted in descending order, it would be if(p.next.data.compareTo(d)<0) inside the for loop.
else //There is element
{
ListNode p = first; //Start with the head, p will point to the element AFTER which insertion should take place
for(int i = 0; i<length; i++){
if(p.next.data.compareTo(d) > 0){ //If ele to insert is lesser than next ele
n.next = p.next; //Insert the element after the actual
p.next = n;
length++;
return; //Return early
}
p = p.next;
}
//We are greater than any element
this.append(d);
}
So for my assignment we are to implement some referenced based list manipulation methods in a class and then add to a list and demonstrate the methods using a driver file.
I have provided the entire program for download which includes a pdf that explains the assignment. Our professor uploaded a completed driver file and mine is exactly the same as his but I am getting some run-time errors, first is when calling add() for the third time I get a NullPointerException, if I comment out the rest of the add() calls, size() will not return the same size as getSize() and getSizeRecursive().
Please Help me. Link to download: https://www.dropbox.com/s/qe771q3156h9nwx/ListReferenceBased.rar
// ****************************************************
// Reference-based implementation of ADT list.
// ****************************************************
public class ListReferenceBased implements ListInterface {
// reference to linked list of items
private Node head;
private int numItems; // number of items in list
public ListReferenceBased() {
numItems = 0;
head = null;
} // end default constructor
public boolean isEmpty() {
return numItems == 0;
} // end isEmpty
public int size() {
return numItems;
} // end size
private Node find(int index) {
// --------------------------------------------------
// Locates a specified node in a linked list.
// Precondition: index is the array index of the desired node.
// Assumes that 0 <= index < numItems
// Postcondition: Returns a reference to the desired node.
// --------------------------------------------------
Node curr = head;
for (int skip = 0; skip < index; skip++) {
curr = curr.getNext();
} // end for
return curr;
} // end find
public Object get(int index)
throws ListIndexOutOfBoundsException {
if (index >= 0 && index < numItems) {
// get reference to node, then data in node
Node curr = find(index);
Object dataItem = curr.getItem();
return dataItem;
}
else {
throw new ListIndexOutOfBoundsException(
"List index out of bounds on get");
} // end if
} // end get
public void add(int index, Object item)
throws ListIndexOutOfBoundsException {
if (index >= 0 && index <= numItems) {
if (index == 0) {
// insert the new node containing item at
// beginning of list
Node newNode = new Node(item, head);
head = newNode;
}
else {
Node prev = find(index-1);
// insert the new node containing item after
// the node that prev references
Node newNode = new Node(item, prev.getNext());
prev.setNext(newNode);
} // end if
numItems++;
}
else {
throw new ListIndexOutOfBoundsException(
"List index out of bounds on add");
} // end if
} // end add
public void remove(int index)
throws ListIndexOutOfBoundsException {
if (index >= 0 && index < numItems) {
if (index == 0) {
// delete the first node from the list
head = head.getNext();
}
else {
Node prev = find(index-1);
// delete the node after the node that prev
// references, save reference to node
Node curr = prev.getNext();
prev.setNext(curr.getNext());
} // end if
numItems--;
} // end if
else {
throw new ListIndexOutOfBoundsException(
"List index out of bounds on remove");
} // end if
} // end remove
public void removeAll() {
// setting head to null causes list to be
// unreachable and thus marked for garbage
// collection
head = null;
numItems = 0;
} // end removeAll
// TO IMPLEMENT
public String toString(){
Node curr = head;
String str = new String("");
while(curr != null){
str += curr.getItem() + ", ";
curr = curr.getNext();
}
return str;
}
// TO IMPLEMENT
public void reverse(){
Node prev = null;
Node curr = head;
while(curr != null){
Node next = curr.getNext();
curr.setNext(prev);
prev = curr;
curr = next;
}
head = prev;
}
// TO IMPLEMENT
// This is a helper method, so try to define your own method
// that this helper will call.
public void reverseRecursive(){
Node prev = null;
Node curr = head;
reverseRecursiveHelper(prev, curr);
head = prev;
}
public Object reverseRecursiveHelper(Node prev, Node curr){
if(curr == null)
return null;
else {
Node next = curr.getNext();
curr.setNext(prev);
prev = curr;
curr = next;
return reverseRecursiveHelper(prev, curr);
}
}
// TO IMPLEMENT
public int getSize()
// --------------------------------------------------
// Returns the number of items in a linked list.
// Precondition: head points to the first element
// in a list of type node.
// Postcondition: The number of items in the list
// is returned.
// --------------------------------------------------
{
int count = 0;
Node curr = head;
while(curr != null){
curr = curr.getNext();
count++;
}
return count;
}
// TO IMPLEMENT
public int getSize(Node cur)
// --------------------------------------------------
// Returns the number of items in a linked list.
// The initial call should have the beginning of the list
// as it's input argument, i.e. listCount(head);
// Precondition: cur points to a list of type node
// Postcondition: The number of items in the list
// is returned.
// --------------------------------------------------
{
if(cur != null)
return 1 + getSize(cur.getNext());
else //base case
return 0;
}
// TO IMPLEMENT
public int getSizeRecursive()
{
return getSize(head);
}
// TO IMPLEMENT
public Node findMToLast(int m){
Node current = head;
if(current == null)
return null;
for(int i = 0; i < m; i++)
if(current.getNext() != null)
current = current.getNext();
else
return null;
Node mBehind = head;
while (current.getNext() != null){
current = current.getNext();
mBehind = mBehind.getNext();
}
return mBehind;
}
} // end ListReferenceBased
Driver:
// ********************************************************
// Test Reference-based implementation of the ADT list.
// *********************************************************
public class TestListReferenceBased {
static public void main(String[] args)
{
ListReferenceBased aList = new ListReferenceBased();
aList.add(0, new Integer(1));
aList.add(1, new Integer(2));
aList.add(2, new Integer(3));
aList.add(3, new Integer(4));
aList.add(4, new Integer(5));
aList.add(5, new Integer(6));
System.out.println("size() and get(i): ");
for (int i = 0; i < aList.size(); i++)
System.out.println(aList.get(i) + " ");
System.out.println();
System.out.println("Size with size() = " + aList.size());
System.out.println("Size with getSize() = " + aList.getSize());
System.out.println("Size with getSizeRecursive() = " + aList.getSizeRecursive());
System.out.println("Initial List = " + aList);
aList.reverse(); // iterative version
System.out.println("Reverse with reverse() = " + aList);
System.out.println("====================================");
aList.reverseRecursive(); // recursive version
System.out.println("Reverse with reverseRecursive() = " + aList);
int offset = 3;
Node node = aList.findMToLast(offset);
if (node != null)
System.out.println(offset + "-th node to the last node contains " + node.getItem() + ".");
else
System.out.println("Offset(=" + offset + ") to the last node is greater than list size(=" + aList.size() + ").");
} // end main
} // end TestListReferenceBased
Stack trace is:
Exception in thread "main" java.lang.NullPointerException at
ListReferenceBased.add(ListReferenceBased.java:63) at
TestListReferenceBased.main(TestListReferenceBased.java:14)
I am having trouble with my int count(int i) function: The function should count the number of occurrences a number appears in the List. For example there is an array of numbers 3 4 4 1 3 2 1
This is what it should display:
Item 0 count = 0
Item 1 count = 2
Item 2 count = 1
Item 3 count = 2
Item 4 count = 2
Item 5 count = 0
class Bag
{
private Node first; //dummy header node
// Initializes the list to empty creating a dummy header node.
public Bag()
{
first = new Node();
}
// Returns true if the list is empty, false otherwise
public boolean isEmpty()
{
return (first.getNext() == null);
}
// Clears all elements from the list
public void clear()
{
first.setNext(null);
}
// Returns the number of item in the list
public int getLength()
{
int length = 0;
Node current = first.getNext();
while (current != null)
{
length++;
current = current.getNext();
}
return length;
}
// Prints the list elements.
public String toString()
{
String list = "";
Node current = first.getNext();
while (current != null)
{
list += current.getInfo() + " ";
current = current.getNext();
}
return list;
}
// Adds the element x to the beginning of the list.
public void add(int x)
{
Node p = new Node();
p.setInfo(x);
p.setNext(first.getNext());
first.setNext(p);
}
// Deletes an item x from the list. Only the first
// occurrence of the item in the list will be removed.
public void remove(int x)
{
Node old = first.getNext();
Node p = first;
//Finding the reference to the node before the one to be deleted
boolean found = false;
while (old != null && !found)
{
if (old.getInfo() == x)
found = true;
else
{
p = old;
old = p.getNext();
}
}
//if x is in the list, remove it.
if (found)
p.setNext(old.getNext());
}
//public int count(int item) {
// int count = 0;
//for(int i = 0; i < length; i++) {
// if(bag[i] == item) {
// count++;
// }
//}
// return count;
//}
// Inner class Node.
private class Node
{
private int info; //element stored in this node
private Node next; //link to next node
// Initializes this node setting info to 0 and next to null
public Node()
{
info = 0;
next = null;
}
// Sets the value for this node
public void setInfo(int i)
{
info = i;
}
// Sets the link to the next node
public void setNext(Node lnk)
{
next = lnk;
}
// Returns the value in this node
public int getInfo()
{
return info;
}
// Returns the link to the next node
public Node getNext()
{
return next;
}
}
}
// Class implementing a linked list.
class LinkedList
{
private Node first; //dummy header node
// Initializes the list to empty creating a dummy header node.
public LinkedList()
{
first = new Node();
}
// Returns true if the list is empty, false otherwise
public boolean isEmpty()
{
return (first.getNext() == null);
}
// Clears all elements from the list
public void clear()
{
first.setNext(null);
}
// Returns the number of item in the list
public int getLength()
{
int length = 0;
Node current = first.getNext();
while (current != null)
{
length++;
current = current.getNext();
}
return length;
}
// Prints the list elements.
public String toString()
{
String list = "";
Node current = first.getNext();
while (current != null)
{
list += current.getInfo() + " ";
current = current.getNext();
}
return list;
}
// Adds the element x to the beginning of the list.
public void add(int x)
{
Node p = new Node();
p.setInfo(x);
p.setNext(first.getNext());
first.setNext(p);
}
// Deletes an item x from the list. Only the first
// occurrence of the item in the list will be removed.
public void remove(int x)
{
Node old = first.getNext();
Node p = first;
//Finding the reference to the node before the one to be deleted
boolean found = false;
while (old != null && !found)
{
if (old.getInfo() == x)
found = true;
else
{
p = old;
old = p.getNext();
}
}
//if x is in the list, remove it.
if (found)
p.setNext(old.getNext());
}
// Returns the element at a given location in the list
public int get(int location)
{
int item = -1;
int length = getLength();
if (location <1 || location > length)
System.out.println("\nError: Attempted get location out of range.");
else
{
int n = 1;
Node current = first.getNext();
while (n < location)
{
n++;
current = current.getNext();
}
item = current.getInfo();
}
return item;
}
/************************************************************************
Students to complete the following two methods for the LinkedList class
***********************************************************************/
// Adds item to the end of the list
public void addEnd(int item)
{
Node currentPos = new Node();
Node newPos = new Node(); //create a new node
newPos.setInfo(item); //load the data
currentPos = first;
while(currentPos.getNext() !=null)
{
currentPos = currentPos.getNext();
}
currentPos.setNext(newPos);
}
// Replaces the info in the list at location with item
public void replace(int location, int item)
{
Node currentPos = new Node();
Node prevPos = new Node();
Node nextPos = new Node();
int length = getLength();
if (location <1 || location > length)
System.out.println("\nError: Attempted get location out of range.");
else
{
prevPos = first;
for(int i=0; i < location-1; i++)
{
prevPos = prevPos.getNext();
}
currentPos = prevPos.getNext();
nextPos = currentPos.getNext();
Node newPos = new Node();
newPos.setInfo(item);
newPos.setNext(nextPos);
prevPos.setNext(newPos);
}
}
// Inner class Node.
private class Node
{
private int info; //element stored in this node
private Node next; //link to next node
// Initializes this node setting info to 0 and next to null
public Node()
{
info = 0;
next = null;
}
// Sets the value for this node
public void setInfo(int i)
{
info = i;
}
// Sets the link to the next node
public void setNext(Node lnk)
{
next = lnk;
}
// Returns the value in this node
public int getInfo()
{
return info;
}
// Returns the link to the next node
public Node getNext()
{
return next;
}
}
}
public class Lab2B2
{
public static void main(String args[])
{
Bag intBag = new Bag();
for (int i =0; i < 10; i++)
{
int info = (int)(Math.random()*10);
intBag.add(info);
}
// Before List
System.out.print("List creation before: " + intBag);
// Counts the # of occurrences of item in the bag
//System.out.println("\nCount the number of occurrences:");
//for(int i = 0; i <= 10; i++)
//{
//System.out.println("Item " + i + " count = " + list.count(i));
//}
// Returns the number of items in the bag
System.out.print("\nLength of List: " + intBag.getLength());
// Adds an item to the bag
intBag.add(9);
System.out.print("\nList creation - Add(9): " + intBag);
// Removes an item from the bag, all occurrences of item in the bag
intBag.remove(8);
System.out.print("\nList creation - Remove(8): " + intBag);
// Removes all of the items from the bag
intBag.clear();
System.out.print("\nList creation - Clear(): " + intBag);
// Determines whether the bag is empty
}
}
you are managing a LinkedList. what you need to do is run over the nodes and check if any of them equals the item you are checking for. in that case, you increase the count.
the code is full of examples how to traverse the list.
The method getLength() is a very good start as it has code that traverses all the elements. with minor modifications, you get what you want.
public int count(int item) {
int count = 0;
Node current = first.getNext();
while (current != null)
{
if (current.getInfo()==item) {
count++;
}
current = current.getNext();
}
return count;
}
Shouldn't you pass an int[] bag as an argument also, since there is no int[] bag declared as a class member?
public int count(int item, int[] bag) {
int count = 0;
for(int i = 0; i < length; i++) {
if(bag[i] == item) {
count++;
}
}
return count;
}
I'm working with a linked list in java and I need to take a list of x objects and move the odd positioned objects to the end of the list.
I have to do it by using linking, no new nodes, no list.data exchanges.
I feel like I have a decent handle when I'm moving stuff from one list to another, but traversing and appending with references to only one list is really tough.
Here's the actual question ---
Write a method shift that rearranges the elements of a list of integers by moving to the end of the list all values that are in odd-numbered positions and otherwise preserving list order. For example, suppose a variable list stores the following values:
[0, 1, 2, 3, 4, 5, 6, 7]
The call of list.shift(); should rearrange the list to be:
[0, 2, 4, 6, 1, 3, 5, 7]
you must solve this problem by rearranging the links of the list.
below is the class that I need to write the method before (with the aforementioned restrictions.
I can't really come up with a plan of attack.
// A LinkedIntList object can be used to store a list of integers.
public class LinkedIntList {
private ListNode front; // node holding first value in list (null if empty)
private String name = "front"; // string to print for front of list
// Constructs an empty list.
public LinkedIntList() {
front = null;
}
// Constructs a list containing the given elements.
// For quick initialization via Practice-It test cases.
public LinkedIntList(int... elements) {
this("front", elements);
}
public LinkedIntList(String name, int... elements) {
this.name = name;
if (elements.length > 0) {
front = new ListNode(elements[0]);
ListNode current = front;
for (int i = 1; i < elements.length; i++) {
current.next = new ListNode(elements[i]);
current = current.next;
}
}
}
// Constructs a list containing the given front node.
// For quick initialization via Practice-It ListNode test cases.
private LinkedIntList(String name, ListNode front) {
this.name = name;
this.front = front;
}
// Appends the given value to the end of the list.
public void add(int value) {
if (front == null) {
front = new ListNode(value, front);
} else {
ListNode current = front;
while (current.next != null) {
current = current.next;
}
current.next = new ListNode(value);
}
}
// Inserts the given value at the given index in the list.
// Precondition: 0 <= index <= size
public void add(int index, int value) {
if (index == 0) {
front = new ListNode(value, front);
} else {
ListNode current = front;
for (int i = 0; i < index - 1; i++) {
current = current.next;
}
current.next = new ListNode(value, current.next);
}
}
public boolean equals(Object o) {
if (o instanceof LinkedIntList) {
LinkedIntList other = (LinkedIntList) o;
return toString().equals(other.toString()); // hackish
} else {
return false;
}
}
// Returns the integer at the given index in the list.
// Precondition: 0 <= index < size
public int get(int index) {
ListNode current = front;
for (int i = 0; i < index; i++) {
current = current.next;
}
return current.data;
}
// Removes the value at the given index from the list.
// Precondition: 0 <= index < size
public void remove(int index) {
if (index == 0) {
front = front.next;
} else {
ListNode current = front;
for (int i = 0; i < index - 1; i++) {
current = current.next;
}
current.next = current.next.next;
}
}
// Returns the number of elements in the list.
public int size() {
int count = 0;
ListNode current = front;
while (current != null) {
count++;
current = current.next;
}
return count;
}
// Returns a text representation of the list, giving
// indications as to the nodes and link structure of the list.
// Detects student bugs where the student has inserted a cycle
// into the list.
public String toFormattedString() {
ListNode.clearCycleData();
String result = this.name;
ListNode current = front;
boolean cycle = false;
while (current != null) {
result += " -> [" + current.data + "]";
if (current.cycle) {
result += " (cycle!)";
cycle = true;
break;
}
current = current.__gotoNext();
}
if (!cycle) {
result += " /";
}
return result;
}
// Returns a text representation of the list.
public String toString() {
return toFormattedString();
}
// Returns a shorter, more "java.util.LinkedList"-like text representation of the list.
public String toStringShort() {
ListNode.clearCycleData();
String result = "[";
ListNode current = front;
boolean cycle = false;
while (current != null) {
if (result.length() > 1) {
result += ", ";
}
result += current.data;
if (current.cycle) {
result += " (cycle!)";
cycle = true;
break;
}
current = current.__gotoNext();
}
if (!cycle) {
result += "]";
}
return result;
}
// ListNode is a class for storing a single node of a linked list. This
// node class is for a list of integer values.
// Most of the icky code is related to the task of figuring out
// if the student has accidentally created a cycle by pointing a later part of the list back to an earlier part.
public static class ListNode {
private static final List<ListNode> ALL_NODES = new ArrayList<ListNode>();
public static void clearCycleData() {
for (ListNode node : ALL_NODES) {
node.visited = false;
node.cycle = false;
}
}
public int data; // data stored in this node
public ListNode next; // link to next node in the list
public boolean visited; // has this node been seen yet?
public boolean cycle; // is there a cycle at this node?
// post: constructs a node with data 0 and null link
public ListNode() {
this(0, null);
}
// post: constructs a node with given data and null link
public ListNode(int data) {
this(data, null);
}
// post: constructs a node with given data and given link
public ListNode(int data, ListNode next) {
ALL_NODES.add(this);
this.data = data;
this.next = next;
this.visited = false;
this.cycle = false;
}
public ListNode __gotoNext() {
return __gotoNext(true);
}
public ListNode __gotoNext(boolean checkForCycle) {
if (checkForCycle) {
visited = true;
if (next != null) {
if (next.visited) {
// throw new IllegalStateException("cycle detected in list");
next.cycle = true;
}
next.visited = true;
}
}
return next;
}
}
// YOUR CODE GOES HERE
}
see it this way:
first we need some sort of cursor that will go through the list and point to our "current" node
second we need some boolean variable (i'll call it INV) initialized as FALSE ... everytime we move a node in the list, we invert INV
if you go through the list from the left, the second element is the first to be rearanged, so that will be our initial cursor position
lets take a reference on that element/node, and keep that reference as abort criteria
start of loop:
now remove the current node from the list and insert it at the end of the list (move to the end ... not that the cursor may not move with the node ...)
move the cursor to the node that is right of the former position of the node we just moved (if that exists)
if the current element is our abort criteria (first element we moved) we can assume the list is sorted now in the desired order -> we are finished -> exit the loop ... if it's not our abort criteria ... go on
evaluate "index of the cursor is even" to either TRUE or FALSE ... XOR that with INV
if the result is TRUE move the cursor to the next element ... if it's FALSE remove the node and insert it at the end (move it to the end)
do the loop
--
this approach will not preserve the order while we move through the list, but will have the list in the desired order when it finishes ...
the INV var is for compensation the index shifts when removing a node ... (0,1,2,3 ... if you remove the 1 and put it at the end, 2 will have an odd index, so if we invert that with every move, we get the "right" elements)