I'm using BlueJ to create an array. The array is of 10 objects inherited from another class.
Now, my problem is that every time I try to find an object within the array (using the findInventoryItem, I get a java.lang.NullPointerException: null error. Now the "inventoryItem" object comes from another class. I am using inventoryItems as the actual array name. the objects that go into it are the inventoryItem of class InventoryItem
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Random;
/**
* THIS IS THE MODIFIED VERSION OF THE ARRAY LIST MANAGER CLASS
*
* #author RAGEED A BASRAWI
* #version VERSION 1
*/
public class HomeInventoryManagerARRAYClass
{
private InventoryItem inventoryItem;
private InventoryItem[] inventoryItems;
/**
* Initialise the home inventory manager.
*/
public HomeInventoryManagerARRAYClass()
{
InventoryItem inventoryItem;
inventoryItems = new InventoryItem[10];
}
/**
* Add an inventory item to the list.
*
*/
public void addInventoryItem(InventoryItem inventoryItem)
{
Random random = new Random();
inventoryItems[random.nextInt(9 - 0 + 1) + 0] = inventoryItem;
}
/**
* Try to find an inventory item in the inventory list with the given partNumber.
*
*/
public InventoryItem findInventoryItem(int partNumber)
{
for(int index = 0; index < 9; index ++)
{
if (inventoryItem.getPartNumber() == partNumber)
{
return inventoryItem;
}
if (inventoryItem.getPartNumber() != partNumber)
{
System.out.println("The entry " + partNumber + " does not exist. Pleast try again.");
}
}
return inventoryItem;
}
/**
* Locate an inventory item with the given partNumber, and return how
* many of this item are in inventory. If the partNumber does not
* match any item, return zero.
*/
public int numberInInventory(int partNumber)
{
InventoryItem inventoryItems = findInventoryItem(partNumber);
if(inventoryItems != null)//There aren't too many ways to write a statement to be NOT NULL. Its kind of annoying... -___-
{
return inventoryItems.getQuantity();
}
else
{
return 0;
}
}
/**
* Return the total number of items in inventory.
*
*/
public int numberInInventoryList()
{
return inventoryItems.length;
}
/**
* Print details of all the home inventory items.
*/
public void printInventoryList()
{
int index = 0;
while(index < inventoryItems.length)
{
System.out.println(inventoryItem = inventoryItems[index]);
index ++;
}
}
public int totalNumberInInventory()
{
int index = 0;
int absoluteInventory = 0;
while (index < inventoryItems.length)
{
InventoryItem inventoryItem = inventoryItems[index];
absoluteInventory += inventoryItem.getQuantity();
index ++;
}
return absoluteInventory;
}
}
inventoryItems[random.nextInt(9 - 0 + 1) + 0] = inventoryItem;
if you initialize the array with the line above, how do you make sure that all elements of the array are initialized? It's generating a random number and doesn't guarantee all elements between 0 to 9 are initialized.
Remember that with this line:
inventoryItems = new InventoryItem[10];
you are initializing your array, not its elements. When running functions again each array's element you should be sure that you have initialized the element itself.
For example :
InventoryItem[i].getPartNumber()
this line of code should be executed before
InventoryItem[i] = new InventoryItem();
As #Jahoy has mentioned, it's likely that the elements in the array that you are accesing are null. It is essential firstly to check if an element exists in the first place.
Your FindInventoryItem function should be like this I think:
public InventoryItem findInventoryItem(int partNumber)
{
for(int index = 0; index < 9; index ++)
{
InventoryItem tempItem = inventoryItems[index]; // ADD THIS LINE HERE
if(tempItem != null)
{
if (tempItem.getPartNumber() == partNumber)
{
return tempItem;
}
if (tempItem.getPartNumber() != partNumber)
{
System.out.println("The entry " + partNumber + " does not exist. Please try again.");
}
}
}
// at this stage you've got no result, I dont really know what you want to return
return inventoryItem;
}
Related
This question already has answers here:
How to override toString() properly in Java?
(15 answers)
Closed 4 years ago.
I have been provided with an object and several methods to work with it. I am having a tough time printing the string that I am assigning to the variables. At the moment, I am unsure if I assigning new values at all and I am unable to print any values. Previous iterations have only printed references.
Question: Am I assigning new string values? How do I print a string with the given methods?
Here is the code I was provided
public class Team implements Comparable<Team> {
public String toString(String team, int wins) {
return team + ": " + wins;
}
// Data fields
private String name;
private int winCount;
Team() {
name = "Sooners";
winCount = 1;
}
Team(String inputName) {
name = inputName;
winCount = 1;
}
Team(String inputName, int inputWinCount) {
name = inputName;
winCount = inputWinCount;
}
// ----------------------------------------------------
// Getters and Setters
/**
* #return the name
*/
public String getName() {
return name;
}
/**
* #param name
* the name to set
*/
public void setName(String name) {
this.name = name;
}
/**
* #return the winCount
*/
public int getWinCount() {
return winCount;
}
/**
* #param winCount
* the winCount to set
*/
public void setWinCount(int winCount) {
this.winCount = winCount;
}
/**
* Increments the winCount variable by one for this Team
*/
public void incrementWinCount() {
winCount++;
}
/**
* This method allows you to check to see if this Team object has the same
* name as another Team object.
*
* This method allows you to use the contains method in ArrayList to see
* if any element in an array list has the same name as a specific Team.
*
* #param o
* the other Team being compared to.
*/
#Override
public boolean equals(Object o) {
return name.equals(((Team) o).name);
}
/**
* This method allows you to check to see if this Team object has the same
* name as another Team object
*
* #param otherTeam
* one team
*/
public boolean sameName(Team otherTeam) {
return name.equals(otherTeam.name);
}
/**
* This method allows you to check to see if this Team object has the same
* name as another Team object
*
* #param team1
* one team
* #param team2
* the other team
*/
public static boolean sameName(Team team1, Team team2) {
return team1.name.equals(team2.name);
}
/**
* This method allows you to sort an ArrayList of Team items using
* Collections.sort
*
* #param o
* the other Team being compared to.
* #return -1 if this Team item should come first, +1 if this Team item
* should come after the other, and 0 if this Team item is
* equivalent to the other.
*/
#Override
public int compareTo(Team o) {
if (this.winCount < o.winCount) {
return -1;
} else if (this.winCount > o.winCount) {
return 1;
}
return 0;
}
}
Here is my current code
Scanner scnr = new Scanner(System.in);
Random rando = new Random();
String name = "no";
int cycles = 0;
int value = 0;
int match = 0;
ArrayList<Team> teams = new ArrayList<Team>();
Team newTeam = new Team(name,1);
System.out.println("Welcome to the Advanced Sportsball Tracker!");
while (!name.equals("x")) // looping print statement
{ // x loop begins
System.out.println("Which team just won? (x to exit)");
match = 0;
cycles++;
name = scnr.next();
for (Team list : teams)
{
if (list.getName().equals(name)) // compares the name of the team to the input value
{
match++;
}
}
if (match == 0)
{
teams.add(newTeam);
}
}// x loop ends
System.out.print(newTeam.getName());
if (cycles == 1) // prints no data if user immediately exits
{
System.out.println("No data input");
}
if (cycles > 1)
{
System.out.println("Final Tally: "); // loop to print final Talley
for (Team list : teams) // FIXME
{
list.toString(list.getName(),list.getWinCount()); // makes a string out of the string and wincount of the team
}
What was the original code for the toString method they gave you? Did you add the parameters? A better way to do this would be to let the object use it's data fields inside of the method. Passing in the member variables in your for loop is unnecessary, and just bad code. Instead, you want to do something like this:
public String toString() {
return name + ": " + wins;
}
And in your loop, if you want to print the results, simply do this:
System.out.print(list.toString());
I want a class, that take in a possitive integer and produce a iterator that let me iterate through all possible of permutation of a list of possitive numbers under the positive integer.
eg. permulator p = paermulator(3)
p.next() -> [0,1,2]
p.next() -> [0,2,1]
p.next() -> [1,0,2]
p.next() -> [1,2,0]
...
which is 6 possible permutations in this case.
I have designed a class, but it is incredibly slow, I want to make iterate faster.
This is my design:
(I am doing it pruely for that sake that it seems possible. )
package Mathematica.complexity;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.NoSuchElementException;
/**
* Tthis will be a class that demonstrate what we call:
* a factorial complexity algorithm
* it's going to print all the possible permutations of some sort of collection
* in java.
* <br>
* A recursive data structure that resembles the process of permutating.
* #author dashie
*
*/
public class FactorialComplexity implements Iterator<List<Integer>>
{
private List<Integer> G_Data;
// sub recursive structure of the class.
private FactorialComplexity G_next = null;
private int G_ChoosenIndex = 0;
private boolean G_canProduceNextElement= true;
public static void main(String[] args)
{
}
public FactorialComplexity(int NumbersofElements)
{
if(NumbersofElements <0)throw new AssertionError();
this.G_Data = new LinkedList<>();
for(int i =0; i< NumbersofElements;i++)this.G_Data.add(i);
this.prepareSubStructure();
}
protected FactorialComplexity(List<Integer> argIn)
{
this.G_Data = argIn;
this.prepareSubStructure();
}
/**
* Using the internal index to return the current element it is
* pointing at.
* <br></b>I doesn't increment the internal pointer. </b>
* #return
*/
public Integer getChoosenElement()
{
//if(this.G_Data.size() == 0)return null;
return this.G_Data.get(this.G_ChoosenIndex);
}
/**
* This function serves for the iterator.
* #return
*/
public List<Integer> getPermutation()
{
// two of the base case.
if(this.G_Data.size()==0)
{
return new LinkedList<>();
}
if(this.G_Data.size()==1)
{
List<Integer> temp = new LinkedList<>();
temp.add(this.G_Data.get(0));
return temp;
}
return this.getPermutation_part1(new LinkedList<Integer>());
}
private List<Integer> getPermutation_part1(List<Integer> argIn)
{
argIn.add(getChoosenElement());
argIn.addAll(this.G_next.getPermutation());
return argIn;
}
/**
* <ol>
* <li>If the sub-structure has next element, increment the sub structure.
* <li>If not, increment the index in this instance and recreate sub structure.
* <li>be careful about the base case please.
* </ol>
*
* #return
* if this, including sub structure should be incremented.
*
*/
protected boolean increment()
{
if(this.G_next!= null)
{
boolean temp = this.G_next.increment();
int pointer = this.G_ChoosenIndex;
if(this.G_ChoosenIndex+1<this.G_Data.size())
{
if(temp)
{
this.G_ChoosenIndex++;
this.prepareSubStructure();
}
return false;
}
else
{
return (this.G_ChoosenIndex+1 == this.G_Data.size())&&temp;
}
}
else
{
//empty means not choice can make.
return true;
}
}
#Override
/**
* All the nodes are at its last index.
*/
public boolean hasNext()
{
if(!this.G_canProduceNextElement)return false;
if(this.isAllPointingAtLastIndex())this.G_canProduceNextElement=false;
return true;
}
/**
* This index in this class instance and
* all its sub structure are pointing at the last index?
* #return
*/
boolean isAllPointingAtLastIndex()
{
if(this.G_Data.size()<=1)
{
return true;
}
return this.G_ChoosenIndex+1
==
this.G_Data.size()&&this.G_next.isAllPointingAtLastIndex();
}
#Override
public List<Integer> next()
{
List<Integer> result = this.getPermutation();
this.increment();
return result;
}
public String toString()
{
String s = new String();
s+= this.G_Data+":"+this.G_ChoosenIndex+"->";
if(this.G_next!= null)s+= this.G_next.toString();
return s;
}
/**
* <ol>
* <li>Base case: the list in this instant is empty.
* <li>Make a copy of the local collection, excluding the
* element the pointer is pointing to
* <li>Make connect the this object to its sub structure and recurse.
* </ol>
*/
protected void prepareSubStructure()
{
if(this.G_Data.size() == 0)return;
List<Integer> temp = new LinkedList<>();
temp.addAll(this.G_Data);
temp.remove(this.G_ChoosenIndex);
this.G_next = new FactorialComplexity(temp);
this.G_next.prepareSubStructure();
}
public static int factorial(int n)
{
if(n<0)return 0;
if(n<=1)return 1;
return n*factorial(n-1);
}
}
To summarize:
The class is recursive like a linked list, each node contains the an index that indicate the element it is pointing at and a list of all the element got passed from the previouse node.
How Naive is this approach? How can I make it faster?
This is a better solution, inspired by https://stackoverflow.com/a/10117424/312172
To achieve, instead of getting a list of elements that are jumbled, we focus on the choices we make when deducting elements from the list.
give the function a size, and a number that is smaller than factorial(size); it will return a sequence of choices we need to make to get the permutation.
for example:
getTheIndexOfSelection(100,5)-> for a list of 5 elements, we want the 100th permutation.
it should output: [4, 0, 2, 0, 0]
it means, remove the element at index 4, for the list that got removed, remove element at 0 ....
if the list is[1,2,3,4,5]; this will be the procujure:
[1,2,3,4,5] remove index 4 -> 5
[1,2,3,4] remove index 0 -> 1
[2,3,4] remove index 2 -> 4
[2,3] rovmove index 0 -> 2
[3] remove index 0 -> 3
all the element we removed sequentially is the permutation.
/**
* Feed this function a number, it gives you a sequence of choices
* to make a permutation.
* <br>
* if this return [0,0,0,0]
* it means remove element at 0, and then remove again... until
* reaches the end.
* #return
*
* #param
* len: the length of the list
* n: the number that got match to a certain permutation.
*/
public static int[] getTheIndexOfSelection(int n, int size)
{
int[] lst = new int[size];
return getTheIndexOfSelection( n, size, 0, lst);
}
private static int[] getTheIndexOfSelection(int n, int size, int index, int[] lst)
{
if(size==1)
{
int[] result = {0}; // a list of one element, you can only choose the one that is in it
// which is at index 0;
return result;
}
if(n >= factorial(size))return null; // This is not possible to do.
size-=1;
int firstchoice = n/factorial(size);
lst[index] = firstchoice;
n = n-firstchoice*factorial(size);
if(size>1)return getTheIndexOfSelection(n ,size, index+1, lst);
return lst;
}
This is a better solution because:
The speed really depends on the factorial function, assume factorial is super fast, this will be o(n).
It matches numbers to permutation, making the expandable for things like map and iterator.
It is not the full solution, the part that is left to solve do is pretty much trivial by now.
An implementation using Heap's Algorithm. It compute next permutations on the fly. And have only one array copying
import java.util.Arrays;
import java.util.Iterator;
class Permutator<E> implements Iterator<E[]>{
E[] arr1 = null;
E[] arr2 = null;
int size;
int[] stack = null;
int index = 0;
public Permutator( E[] arr ){
if( arr.length > 0 ){
arr1 = arr;
size = arr1.length;
arr2 = Arrays.copyOf(arr1, size);
stack = new int[size];
Arrays.fill(stack, 0);
}
}
#Override
public boolean hasNext() {
return (null != arr1 && arr1.length > 0);
}
#Override
public E[] next() {
// start computing.
// We will return original array as value of last permutation.
// This is to make "hasNext() " implementation easy.
updateValue();
return arr2;
}
protected void updateValue(){
boolean bret = false;
for( ; index < size ; ){
if( stack[index] < index ){
if( index %2 == 0 ){
swap(0, index);
}else{
swap(stack[index], index);
}
stack[index]++;
index = 0;
bret = true;
break;
}else{
stack[index] = 0;
index++;
}
}
if( !bret ){
// No more permutation available.
// Set the original array as return value.
// Also set arr1 = null , so that hasNext() will return false for next test
arr2 = arr1;
arr1 = null;
}
}
private void swap (final int i, final int j) {
E temp = arr2[i];
arr2[i] = arr2 [j];
arr2[j] = temp;
}
}
Usage:
public static void main(String[] args) {
Permutator<Integer> perm = new Permutator<Integer>(new Integer[]{1,2,3, 4, 5});
int count = 0;
while(perm.hasNext()){
System.out.println(Arrays.toString(perm.next()));
count++;
}
System.out.println("total: " + count);
}
I'm currently working on a university assignment which involves implementing sorting algorithms. I believe I have correctly implemented the quicksort algorithm, however in the test class the method just prints out the array being read in without sorting it. Below is the code from the test class, and the code for the actual quicksort(which is in a seperate class called 'sort').
Has anyone got any idea what I'm doing wrong?
import java.io.*;
import java.text.*;
import java.util.*;
public class Sort {
/** Array of integers to sort **/
private int[] A;
/** Size of the array **/
private int size;
/** Number of elements actually used in array **/
private int usedSize;
/** Global variables for counting sort comparisons **/
public int compIS;
/** Global comparison count for Insertion Sort **/
public int compQS;
/** Global comparison count for Quicksort **/
public int compNewS;
/** Global comparison count for new sort **/
/*****************/
/** Constructor **/
/*****************/
Sort(int max) {
/** Initialiase global sort count variables **/
compIS = 0;
compQS = 0;
compNewS = 0;
/** Initialise size variables **/
usedSize = 0;
size = max;
/** Create Array of Integers **/
A = new int[size];
}
public int getRightElement() {
return usedSize - 1;
}
public int getLeftElement() {
return A[0];
}
/*********************************************/
/*** Read a file of integers into an array ***/
/*********************************************/
public void readIn(String file) {
try {
/** Initialise loop variable **/
usedSize = 0;
/** Set up file for reading **/
FileReader reader = new FileReader(file);
Scanner in = new Scanner(reader);
/** Loop round reading in data while array not full **/
while (in.hasNextInt() && (usedSize < size)) {
A[usedSize] = in.nextInt();
usedSize++;
}
} catch (IOException e) {
System.out.println("Error processing file " + file);
}
}
/**********************/
/*** Display array ***/
/**********************/
public void display(int line, String header) {
/*** Integer Formatter - three digits ***/
NumberFormat FI = NumberFormat.getInstance();
FI.setMinimumIntegerDigits(3);
/** Print header string **/
System.out.print("\n" + header);
/** Display array data **/
for (int i = 0; i < usedSize; i++) {
/** Check if new line is needed **/
if (i % line == 0) {
System.out.println();
}
/**
* Display an ar ray element
**/
System.out.print(FI.format(A[i]) + " ");
}
}
public void quick(int L, int R) {
/* ensure there is more than one element in array */
if (R > L) {
/* split array in two */
int pLoc = partition(L, R);
/* sort left half */
quick(L, pLoc - 1);
/* sort right half */
quick(pLoc + 1, R);
}
System.out.println("\n\nAfter QuickSort: ");
for (int i = 0; i < usedSize; i++) {
System.out.println(A[i] + " ");
}
}
/* partitions array for quicksort */
public int partition(int L, int R) {
/* Select pivot */
int pivot = A[R];
/* initialise scanning pointers */
int pR = R;
int pL = L;
/* repeat until pointers cross */
while (pL < pR) {
compQS++;
/* move left pointer */
while (A[pL] < pivot) {
pL++;
}
/* move right pointer */
while ((A[pR] >= pivot) && (pR > L)) {
pR--;
//compQS++;
}
/* swap elements */
//compQS++;
if (pL < pR) {
swap(pL, pR);
L++;
R--;
}
}
/* put pivot in correct position */
swap(pL, R);
/* return pivot position */
return pL;
}
/* swaps elements in quicksort */
public void swap(int i, int j) {
int temp = A[i];
A[i] = A[j];
A[j] = temp;
}
public class TestSort
{
public static void main(String[] args)
{
Sort sortTest = new Sort(100);
/** Read in test data into array **/
sortTest.readIn("test1.txt");
/** Display array **/
sortTest.display(10,"Input Array 1");
/*apply insertion sort to array*/
//sortTest.insertion();
//sortTest.readIn("test1.txt");
sortTest.quick(sortTest.getLeftElement(), sortTest.getRightElement());
sortTest.newSort();
/** Display comparison counters **/
System.out.println("Quicksort comparison counter: " + sortTest.compQS);
System.out.println("\n\nInsertion sort comparison counter: " + sortTest.compIS);
}
One of your problems is that getLeftElement() is returning the value at position 0 within your array instead of just returning 0. In situations in which the value of the first element in the array is greater than the size of the array, no sorting will be done.
Also, I believe that your implementation of the method quick is incorrect. Within the method you recursively invoke quick(L, pLoc - 1)
and quick(pLoc + 1, R). By invoking in this manner, you do not traverse all indices of the array in your array. (Ex if L is 0, R is 10, and pLoc is 5, then you do not involve the index 5 in the sorting of your array.)
Im trying to make a PhoneBook using array list but I'm not getting the right output here is my code, thank you for any help with this, the output I'm getting now is just a zero when i ask for the size, not seeming to add anyone, that is probably where the problem lies
import java.util.ArrayList;
public class Phonebook implements Directory
{
private ArrayList<Person> book;
public Phonebook ()
{
book = new ArrayList<Person>();
}
/**
* will return the number of entries currently entered in
* the <code>Directory</code>.
* #return - the number of valid entries in the <code>Directory</code>.
**/
public int size()
{
return book.size();
}
/**
* will display the entries currently entered in the <code>Directory</code>.
**/
public void listAll()
{
for(int i = 0; i < book.size(); i++)
{
System.out.println(book.get(i));
}
}
/**
* will add a new record to the <code>Directory</code> in alphabetical order
* if the name is not a duplicate entry. Otherwise no changes will be made.
* #param name - name of individual to be added to the <code>Directory</code>.
* #param number - phone number of the individual to be added.
* #return - true if the entry was added successfully, otherwise false.
**/
public boolean addPerson(String name, String number)
{
Person x = new Person (name, number);
if (checkPerson(name) == -1)
return false;
int index = 0;
while(index < book.size())
{
if((x.getName().compareTo((book.get(index)).getName())) < 0)
{
book.add(x);
return true;
}
index++;
}
return false;
}
public int checkPerson(String name)
{
int lo = 0;
int hi = book.size() - 1;
while(lo <= hi)
{
int half = (lo + hi) / 2;
if(name.equals(book.get(half).getName()))
return half;
if(name.compareTo(book.get(half).getName()) < 0){
hi = half - 1;}
else lo = half + 1;
}
return -1;
}
/**
* will remove an entry from the <code>Directory</code> if the name parameter
* is currently in the <code>Directory</code>. Otherwise no changes
* will be made.
* #param name - individual to be removed from the <code>Directory</code>.
* #return - true if the entry was successfully removed, otherwise false.
**/
public boolean removePerson(String name)
{
if (checkPerson(name) == -1)
return false;
book.remove(checkPerson(name));
return true;
}
/**
* will search the <code>Directory</code> to find out if the name passed in
* is currently in the <code>Directory</code>. If so, it will return the
* phone number associated with this person. Otherwise it will return null.
* #param name - name of individual to look up in the <code>Directory</code>.
* #return - the phone number if the name was found, otherwise null.
**/
public String lookUp(String name)
{
Person n = new Person (name, "999-9999");
int local = checkPerson(n.getName());
if(local == -1)
return null;
return book.get(local).getNumber();
}
/**
* will search the <code>Directory</code> to find out if the phone number
* is currently in the <code>Directory</code>. If so, it will return the
* name associated with this number. Otherwise it will return null.
* #param number - name of individual to look up in the <code>Directory</code>.
* #return - the name of the person if the number was found, otherwise null.
**/
public String lookUpNum(String number)
{
for(int i = 0; i <book.size(); i++)
{
if(number.equals(book.get(i).getNumber()))
return book.get(i).getName();
}
return null;
}
}
/**
* The Person class is a container class to hold the
* name and phone number of an individual. There are methods
* to access the name and number, and modify the name and number.
* Each name is stored in "Last, First" form to facilitate searching
* and sorting of persons. A private helper method is used to be
* sure that names entered in "First Last" form are converted to
* the proper format.
*/
public class Person implements Comparable<Person>
{
private String first;
private String last;
private String name; // Last, First
private String number;
/**
* explicit constructor, will store the first and last
* names, as well as the entire name in Last, First order
*
* #param na is the name of the individual
* #param nu is the phone number of the individual
*/
public Person(String na, String nu)
{
convert(na);
number = nu;
}
/**
* copy constructor, will make an exact copy of the parameter
*
* #param per is the <B>Person</B> to be duplicated
*/
public Person(Person per)
{
first = per.first;
last = per.last;
name = per.name;
number = per.number;
}
/**
* accessor method to return the name of <B>this Person</B>
*
* #return the name of the individual in Last, First order
*/
public String getName()
{
return name;
}
/**
* accessor method to return the phone number of <B>this Person</B>
*
* #return the phone number of the individual
*/
public String getNumber()
{
return number;
}
/**
* modifier method to set a new name for <B>this Person</B>
* The helper method convert() is called to handle the details
*
* #param the new name for the individual
*/
public void setName(String na)
{
convert(na);
}
/**
* modifier method to set a new phone number <B>this Person</B>
* just in case somebody needs to enter witness protection
*
* #param the new phone number for the individual
*/
public void setNumber(String num)
{
number = num;
}
/**
* accessor method that implements the <B>Comparable interface</B>
* based on the name field for <B>this Person</B>
* will return a positive number if <B>this</B> is greater than oth
* zero if <B>this</B> is equal to oth
* and a negative number if <B>this</B> is less than oth
*
* #return negative, zero, or positive int as per Comparable interface
*/
public int compareTo(Person oth)
{
return name.toUpperCase().compareTo(oth.name.toUpperCase());
}
/**
* accessor method to test if the instance data for <B>this Person</B>
* is equal to the instance data for oth
*
* #return true if names and numbers match, false otherwise
*/
public boolean equals(Person oth)
{
return name.toUpperCase().equals(oth.name.toUpperCase()) && number.equals(oth.number);
}
private void convert(String na)
{
if(na.indexOf(" ") == -1)
{
last = na;
first = null;
name = na;
}
else if(na.indexOf(",") != -1)
{
name = na;
first = na.substring(na.indexOf(",") + 2);
last = na.substring(na.indexOf(","));
}
else
{
first = na.substring(0, na.indexOf(" "));
last = na.substring(na.indexOf(" ") + 1);
name = last + ", " + first;
}
}
/**
* accessor method to return the instance data of <B>this Person</B>
* in a formatted String (24 character name field, followed by the number)
*
* #return name in Last, First order followed by the phone number
*/
public String toString()
{
String local = name;
if(name.length() < 8)
local += "\t";
if(name.length() < 16)
local += "\t";
local += "\t" + number;
return local;
}
}
public class client
{
public static void main(String[] args)
{
Phonebook nickBook = new Phonebook();
nickBook.addPerson("name lastname", "321-3256");
System.out.println();
nickBook.listAll();
System.out.println(nickBook.size());
}
}
Your addPerson method won't add the Person if the list is empty, since while (0 < 0) will be false, and the loop won't be entered :
int index = 0;
while(index < book.size())
{
if((x.getName().compareTo((book.get(index)).getName())) < 0)
{
book.add(x);
return true;
}
index++;
}
Beside that problem, book.add(x); will always add the new Person to the end of the List, which is not what you want. You should use book.add(index,x), assuming index is the location in which you wish to add the new Person.
Finally, if the new Person wasn't added inside the while loop, that means this Person should be the last Person on the List, so you have to add it to the end of the List after the loop.
A possible implementation :
public boolean addPerson(String name, String number)
{
Person x = new Person (name, number);
if (checkPerson(name) == -1)
return false;
int index = 0;
while(index < book.size())
{
if((x.getName().compareTo((book.get(index)).getName())) < 0)
{
book.add(index,x);
return true;
}
index++;
}
book.add(x); // this handles both the case of an empty List and the
// case in which the new Person should be the last Person
// on the list
return true;
}
Your function checkPerson is wrong. book.size() is 0 in the beginning and the hi results to -1 which means that it does not enter the loop. Besides that think about your half variable. It is possible that this results in another number than an integer which is not allowed if you are using this variable as an index for a query of the list.
public int checkPerson(String name)
{
int lo = 0;
int hi = book.size() -1;
while(lo <= hi)
{
int half = (lo + hi) / 2;
if(name.equals(book.get(half).getName()))
return half;
if(name.compareTo(book.get(half).getName()) < 0){
hi = half - 1;}
else lo = half + 1;
}
return -1;
}
I am working on a program that checks the validity of a sudoku solution. I am close to having it finished, but for some reason when I try to call certain methods I have created, the compiler returns that they are undefined.
There are three main classes:
A sudoku class, which implements the iterable interface. It contains a two dimensional array that is the puzzle. The constructor takes a file from scanner input and builds the puzzle. It has a iterator method to satisfy the interface requirements. This method returns an interator of type SudokuIterator.
A SudokuIterator class, which implements the Iterator Interface. This is a private inner class of the Sudoku class. It also has a 2 dimensional array and a cursor as attributes. It has the standard hasNext(), next(), and a remove() stub to satisfy the interface. I have also added a nextColumn() and nextBox() that return an array based on the cursor position. The next method has been overridden to return rows.
Finally is the Validator. This method is the main method. It has a method isSolution() that returns a boolean depending on analysis of each array returned from methods defined in the SudokuIterator Class.
And this is where my problems arise; when use the iterator method to instantiate and return a SudokuIterator and try to then use my added nextColumn() and nextBox() methods, the compiler returns that those methods are undefined for Iterator.
Any advice or suggestions would be much appreciated. Thanks in advance.
import java.util.*;
/**
* Sudoku class represents the matrix of cells in a Sudoku puzzle
* #version 01/05/2012
* #author Bob Wilson
*/
public class Sudoku implements Iterable<Cell []>
{
private Cell [] [] puzzle;
/**
* Default constructor should not be called. Make it private.
*/
private Sudoku() {}
/**
* Puzzle constructor that uses a Scanner object to read a file.
* File contains 81 numbers that are the values of the 81 cells.
* #param file a Scanner object on a File object
*/
public Sudoku(Scanner file)
{
int size = file.nextInt();
System.out.println("Size: " + size);
puzzle = new Cell[size][size];
for (int i = 0; i < size; i++)
for (int j = 0; j < size; j++)
puzzle[i][j] = new Cell(file.nextInt());
}
public int getLength(){
return this.puzzle.length;
}
class SudokuIterator implements Iterator<Cell []> {
private Cell [][] puzzle;
private int cursor;
public SudokuIterator(Cell [][] puzzle){
this.puzzle = puzzle;
cursor = 1;
}
public boolean hasNext(){
if(cursor <= this.puzzle.length){
return true;
}
return false;
}
public Cell[] next(){
Cell[] row = puzzle[cursor-1];
cursor++;
return row;
}
public Cell[] nextColumn(){
Cell[] column = new Cell[puzzle.length];
for(int i = 0; i < puzzle.length; i++){
column[i] = puzzle[i][cursor-1];
}
cursor++;
return column;
}
public Cell[] nextBox(){
Cell[] box = new Cell[puzzle.length];
int boxIndex = 0;
for(int i = ((cursor - 1)/((int)Math.sqrt(puzzle.length)))*(int)Math.sqrt(puzzle.length) ; i < ((cursor - 1)/((int)Math.sqrt(puzzle.length)))*(int)Math.sqrt(puzzle.length) + (int)Math.sqrt(puzzle.length); i++){
for(int j = (((cursor - 1) + ((int)Math.sqrt(puzzle.length))) % ((int)Math.sqrt(puzzle.length))) * ((int)Math.sqrt(puzzle.length)); j < (((cursor - 1) + ((int)Math.sqrt(puzzle.length))) % ((int)Math.sqrt(puzzle.length))) * ((int)Math.sqrt(puzzle.length)) + ((int)Math.sqrt(puzzle.length)); j++){
box[boxIndex] = puzzle[i][j];
}
}
cursor++;
return box;
}
public void remove(){}
}
/**
* Generates and returns a String representation of the puzzle cells
* #return A String representing the contents of the puzzle array
*/
public String toString()
{
// display the puzzle
String value = "Puzzle is:\n";
for (int i = 0; i < puzzle.length; i++) {
for (int j = 0; j < puzzle[i].length; j++)
value += puzzle[i][j].toString();
value += "\n";
}
return value;
}
/**
* Instantiates and returns a new SudokuIterator object
* #return A SudokuIterator object on the puzzle array
*/
public SudokuIterator iterator(){
SudokuIterator iterator = new SudokuIterator(this.puzzle);
return iterator;
}
}
/* 201340 */
import java.util.*;
import java.io.*;
/**
* This class instantiates a Sudoku object passing a Scanner on a
* file to the Sudoku constructor. It prints the puzzle using the
* Sudoku toString method. It determines if the digit matrix is a
* valid solution for a Sudoku puzzle or not and prints the result.
*
* #version 01/05/2012
* #author Bob Wilson
*
*/
public class SudokuValidator
{
private Sudoku puzzle;
/**
* #param args - not used
*/
public static void main( String [] args)
{
Scanner scan = new Scanner(System.in);
System.out.println("Please enter name of file containing puzzle to verify");
SudokuValidator myValidator = new SudokuValidator(scan.nextLine());
System.out.println(myValidator.isSolution());
}
public SudokuValidator(String fileName)
{
Scanner file = null;
try
{
file = new Scanner(new File(fileName));
}
catch (Exception e)
{
System.out.println("Bad file name");
System.exit(0);
}
puzzle = new Sudoku(file);
System.out.println(puzzle);
}
public boolean isSolution(){
boolean flag = true;
Iterator<Cell[]> game = puzzle.iterator();
while(game.hasNext()){
Cell[] row = game.next();
Cell[] column = game.nextColumn();
Cell[] box = game.nextBox();
for(Cell i: row){
for(Cell j: row){
if(j.equals(i.getValue())){
flag = false;
return flag;
}
}
}
}
return flag;
}
} /* 201340 */
The issue is, the declared type of game reference variable is Iterator, which doesn't define any nextColumn() method, so compiler cannot find it. You can fix this by changing the declared type to Sudoku.SudokuIterator (Since that is an inner class).
Change:
Iterator<Cell[]> game = puzzle.iterator();
to:
Sudoku.SudokuIterator game = puzzle.iterator();