I'm trying to implement an algorithm for Huffman coding, I have a very simple code at the moment that works fine. In my code, the weight of the character is based on the frequency of occurrence of that character, however I would like to improve it so that it meets the following criteria:
I would like my code to consider the order in which a node is encountered. For example if ’e’ and ’ ’ have the same frequency, but ’e’ occurs first, its weight would be considered greater. I have been trying to implement this for my code but it seems to give me mixed results.
Here is what I have. Any input on how to go about this would be greatly appreciated. I apologize in advance if this is too simple, but I'm a student and still learning.
import java.util.ArrayList;
public class Huffman {
static Node node;
static Node newRoot;
static String codedString = "";
public static void main(String[] args) {
String message = "'twas brillig, and the slithy toves did gyre and gimble in the wabe: all mimsy were the borogoves, and the mome raths outgrabe. "
+ "\"beware the jabberwock, my son! the jaws that bite, the claws that catch! beware the jubjub bird, and shun the frumious bandersnatch!\" "
+ "he took his vorpal sword in hand: long time the manxome foe he sought -- so rested he by the tumtum tree, and stood awhile in thought. "
+ "and, as in uffish thought he stood, the jabberwock, with eyes of flame, came whiffling through the tulgey wood, and burbled as it came! "
+ "one, two! one, two! and through and through the vorpal blade went snicker-snack! he left it dead, and with its head he went galumphing back. "
+ "\"and, has thou slain the jabberwock? come to my arms, my beamish boy! o frabjous day! callooh! callay!\" "
+ " he chortled in his joy. 'twas brillig, and the slithy toves did gyre and gimble in the wabe; "
+ " all mimsy were the borogoves, and the mome raths outgrabe.";
// Convert the string to char array
char[] msgChar = message.toCharArray();
ArrayList<Character> characters = new ArrayList<Character>();
/*
* Get a List of all the chars which are present in the string No
* repeating the characters!
*/
for (int i = 0; i < msgChar.length; i++) {
if (!(characters.contains(msgChar[i]))) {
characters.add(msgChar[i]);
}
}
/* Print out the available characters */
// System.out.println(characters);
/* Count the number of occurrences of Characters */
int[] countOfChar = new int[characters.size()];
/* Fill The Array Of Counts with one as base value */
for (int x = 0; x < countOfChar.length; x++) {
countOfChar[x] = 0;
}
/* Do Actual Counting! */
for (int i = 0; i < characters.size(); i++) {
char checker = characters.get(i);
for (int x = 0; x < msgChar.length; x++) {
if (checker == msgChar[x]) {
countOfChar[i]++;
}
}
}
/* Sort the arrays is descending order */
for (int i = 0; i < countOfChar.length - 1; i++) {
for (int j = 0; j < countOfChar.length - 1; j++) {
if (countOfChar[j] < countOfChar[j + 1]) {
int temp = countOfChar[j];
countOfChar[j] = countOfChar[j + 1];
countOfChar[j + 1] = temp;
char tempChar = characters.get(j);
characters.set(j, characters.get(j + 1));
characters.set(j + 1, tempChar);
}
}
}
/* Print Out The Frequencies of the Characters */
for (int x = 0; x < countOfChar.length; x++) {
System.out.println(characters.get(x) + " - " + countOfChar[x]);
}
/* Form the Tree! */
/* Form Leaf Nodes and Arrange them in a linked list */
Node root = null;
Node current = null;
Node end = null;
for (int i = 0; i < countOfChar.length; i++) {
Node node = new Node(characters.get(i).toString(), countOfChar[i]);
if (root == null) {
root = node;
end = node;
} else {
current = root;
while (current.linker != null) {
current = current.linker;
}
current.linker = node;
current.linker.linkerBack = current;
end = node;
}
}
// Recursively add and make nodes!
TreeMaker(root, end);
// inOrder(root);
System.out.println();
inOrder(node);
// preOrder(root);
System.out.println();
preOrder(node);
// Calculate the ends and the meets!
char[] messageArray = message.toCharArray();
char checker;
for (int i = 0; i < messageArray.length; i++) {
current = node;
checker = messageArray[i];
String code = "";
while (true) {
if (current.left.value.toCharArray()[0] == checker) {
code += "0";
break;
} else {
code += "1";
if (current.right != null) {
if (current.right.value.toCharArray()[0] == characters
.get(countOfChar.length - 1)) {
break;
}
current = current.right;
} else {
break;
}
}
}
codedString += code;
}
System.out.println();
System.out.println("The coded string is " + codedString);
}
public static void preOrder(Node root) {
if (root != null) {
System.out.print(root.value + "->");
preOrder(root.left);
preOrder(root.right);
}
}
public static void inOrder(Node root) {
if (root != null) {
inOrder(root.left);
System.out.print(root.value + "->");
inOrder(root.right);
}
}
public static void TreeMaker(Node root, Node end) {
node = new Node(end.linkerBack.value + end.value, end.linkerBack.count
+ end.count);
node.left = end.linkerBack;
node.right = end;
end.linkerBack.linkerBack.linker = node;
node.linkerBack = end.linkerBack.linkerBack;
end = node;
end.linker = null;
Node current = root;
while (current.linker != null) {
System.out.print(current.value + "->");
current = current.linker;
}
System.out.println(current.value);
if (root.linker == end) {
node = new Node(root.value + end.value, root.count + end.count);
node.left = root;
node.right = end;
node.linker = null;
node.linkerBack = null;
System.out.println(node.value);
newRoot = node;
} else {
TreeMaker(root, end);
}
}
}
class Node {
String value;
int count;
Node left;
Node right;
Node linker;
Node linkerBack;
Node(String value, int count) {
this.value = value;
this.count = count;
this.left = null;
this.right = null;
this.linker = null;
this.linkerBack = null;
}
}
So I had to write this to simulate queues on two servers running the same operation, to compare if a shop needs to hire a second cashier depending on how efficient the simulation runs. Single queue with single server vs single queue with two servers. I write all my code in main rather than creating additional classes and calling/extending since JAVA is not my strong suite, it takes me a ton of time to come up with this stuff and I write very simple code so it gets really long as you can see. Are there any pointers that you folks can give me based on what you see, to help me streamline this? Within the methods, constructors or classes, groups of lines or code that can be reduced, be more efficient? This works with the desired results though. My apologies if this is not the right way to ask or not the right thing to ask, I will delete it. Thanks in advance.
public class SimulationProject1 {
private static int poissonDistr(double mean) {
Random x = new Random();
double J = Math.exp(-mean);
int i = 0;
double pD = 1.0;
do {
pD = pD * x.nextDouble();
i++;
} while (pD > J);
return i - 1;
}
public class listNode {
int data;
listNode next;
public listNode(int data) {
this.data = data;
this.next = null;
}
}
private final listNode head;
public SimulationProject1() {
this.head = null;
}
public boolean isEmpty() {
return (this.head == null);
}
public int getFirst() {
return head.data;
}
public static class LinkedQueue extends SimulationProject1 {
int size;
int totalTime;
private class Node {
int items;
int waitTime;
int dead;
Node next;
public Node(int items) {
this.items = items;
waitTime = 0;
dead = 0;
size++;
this.next = null;
}
}
private Node head;
public void enqueue(int items) {
if (head == null) {
head = new Node(items);
} else {
Node tmp = head;
while (tmp.next != null) {
tmp = tmp.next;
}
tmp.next = new Node(items);
}
this.size++;
}
public void dequeue() {
if (this.head == null) {
System.out.println("No customers in line");
} else {
this.head = head.next;
}
this.size--;
}
public void setWaitTime() {
Node temp = head;
while (temp != null) {
temp.waitTime++;
temp = temp.next;
}
}
public void getWaitTime() {
Node temp = head;
if(temp != null){
while (temp != null) {
totalTime = temp.waitTime + totalTime;
System.out.println("Total wait time: " + totalTime);
temp = temp.next;
}
}else{
System.out.println("Noone's waiting..");
}
}
public void setTimeout() {
Node temp = head;
while (temp != null) {
if (temp.waitTime >= 8) {
temp.dead = 1;
this.size--;
} else if (temp.waitTime <= 8) {
temp.waitTime++;
}
temp = temp.next;
}
}
}
public static void oneServer(LinkedQueue line, LinkedQueue cashier) {
int cost = 0;
int profit = 0;
int timedOut = 0;
int inLine = 0;
double mean = 0.2;
int [] customersServiced = new int[50];
int [] customerWaitTime = new int[50];
int [] customersInLine = new int[50];
int [] profitData = new int[50];
int [] costData = new int[50];
for (int i = 0; i < 50; i++) {
cost = cost - 3;
for (int j = 0; j < poissonDistr(mean); j++) {
System.out.println("Customers Arriving");
int items = (int) (Math.random() * 6 + 2);
line.enqueue(items);
}
if (line.head != null && line.head.dead == 1) {
timedOut++;
line.dequeue();
cost = cost - 10;
}
if (cashier.head == null && line.head != null && line.head.dead == 0) {
System.out.println("Line Moving");
cashier.head = line.head;
line.head = line.head.next;
}
if (cashier.head != null && cashier.head.items > 0) {
cashier.head.items--;
} else if (cashier.head != null && cashier.head.items <= 0) {
System.out.println("Available");
profit++;
cashier.head = null;
}
line.setWaitTime();
line.setTimeout();
System.out.println("Number currently in line: " + line.size);
customersInLine[i] = line.size;
line.getWaitTime();
customerWaitTime[i] = line.totalTime;
System.out.println("Customers serviced: " + profit);
customersServiced[i] = profit;
profitData[i] = profit;
costData[i] = cost;
}
while (line.head != null) {
line.head = line.head.next;
inLine++;
}
System.out.println("\n" + "-------------------------Stats-----------------------------" + "\n" + "Cost: " +
cost + "\nPer iteration: " + Arrays.toString(costData) + "\n");
System.out.println("Profit: " + profit + "\nPer iteration: " + Arrays.toString(profitData) + "\n");
System.out.println("In the line: " + inLine + "\nAccrued per iteration: " + Arrays.toString(customersInLine) + "\n");
System.out.println("Timed out: " + timedOut + "\n");
System.out.println("Total wait time: " + line.totalTime + "\nPer iteration: " + Arrays.toString(customerWaitTime) + "\n");
}
public static void twoServer(LinkedQueue line, LinkedQueue cashier, LinkedQueue cashier2) {
int cost = 0;
int profit = 0;
int timedOut = 0;
int inLine = 0;
double mean = 0.2;
int[] customersServiced = new int[50];
int[] customerWaitTime = new int[50];
int[] customersInLine = new int[50];
int[] profitData = new int[50];
int[] costData = new int[50];
for (int i = 0; i < 50; i++) {
cost = cost - 6;
for (int j = 0; j < poissonDistr(mean); j++) {
System.out.println("Customers Arriving");
int items = (int) (Math.random() * 6 + 2);
line.enqueue(items);
}
if (line.head != null && line.head.dead == 1) {
timedOut++;
line.dequeue();
cost = cost - 10;
}
if (cashier.head == null && line.head != null && line.head.dead == 0) {
System.out.println("Line Moving");
cashier.head = line.head;
line.head = line.head.next;
}
if (cashier2.head == null && line.head != null && line.head.dead == 0) {
System.out.println("Line Moving");
cashier2.head = line.head;
line.head = line.head.next;
}
if (cashier.head != null && cashier.head.items > 0) {
cashier.head.items--;
} else if (cashier.head != null && cashier.head.items <= 0) {
System.out.println("Available");
profit++;
cashier.head = null;
}
if (cashier2.head != null && cashier2.head.items > 0) {
cashier2.head.items--;
} else if (cashier2.head != null && cashier2.head.items <= 0) {
System.out.println("Available");
profit++;
cashier2.head = null;
}
line.setWaitTime();
line.setTimeout();
System.out.println("Number currently in line: " + line.size);
customersInLine[i] = line.size;
line.getWaitTime();
customerWaitTime[i] = line.totalTime;
System.out.println("Customers serviced: " + profit);
customersServiced[i] = profit;
profitData[i] = profit;
costData[i] = cost;
}
while (line.head != null) {
line.head = line.head.next;
inLine++;
}
System.out.println("\n" + "-------------------------Stats-----------------------------" + "\n" +
"Cost: " + cost + "\nPer iteration: " + Arrays.toString(costData) + "\n");
System.out.println("Profit: " + profit + "\nPer iteration: " + Arrays.toString(profitData) + "\n");
System.out.println("In the line: " + inLine + "\nAccrued per iteration: " + Arrays.toString(customersInLine) + "\n");
System.out.println("Timed out: " + timedOut + "\n");
System.out.println("Total wait time: " + line.totalTime + "\nPer iteration: " + Arrays.toString(customerWaitTime) + "\n");
}
public static void main(String[] args) {
LinkedQueue line = new LinkedQueue();
LinkedQueue line2 = new LinkedQueue();
LinkedQueue cashier = new LinkedQueue();
LinkedQueue cashier2 = new LinkedQueue();
oneServer(line, cashier);
System.out.println("-------------------------Double Server------------------------------------");
twoServer(line2, cashier, cashier2);
}
}
The output it too large to post, it has stuff like
Numbers in line
Currently Waiting
Currently serviced
Cost
Loss
Profit
etc
I need help making this toString method pass the tests at the bottom. I am currently getting the error (expected:<0:20, 1:[1]0> but was <0:20, 1:[2]0>). addFirst is working 100%, but I'm not sure what is wrong here.
public class LList
{
public Node head;
private int i;
private int size;
public void addFirst(int value)
{
Node n = new Node();
n.value = value;
n.next = head;
head = n;
}
public void removeFirst()
{
if (head != null)
{
// commone case: there is at least one node
head = head.next;
}
else
{
// no nodes
throw new Banana();
}
}
public int size()
{
Node current = head;
int count = 0;
while(current != null)
{
count++; // keep count of nodes
current = current.next; // move to next node
}
return count;
}
public int get(int index)
{
int count = 0;
Node current = head;
if (index < 0 || index >= size())
{
throw new Banana();
}
while(count != index)
{
count++;
current = current.next;
}
return current.value;
}
public String toString()
{
String s = "";
Node current = head;
//current = head;
if (size() == 0)
{
return s;
}
else
{
s = s + "" + i + ":" + current.value;
for (int i = 1; i < size(); i++)
{
s = s + ", " + i + ":" + current.value;
}
return s;
}
}
public class Node
{
public int value;
public Node next;
}
#Test
public void testToString()
{
LList a = new LList();
assertEquals("", a.toString());
a.addFirst(10);
assertEquals("0:10", a.toString());
a.addFirst(20);
assertEquals("0:20, 1:10", a.toString());
a.addFirst(30);
assertEquals("0:30, 1:20, 2:10", a.toString());
}
You should iterate (walk over) all Nodes.
Use while loop for that, e.g.:
public String toString() {
String s = "";
Node current = head;
// current = head;
if (size() != 0) {
int i = 0;
s = s + "" + i + ":" + current.value;
while(current.next != null) {
i++;
current = current.next;
s = s + ", " + i + ":" + current.value;
}
}
return s;
}
Greeting to everyone. I currently work on a program that sorting the emergency number of patients(the number that assigned by nurse when they enter the emergency room and this number determines the seriousness of their sickness too). However, if there are more than 1 patient who hold the same emergency numbers(eg: 2 patients hold emergency number 1), the one who came earlier should receive the treatment first. For this reason, I have 2 sortings, one is to sort the emergency number in ascending order and the other is to sort the time in ascending order too. But unfortunately the second sorting cannot work correctly.The following are the explanations for the type of emergency numbers:
Emergency number : 1 – Immediately life threatening
Emergency number : 2 – Urgent, but not immediately life threatening
Emergency number : 3 – Less urgent
So,now comes the coding part(Please note that this is a linkedlist)
Interface:
public interface ListInterface<T> {
public boolean add(T newEntry);
public boolean add(int newPosition, T newEntry);
public T remove(int givenPosition);
public void clear();
public boolean replace(int givenPosition, T newEntry);
public T getEntry(int givenPosition);
public boolean contains(T anEntry);
public int getLength();
public boolean isEmpty();
public boolean isFull();
}
LList class:
/**
* LList.java
* A class that implements the ADT list by using a chain of nodes,
* with the node implemented as an inner class.
*/
public class LList<T> implements ListInterface<T> {
private Node firstNode; // reference to first node
private int length; // number of entries in list
public LList() {
clear();
}
public final void clear() {
firstNode = null;
length = 0;
}
public boolean add(T newEntry) {
Node newNode = new Node(newEntry); // create the new node
if (isEmpty()) // if empty list
firstNode = newNode;
else { // add to end of nonempty list
Node currentNode = firstNode; // traverse linked list with p pointing to the current node
while (currentNode.next != null) { // while have not reached the last node
currentNode = currentNode.next;
}
currentNode.next = newNode; // make last node reference new node
}
length++;
return true;
}
public boolean add(int newPosition, T newEntry) { // OutOfMemoryError possible
boolean isSuccessful = true;
if ((newPosition >= 1) && (newPosition <= length+1)) {
Node newNode = new Node(newEntry);
if (isEmpty() || (newPosition == 1)) { // case 1: add to beginning of list
newNode.next = firstNode;
firstNode = newNode;
}
else { // case 2: list is not empty and newPosition > 1
Node nodeBefore = firstNode;
for (int i = 1; i < newPosition - 1; ++i) {
nodeBefore = nodeBefore.next; // advance nodeBefore to its next node
}
newNode.next = nodeBefore.next; // make new node point to current node at newPosition
nodeBefore.next = newNode; // make the node before point to the new node
}
length++;
}
else
isSuccessful = false;
return isSuccessful;
}
public T remove(int givenPosition) {
T result = null; // return value
if ((givenPosition >= 1) && (givenPosition <= length)) {
if (givenPosition == 1) { // case 1: remove first entry
result = firstNode.data; // save entry to be removed
firstNode = firstNode.next;
}
else { // case 2: givenPosition > 1
Node nodeBefore = firstNode;
for (int i = 1; i < givenPosition - 1; ++i) {
nodeBefore = nodeBefore.next; // advance nodeBefore to its next node
}
result = nodeBefore.next.data; // save entry to be removed
nodeBefore.next = nodeBefore.next.next; // make node before point to node after the
} // one to be deleted (to disconnect node from chain)
length--;
}
return result; // return removed entry, or
// null if operation fails
}
public boolean replace(int givenPosition, T newEntry) {
boolean isSuccessful = true;
if ((givenPosition >= 1) && (givenPosition <= length)) {
Node currentNode = firstNode;
for (int i = 0; i < givenPosition - 1; ++i) {
// System.out.println("Trace| currentNode.data = " + currentNode.data + "\t, i = " + i);
currentNode = currentNode.next; // advance currentNode to next node
}
currentNode.data = newEntry; // currentNode is pointing to the node at givenPosition
}
else
isSuccessful = false;
return isSuccessful;
}
public T getEntry(int givenPosition) {
T result = null;
if ((givenPosition >= 1) && (givenPosition <= length)) {
Node currentNode = firstNode;
for (int i = 0; i < givenPosition - 1; ++i) {
currentNode = currentNode.next; // advance currentNode to next node
}
result = currentNode.data; // currentNode is pointing to the node at givenPosition
}
return result;
}
public boolean contains(T anEntry) {
boolean found = false;
Node currentNode = firstNode;
while (!found && (currentNode != null)) {
if (anEntry.equals(currentNode.data))
found = true;
else
currentNode = currentNode.next;
}
return found;
}
public int getLength() {
return length;
}
public boolean isEmpty() {
boolean result;
if (length == 0)
result = true;
else
result = false;
return result;
}
public boolean isFull() {
return false;
}
public String toString() {
String outputStr = "";
Node currentNode = firstNode;
while (currentNode != null) {
outputStr += currentNode.data + "\n";
currentNode = currentNode.next;
}
return outputStr;
}
private class Node {
private T data;
private Node next;
private Node(T data) {
this.data = data;
this.next = null;
}
private Node(T data, Node next) {
this.data = data;
this.next = next;
}
} // end Node
} // end LList
Patient class:
public class Patient {
private int emergencyNo;
private int queueTime;
private String patientName;
private String patientIC;
private String patientGender;
private String patientTelNo;
private String patientAdd;
private String visitDate;
public Patient() {
}
public Patient(int emergencyNo, int queueTime, String patientName, String patientIC, String patientGender, String patientTelNo, String patientAdd, String visitDate)
{
this.emergencyNo = emergencyNo;
this.queueTime = queueTime;
this.patientName = patientName;
this.patientIC = patientIC;
this.patientGender = patientGender;
this.patientTelNo = patientTelNo;
this.patientAdd = patientAdd;
this.visitDate = visitDate;
}
//set methods
public void setQueueTime(int queueTime)
{
this.queueTime = queueTime;
}
public boolean setEmergencyNo(int emergencyNo)
{
boolean varEmergencyNo = true;
if (emergencyNo != 1 && emergencyNo != 2 && emergencyNo != 3)
{
varEmergencyNo = false;
System.out.println("Emergency number is in invalid format!");
System.out.println("Emergency number is either 1, 2 or 3 only!");
System.out.println("\n");
}
else
{
this.emergencyNo = emergencyNo;
}
return varEmergencyNo;
}
public boolean setPatientName(String patientName)
{
boolean varPatientName = true;
if (patientName.equals("") || patientName.equals(null))
{
varPatientName = false;
System.out.println("The patient name cannot be empty!\n");
}
else
{
this.patientName = patientName;
}
return varPatientName;
}
public boolean setPatientIC(String patientIC)
{
boolean varPatientIC = true;
if(!patientIC.matches("^[0-9]{12}$"))
{
varPatientIC = false;
System.out.println("IC is in invalid format!");
System.out.println("It must consist of 12 numbers only!\n");
}
else
{
this.patientIC = patientIC;
}
return varPatientIC;
}
public boolean setPatientGender(String patientGender)
{
boolean varPatientGender = true;
if(!patientGender.equals("F") && !patientGender.equals("f") && !patientGender.equals("M") && !patientGender.equals("m"))
{
varPatientGender = false;
System.out.println("Gender is in invalid format!");
System.out.println("It must be either 'M' or 'F' only!\n");
}
else
{
this.patientGender = patientGender;
}
return varPatientGender;
}
public boolean setPatientTelNo(String patientTelNo)
{
boolean varPatientTelNo = true;
if((!patientTelNo.matches("^01[02346789]\\d{7}$")) && (!patientTelNo.matches("^03\\d{8}$")))
{
varPatientTelNo = false;
System.out.println("Invalid phone number!");
System.out.println("It must be in the following format : 0167890990 / 0342346789!\n");
System.out.print("\n");
}
else
{
this.patientTelNo = patientTelNo;
}
return varPatientTelNo;
}
public boolean setPatientAdd(String patientAdd)
{
boolean varPatientAdd = true;
if (patientAdd.equals("") || patientAdd.equals(null))
{
varPatientAdd = false;
System.out.println("The patient address cannot be empty!\n");
}
else
{
this.patientAdd = patientAdd;
}
return varPatientAdd;
}
public void setVisitDate(String visitDate)
{
this.visitDate = visitDate;
}
//get methods
public int getQueueTime()
{
return this.queueTime;
}
public int getEmergencyNo()
{
return this.emergencyNo;
}
public String getPatientName()
{
return this.patientName;
}
public String getPatientIC()
{
return this.patientIC;
}
public String getPatientGender()
{
return this.patientGender;
}
public String getPatientTelNo()
{
return this.patientTelNo;
}
public String getPatientAdd()
{
return this.patientAdd;
}
public String getVisitDate()
{
return this.visitDate;
}
#Override
public String toString()
{
return (this.emergencyNo + "\t\t" + this.patientName + "\t\t" + this.patientIC +
"\t\t" + this.patientGender + "\t\t" + this.patientTelNo + "\t\t" + this.patientAdd + "\t\t" + this.visitDate);
}
public String anotherToString()
{
return (this.emergencyNo + "\t\t\t\t\t\t" + this.patientName + "\t\t\t " + this.visitDate);
}
}
EmergencyCmp(Comparator)--->use for sorting the emergency numbers of the patients
import java.util.Comparator;
public class EmergencyCmp implements Comparator<Patient>
{
#Override
public int compare(Patient p1, Patient p2)
{
if(p1.getEmergencyNo() > p2.getEmergencyNo())
{
return 1;
}
else
{
return -1;
}
}
}
QueueCmp(Comparator)--->use for sorting the arrival time of the patients
import java.util.Comparator;
public class QueueCmp implements Comparator<Patient>
{
#Override
public int compare(Patient p1, Patient p2)
{
if(p1.getQueueTime() > p2.getQueueTime())
{
return 1;
}
else
{
return -1;
}
}
}
Main function:
import java.util.Calendar;
import java.util.Scanner;
import java.util.Arrays;
import java.util.*;
public class DSA {
public DSA() {
}
public static void main(String[] args) {
//patient's attributes
int emergencyNo;
int queueTime;
String patientName;
String patientIC;
String patientGender;
String patientTelNo;
String patientAdd;
String visitDate;
//counter
int j = 0;
int x = 0;
int y = 0;
int z = 0;
int count1 = 0;
int count2 = 0;
int count3 = 0;
int countEnteredPatient = 1;
int totalCount = 0;
//calendar
int nowYr, nowMn, nowDy, nowHr, nowMt, nowSc;
//others
boolean enterNewPatient = true;
String continueInput;
boolean enterNewPatient1 = true;
String continueInput1;
boolean continueEmergencyNo;
Scanner scan = new Scanner(System.in);
ListInterface<Patient> patientList = new LList<Patient>();
ListInterface<Patient> newPatientList = new LList<Patient>();
Patient[] patientArr1 = new Patient[10000];
Patient[] patientArr2 = new Patient[10000];
Patient[] patientArr3 = new Patient[10000];
Patient tempoPatient;
do{
//do-while loop for entering new patient details after viewing patient list
System.out.println("Welcome to Hospital Ten Stars!\n");
do{
//do-while loop for entering new patient details
System.out.println("Entering details of patient " + countEnteredPatient);
System.out.println("===================================\n");
Calendar calendar = Calendar.getInstance();
nowYr = calendar.get(Calendar.YEAR);
nowMn = calendar.get(Calendar.MONTH);
nowDy = calendar.get(Calendar.DAY_OF_MONTH);
nowHr = calendar.get(Calendar.HOUR);
nowMt = calendar.get(Calendar.MINUTE);
nowSc = calendar.get(Calendar.SECOND);
queueTime = calendar.get(Calendar.MILLISECOND);
visitDate = nowDy + "/" + nowMn + "/" + nowYr + ", " + nowHr + ":" + nowMt + ":" + nowSc;
//input emergency number
do{
tempoPatient = new Patient();
continueEmergencyNo = false;
int EmergencyNoOption;
try
{
do{
System.out.print("Please select 1 – Immediately life threatening, 2 – Urgent, but not immediately life threatening or 3 – Less urgent(Eg: 1) : ");
EmergencyNoOption = scan.nextInt();
scan.nextLine();
System.out.print("\n");
}while(tempoPatient.setEmergencyNo(EmergencyNoOption) == false);
}
catch(InputMismatchException ex)
{
System.out.print("\n");
System.out.println("Invalid input detected.");
scan.nextLine();
System.out.print("\n");
continueEmergencyNo = true;
}
}while(continueEmergencyNo);
//input patient name
do{
System.out.print("Patient name(Eg: Christine Redfield) : ");
patientName = scan.nextLine();
System.out.print("\n");
}while(tempoPatient.setPatientName(patientName) == false);
//input patient ic no
do{
System.out.print("Patient IC number(Eg: 931231124567) : ");
patientIC = scan.nextLine();
System.out.print("\n");
}while(tempoPatient.setPatientIC(patientIC) == false);
//input patient gender
do{
System.out.print("Patient gender(Eg: M) : ");
patientGender = scan.nextLine();
System.out.print("\n");
}while(tempoPatient.setPatientGender(patientGender) == false);
//input patient tel. no
do{
System.out.print("Patient tel.No(without'-')(Eg: 0162345678/0342980123) : ");
patientTelNo = scan.nextLine();
System.out.print("\n");
}while(tempoPatient.setPatientTelNo(patientTelNo) == false);
//input patient address
do{
System.out.print("Patient address(Eg: 4-C9 Jln Besar 123, Taman Besar, 56000 Kuala Lumpur) : ");
patientAdd = scan.nextLine();
System.out.print("\n");
}while(tempoPatient.setPatientAdd(patientAdd) == false);
tempoPatient.setQueueTime(queueTime);
tempoPatient.setVisitDate(visitDate);
patientList.add(tempoPatient);
//decide whether want to enter a new patient or not
do{
System.out.print("Do you want to enter another new patient?(Eg: Y/N) : ");
continueInput = scan.nextLine();
if(continueInput.equals("Y") || continueInput.equals("y"))
{
enterNewPatient = true;
System.out.print("\n");
}
else if(continueInput.equals("N") || continueInput.equals("n"))
{
enterNewPatient = false;
}
else
{
System.out.println("\n");
System.out.println("Please enter Y/N only.\n");
}
}while(!continueInput.equals("Y") && !continueInput.equals("y") && !continueInput.equals("N") && !continueInput.equals("n"));
countEnteredPatient++;
}while(enterNewPatient); //end do-while loop for entering new patient details
System.out.println("\nWaiting list of patient will be displayed soon.\n");
try{
Thread.sleep(1000);
}
catch (Exception e)
{
}
System.out.println("Waiting list of patients");
System.out.println("========================\n");
System.out.println("Number\t\tEmergency number\t\tPatient name\t\t ArrivalTime");
System.out.println("============================================================================");
for(int i = 1; i <= patientList.getLength(); i++)
{
System.out.println(i + "\t\t\t" + patientList.getEntry(i).anotherToString());
}
do{
System.out.print("\nSo, now do you want to enter another new patient?(Eg: Y/N) : ");
continueInput1 = scan.nextLine();
if(continueInput1.equals("Y") || continueInput1.equals("y"))
{
enterNewPatient1 = true;
System.out.print("\n");
}
else if(continueInput1.equals("N") || continueInput1.equals("n"))
{
enterNewPatient1 = false;
}
else
{
System.out.println("\n");
System.out.println("Please enter Y/N only.\n");
}
}while(!continueInput1.equals("Y") && !continueInput1.equals("y") && !continueInput1.equals("N") && !continueInput1.equals("n"));
}while(enterNewPatient1);//end do-while loop for entering new patient details after viewing patient list
System.out.println("\nNow rearranging the list based on the seriouness and their arrival time.");
try{
Thread.sleep(1000);
}
catch (Exception e)
{
}
//create an unsorted array
Patient[] tempoPatientArr = new Patient[patientList.getLength()];
//copy the contents of patientList into tempoPatientArr
for(int i = 1; i <= patientList.getLength(); i++ )
{
tempoPatientArr[i-1] = patientList.getEntry(i);
}
//sort tempoPatientArr
Arrays.sort(tempoPatientArr, new EmergencyCmp());
//the above part until this comment line does not have problem
//check the emergency no and then categorise accordingly
for(int i = 0; i < tempoPatientArr.length; i++)
{
if(tempoPatientArr[i].getEmergencyNo() == 1)
{
patientArr1[x] = tempoPatientArr[i];
x++;
}
else if(tempoPatientArr[i].getEmergencyNo() == 2)
{
patientArr2[y] = tempoPatientArr[i];
y++;
}
else if(tempoPatientArr[i].getEmergencyNo() == 3)
{
patientArr3[z] = tempoPatientArr[i];
z++;
}
}
//to check how many !null elements by using count for 3 sub-arrays
for(int i = 0; i < patientArr1.length; i++)
{
if(patientArr1[i] != null)
{
count1++;
}
else
{
break;
}
}
for(int i = 0; i < patientArr2.length; i++)
{
if(patientArr2[i] != null)
{
count2++;
}
else
{
break;
}
}
for(int i = 0; i < patientArr3.length; i++)
{
if(patientArr3[i] != null)
{
count3++;
}
else
{
break;
}
}
//new array with elimination of null values
Patient[] newPatientArr1 = new Patient[count1];
Patient[] newPatientArr2 = new Patient[count2];
Patient[] newPatientArr3 = new Patient[count3];
//copy the contents of old sub arrays(the arrays with null values) into the new sub arrays(without null values)
for(int i = 0; i < newPatientArr1.length; i++)
{
newPatientArr1[i] = patientArr1[i];
}
for(int i = 0; i < newPatientArr2.length; i++)
{
newPatientArr2[i] = patientArr2[i];
}
for(int i = 0; i < newPatientArr3.length; i++)
{
newPatientArr3[i] = patientArr3[i];
}
totalCount = count1 + count2 + count3;
//array that used to combine all the sub-arrays
Patient[] newPatientArr = new Patient[totalCount];
//sort all sub new arrays
Arrays.sort(newPatientArr1, new QueueCmp());
Arrays.sort(newPatientArr2, new QueueCmp());
Arrays.sort(newPatientArr3, new QueueCmp());
//combine the contents of sub new arrays into the newPatientArr array
do{
for (int i = 0; i < count1; i++)
{
newPatientArr[j] = newPatientArr1[i];
j++;
}
for (int b = 0; b < count2; b++)
{
newPatientArr[j] = newPatientArr2[b];
j++;
}
for (int c = 0; c < count3; c++)
{
newPatientArr[j] = newPatientArr3[c];
j++;
}
}while(j < totalCount);
//relink the nodes
for(int i = 0; i < newPatientArr.length; i++)
{
newPatientList.add(newPatientArr[i]);
}
System.out.println("\nSorted waiting list of patients");
System.out.println("===============================\n");
System.out.println("Number\t\tEmergency number\t\tPatient name\t\t ArrivalTime");
System.out.println("============================================================================");
for(int i = 1; i <= newPatientList.getLength(); i++)
{
System.out.println(i + "\t\t\t" + newPatientList.getEntry(i).anotherToString());
}
}
}
Interface and LList class definitely do not have problems. So everyone can skip the 2 parts.
For the main function, I have a comment like this:
//the above part until this comment line does not have problem
When you all see the comment, that means the previous code does not have problem and you all may skip it and below is an attachment of the result that I got earlier:
So, from the picture you all can see that the sorting of arrival time is not correct. I hope that I can know why does this problem occurs since I cannot figure it out by myself. Thanks to all of you first.
So, after taking the advice of #Scott Hunter, I have made the following modification to the EmergencyCmp:
#Override
public int compare(Patient p1, Patient p2)
{
int value = 0;
if(p1.getEmergencyNo() > p2.getEmergencyNo())
{
value = 1;
}
else if(p1.getEmergencyNo() < p2.getEmergencyNo())
{
value = -1;
}
else if(p1.getEmergencyNo() == p2.getEmergencyNo())
{
if(p1.getQueueTime() > p2.getQueueTime())
{
return 1;
}
else
{
return -1;
}
}
return value;
}
However, the time sorting still produce a wrong result.
As I understand it (which I may not; you provided a LOT of extraneous stuff), it looks like you are trying to perform 2 distinct sorts, one after the other, such that the second is undoing the work of the first. Instead, you should define a single Comparator which compares emergency numbers and, only if they are the same, compares arrival times.
I am trying to recursively populate a tree, but my code is only only fill out one depth length, and then quiting. i.e. each node only has one child. Is there something am failing to take in to consideration?
public static void populate(Node n, int depth, String player){
System.out.println("Depth: " + depth);
if(player.equalsIgnoreCase("X"))
player = "O";
else
player = "X";
int j = 0;
System.out.println("empty spots: " + ((Board)n.getData()).noOfEmpty());
for(int i=0; i<((Board)n.getData()).noOfEmpty(); i++){
if(((Board)n.getData()).getSquare(j).equalsIgnoreCase("X")
|| ((Board)n.getData()).getSquare(j).equalsIgnoreCase("O"))
j++;
else{
Board tmp = new Board(((Board)n.getData()), j, player);
Node newNode = new Node(tmp);
tree.insert(n, newNode);
populate(newNode, depth-1, player);
}
}
}
P.S. and i check the noOfEmpty() return value, which should determine the number of children a node should have.
edit:#eznme the complete code as requested:
public class MinMax {
protected static Tree tree;
public static void createTree(Board b){
tree = new Tree();
tree.setRoot(new Node(b));
populate(tree.getRoot(), 5, "X");
//System.out.println("printing tree");
//tree.print(1);
}
public static void populate(Node n, int depth, String player){
System.out.println("Depth: " + depth);
if(player.equalsIgnoreCase("X"))
player = "O";
else
player = "X";
int j = 0;
System.out.println("empty spots: " + ((Board)n.getData()).noOfEmpty());
for(int i=0; i<((Board)n.getData()).noOfEmpty(); i++){
if(((Board)n.getData()).getSquare(j).equalsIgnoreCase("X")
|| ((Board)n.getData()).getSquare(j).equalsIgnoreCase("O"))
j++;
else{
Board tmp = new Board(((Board)n.getData()), j, player);
Node newNode = new Node(tmp);
tree.insert(n, newNode);
populate(newNode, depth-1, player);
}
}
}
}
import java.util.ArrayList;
/**
*
* #author Greg
*/
public class Node {
protected Object data;
protected int score; //fields to be used by the MaxMin class
protected ArrayList<Node> children;
//constructors
public Node(){
children = new ArrayList(0);
data = null;
}
public Node(Object obj){
children = new ArrayList(0);
data = obj;
}
public void setChild(Node n){
//EFFECT: set the ith child to node t
children.add(n);
}
public void setChildren(Node[] t){
//EFFECT: copy the array t, into the array children, effectively
// setting all the chidern of this node simultaneouly
int l = children.size();
for(int i=0; i<t.length; i++){
children.add(l, t[i]);
}
}
public void setData(Object obj){
//EFFECT: set the date of this node to obj, and also set the number of
// children this node has
data = obj;
}
public Node getChild(int i){
//EFFECT: returns the child at index i
return children.get(i);
}
public int noOfChildren(){
//EFFECT: return the length of this node
return children.size();
}
public Object getData(){
//EFFECT: returns the data of this node
return data;
}
#Override
public String toString(){
//EFFECT: returns the string form of this node
return "" + data.toString() + "\nwith " + noOfChildren()+ "\n";
}
public boolean isLeaf(){
if(children.size()==0)
return true;
return false;
}
public void setScore(int scr){
score = scr;
}
public int getScore(){
return score;
}
}
public class Tree {
private Node root;
public Tree(){
setRoot(null);
}
public Tree(Node n){
setRoot(n);
}
public Tree(Object obj){
setRoot(new Node(obj));
}
protected Node getRoot(){
return root;
}
protected void setRoot(Node n){
root = n;
}
public boolean isEmpty(){
return getRoot() == null;
}
public Object getData(){
if(!isEmpty())
return getRoot().getData();
return null;
}
public Object getChild(int i){
return root.getChild(i);
}
public void setData(Object obj){
if(!isEmpty())
getRoot().setData(obj);
}
public void insert(Node p,Node c){
if(p != null)
p.setChild(c);
}
public void print(int mode){
if(mode == 1) pretrav();
else if(mode == 2) postrav();
else
System.out.println("yeah... mode 1 or 2...nothing else, try agn");
}
public void pretrav(){
pretrav(getRoot());
}
protected void pretrav(Node t){
if(t == null)
return;
System.out.println(t.getData()+" \n");
for(int i=0; i<t.noOfChildren(); i++)
pretrav(t.getChild(i));
}
public void postrav(){
postrav(getRoot());
}
protected void postrav(Node t){
if(t == null)
return;
System.out.print(t.getData()+" ");
for(int i=0; i<t.noOfChildren(); i++)
pretrav(t.getChild(i));
System.out.print(t.getData()+" ");
}
}
public class Board {
boolean isFull = false; // a check to see if the board is full
String[] grid = new String[9]; //an array represting the 9 square on a board
int hV;
String MIN, MAX;
public Board(){
for(int i=0; i<grid.length;i++)
grid[i] = Integer.toString(i);
hV = heuristicValue(this);
}
public Board(Board b, int x, String player){
this.grid = b.getBoard();
if(!(grid[x].equalsIgnoreCase("X")|| grid[x].equalsIgnoreCase("X")))
grid[x] = player;
}
public boolean setSquare(String player, int position){
/*
EFFECT:set a square on the board to either a X or a O, debending on the player
PRECON: square (x,y) is empty
POATCON: square (x,y) has player 'symbol'
*/
boolean isValidPlay = false;
try{
//as a sanity
Integer.parseInt(grid[position]);
grid[position] = player;
isValidPlay = true;
}catch(NumberFormatException e){
System.out.println("positon " + position + "is already occupied");
}
return isValidPlay;
}
public boolean endGame(){
/*
* EFFECT: check to see if the game have been won or drawn
*/
if(ticTacToe(0,1,2)){
//System.out.println("Player " + grid[0] + " wins");
return true;
}
else if(ticTacToe(3,4,5)){
//System.out.println("Player " + grid[3] + " wins");
return true;
}
else if(ticTacToe(6,7,8)){
//System.out.println("Player " + grid[6] + " wins");
return true;
}
else if(ticTacToe(0,4,8)){
//System.out.println("Player " + grid[0]+ " wins");
return true;
}
else if(ticTacToe(0,3,6)){
//System.out.println("Player " + grid[0]+ " wins");
return true;
}
else if(ticTacToe(1,4,7)){
//System.out.println("Player " + grid[1] + " wins");
return true;
}
else if(ticTacToe(2,5,8)){
//System.out.println("Player " + grid[2] + " wins");
return true;
}else if(ticTacToe(2,4,6)){
//System.out.println("Player " + grid[2] + " wins");
return true;
}
else
return isDrawn();
}
public boolean ticTacToe(int x, int y, int z){
/*
* check is x, y and z has the same value
*/
try{
Integer.parseInt(grid[x]);
return false;
}catch(NumberFormatException e){
if( grid[x].equals(grid[y])
&& grid[x].equals(grid[z]))
return true;
else
return false;
}
}
public String getSquare(int i){
return grid[i];
}
#Override
public String toString(){
String msg = "";
for(int i=0; i<grid.length; i++){
msg = msg + grid[i] + " ";
if(i==2 || i==5)
msg = msg+ "\n";
}
return msg;
}
public boolean isDrawn(){
/*
* check to see if there are any 'free' spaces on the board, if there are any
* return false, else return true
*/
for(int i=0; i<grid.length; i++){
try{
Integer.parseInt(grid[i]);
return false;
}catch(NumberFormatException e){
}
}
System.out.println("Game drawn");
return true;
}
public String[] getBoard(){
return grid;
}
public int noOfEmpty(){
//EFFECT: returns the number of empty squares
int count = 0;
for(int i=0; i<grid.length; i++)
if (!(grid[i].equalsIgnoreCase("X") || grid[i].equalsIgnoreCase("O")))
count++;
return count;
}
public int heuristicValue(Board b){
String MAX = "X", MIN = "O";
/*
* calculate a value that will be used as a heuristic function
* the function works for ever X in a row WITHOUT O: 1 point,
* for two X in a row WITHOUT a O: 5 points
* and 3 X in a row: 100 points
*/
//System.out.println("Computing heuristic");
//System.out.println("Computing horizontals");
int hCount = 0;
//sum up the horizontals
for(int i=0; i<9; i=i+3){
int tmpMAX = playerCount(b, MAX,i,i+1,i+2);
int tmpMIN = playerCount(b, MIN,i,i+1,i+2);
//System.out.println(tmpMAX);
//System.out.println(tmpMIN);
if(tmpMIN > 0){
//System.out.println("Min was zero");
}
else if(tmpMAX==1){
//System.out.println("has one");
hCount = hCount + 1;
}
else if(tmpMAX==2){
//System.out.println("was tw0");
hCount = hCount + 5;
}
else if(tmpMAX==3){
//System.out.println("full 100");
hCount = hCount + 100;
}
}
//System.out.println("Computing verticals");
//sum up the verticals
for(int i=0; i<3; i++){
int tmpMAX = playerCount(b, MAX,i,i+3,i+6);
int tmpMIN = playerCount(b, MIN,i,i+3,i+6);
if(tmpMIN > 0){}
else if(tmpMAX==1){
hCount = hCount +1;
}
else if(tmpMAX==2){
hCount = hCount + 5;
}
else if(tmpMAX==3){
hCount = hCount + 100;
}
}
//System.out.println("Computing diagonals");
//sum up diagonals
if(playerCount(b, MIN,0,4,8)==0){
if(playerCount(b, MAX,0,4,8)==1){
hCount = hCount + 1;
}
if(playerCount(b, MAX,0,4,8)==2)
hCount = hCount + 5;
if(playerCount(b, MAX,0,4,8)==3)
hCount = hCount + 100;
}
if(playerCount(b, MIN,2,4,6)==0){
if(playerCount(b, MAX,2,4,6)==1){
hCount = hCount + 1;
}
if(playerCount(b, MAX,2,4,6)==2)
hCount = hCount + 5;
if(playerCount(b, MAX,2,4,6)==3)
hCount = hCount + 100;
}
//System.out.println("Computing completed");
int hV = hCount;
return hV;
}
int playerCount(Board b, String player, int x, int y, int z){
int count = 0;
if(b.getSquare(x).equals(player))
count = count + 1;
if(b.getSquare(y).equals(player))
count = count + 1;
if(b.getSquare(z).equals(player))
count = count + 1;
//System.out.println("playerCount; " + count);
return count;
}
}
import java.io.*;
import java.io.IOException;
public class Main {
public static void main(String[] args) throws IOException{
BufferedReader reader = new BufferedReader(new
InputStreamReader(System.in));
Board thisGame = new Board();
System.out.println("Start \n" + thisGame.toString());
MinMax.createTree(thisGame);
System.exit(0);
}
}
In order to recursively build a n-ary tree, I would do this:
public static void populate(Node n, int height){
if(height = 0){
n = new Node();
}else{
n = new Node();
for(int i = 0; i < n.nbChilds(); i++){
populate(n.getChildAt(i), height - 1);
}
}
}
I hope it helps.
Order of nodes creation with this algo (on a binary tree):
1
2 9
3 6 10 13
4 5 7 8 11 12 14 15
So here is what I would do in your case (minimax tic-tac-toe):
Terminology:
Height of a node: Distance from this node to it's further leaf.
Depth of a node: Distance from the root of the tree, to this node.
You have to keep trying all cases until: the board is full OR one player won. So, your tree's height is numberOfCells + 1.
If we simplify the problem and don't worry about symmetric duplicates:
Each node will have numberOfcells - nodeDepth childs.
public static void main(String[] args){
Tree t = new Tree();
int nbCells = 9;
t.setRoot(buildTree(new Board(nbCells), 0, -1));
}
public static Node buildTree(Board b, int player, int positionToPlay){
if(player != 0){
b.setCellAt(positionToPlay, player);
}
Node n = new Node(b, b.nbEmptyCells());
int j = 0;
for(int i = 0; i < b.nbCells(); i++){
if(b.getCellAt(i) == 0)
n.setChildAt(j++, buildTree(new Board(b), changePlayer(player), i));
}
return n;
}
public static int changePlayer(int p){
switch(p){
case 0:
return 1;
case 1:
return 2;
case 2:
return 1;
default:
return 0;
}
}
Node class:
public class Node {
private Board board;
private Node[] childs;
public Node(Board b, int nbChilds){
this.board = new Board(b);
this.childs = new Node[nbChilds];
}
public Node getChildAt(int i){
return childs[i];
}
public int nbChilds(){
return childs.length;
}
public void setChildAt(int i, Node n){
this.childs[i] = n;
}
public Board getBoard(){
return this.board;
}
I think you got a wrong approach.
First of all, you're doing a loop and recursion, besides using a depth variable that has no meaning since you never check it's value either to end the recursion, or to know something about what you want to do.
The use a a dynamic function within the loop itself is not quite good, since the iteration should be well defined from the beginning of the loop.
i is just useless in your context.
So if I understand your code, a problematic case would be a case where there is 3 empty squares and 4 non empty squares since you would iterate i from 0 to 3 and do nothing but incrementing j from 0 to 3 then exit because i would have reach 3.
Of course I may be mistaken on some points because I don't know what tree is, from where did it come from? is it related to n? What is a board.
I hope my contribution can help you and I encourage you to post more details to clarify the holes and enable me to help you a bit more.