init
This commit is contained in:
BIN
Tries/Node.class
Normal file
BIN
Tries/Node.class
Normal file
Binary file not shown.
194
Tries/Node.java
Normal file
194
Tries/Node.java
Normal file
@@ -0,0 +1,194 @@
|
||||
/**
|
||||
* Provides methods to manipulate single Nodes.<br />
|
||||
* A Node represents a char in the Trie and provides a children-array
|
||||
* that saves following chars. <br />The Node also saves the parent Node.
|
||||
* if a character is the last one of a string that is set it contains points.
|
||||
* <br /><br />i.e. if "hans" is set with 5 points, <code>points</code>
|
||||
* of 's' is 5.
|
||||
*/
|
||||
public class Node {
|
||||
|
||||
/**
|
||||
* the points of a Student.
|
||||
*/
|
||||
private Integer points;
|
||||
/**
|
||||
* Node array for children.
|
||||
*/
|
||||
private Node[] children = new Node[26];
|
||||
/**
|
||||
* Parent Node.
|
||||
*/
|
||||
private Node parent;
|
||||
/**
|
||||
* The Character of the Node.
|
||||
*/
|
||||
private char ch;
|
||||
|
||||
/**
|
||||
* Constructor for root Node.
|
||||
*/
|
||||
public Node() {
|
||||
this.points = null;
|
||||
this.parent = null;
|
||||
this.ch = '+';
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor for Node with character <code>ch</code>.
|
||||
* @param ch character of the Node
|
||||
*/
|
||||
private Node(char ch) {
|
||||
this.points = null;
|
||||
this.parent = null;
|
||||
this.ch = ch;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor for Node <code>ch</code>s with known parent
|
||||
* Node <code>parent</code>.
|
||||
* @param ch character of the Node
|
||||
* @param parent Parent Node of the Node
|
||||
*/
|
||||
public Node(char ch, Node parent) {
|
||||
Node hlp = new Node(ch);
|
||||
hlp.parent = parent;
|
||||
parent.setChild(ch, hlp);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a character <code>ch</code> into the index for
|
||||
* the children array.
|
||||
* @param ch character to convert
|
||||
* @return index for the children array
|
||||
*/
|
||||
private int convertChar(char ch) {
|
||||
return ch - 'a';
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets <code>child</code> with character <code>ch</code>
|
||||
* in children array.
|
||||
* @param ch the child's character
|
||||
* @param child the child Node
|
||||
*/
|
||||
private void setChild(char ch, Node child) {
|
||||
this.children[convertChar(ch)] = child;
|
||||
}
|
||||
|
||||
/**
|
||||
* Child getter.
|
||||
* @param ch character of child to get
|
||||
* @return <code>Node</code> of child
|
||||
* or <code>null</code>, if child does not exist
|
||||
*/
|
||||
public Node getChild(char ch) {
|
||||
return this.children[convertChar(ch)];
|
||||
}
|
||||
|
||||
/**
|
||||
* Searches the subtree for a string <code>key</code>.
|
||||
* @param key string to search for
|
||||
* @return <code>Node</code> of found key or <code>null</code>
|
||||
*/
|
||||
public Node find(String key) {
|
||||
int i = 1;
|
||||
Node iterator = this.children[convertChar(key.charAt(0))];
|
||||
while (iterator != null && i < key.length()) {
|
||||
iterator = iterator.children[convertChar(key.charAt(i))];
|
||||
i++;
|
||||
}
|
||||
if (i == key.length()) {
|
||||
return iterator;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset <code>points</code> of Node.
|
||||
*/
|
||||
public void deleteMe() {
|
||||
this.points = null;
|
||||
cleanup();
|
||||
}
|
||||
|
||||
/**
|
||||
* Searches for children.
|
||||
* @return <code>true</code>, if child was found or<br />
|
||||
* <code>false</code>, if child not available
|
||||
*/
|
||||
private boolean hasChild() {
|
||||
for (int i = 0; i < this.children.length; i++) {
|
||||
if (this.children[i] != null) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes unneeded Nodes after Student deletion.
|
||||
*/
|
||||
private void cleanup() {
|
||||
if (hasChild()) {
|
||||
return;
|
||||
}
|
||||
Node iterator = this.parent;
|
||||
char isChild = this.ch;
|
||||
while (iterator.points == null && iterator.parent != null) {
|
||||
|
||||
//delete edge
|
||||
iterator.children[convertChar(isChild)] = null;
|
||||
|
||||
//if another child is set, the Node is still needed
|
||||
if (iterator.hasChild()) {
|
||||
return;
|
||||
}
|
||||
isChild = iterator.ch;
|
||||
iterator = iterator.parent;
|
||||
}
|
||||
|
||||
//delete child Node in root
|
||||
iterator.children[convertChar(isChild)] = null;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to print a Node and his subtree.<br />
|
||||
* Recursive self-calling every child of the Node.
|
||||
* @return <code>string</code> of Node and subtree
|
||||
*/
|
||||
public String toString() {
|
||||
System.out.print(this.ch);
|
||||
if (this.points != null) {
|
||||
System.out.print("[" + this.points + "]");
|
||||
}
|
||||
if (this.hasChild()) {
|
||||
System.out.print("(");
|
||||
for (int i = 0; i < this.children.length; i++) {
|
||||
if (this.children[i] != null) {
|
||||
this.children[i].toString();
|
||||
}
|
||||
}
|
||||
System.out.print(")");
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter for points of Node.
|
||||
* @param points to set
|
||||
*/
|
||||
public void setPoints(Integer points) {
|
||||
this.points = points;
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for Points of Node.
|
||||
* @return <code>points</code> of Node
|
||||
*/
|
||||
public Integer getPoints() {
|
||||
return this.points;
|
||||
}
|
||||
}
|
||||
BIN
Tries/Shell.class
Normal file
BIN
Tries/Shell.class
Normal file
Binary file not shown.
170
Tries/Shell.java
Normal file
170
Tries/Shell.java
Normal file
@@ -0,0 +1,170 @@
|
||||
import java.io.BufferedReader;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Main Class for the Student-Administration.<br />
|
||||
* The user types commands and parameters to manipulate or change
|
||||
* the Trie. <br />Commands are found with the HELP command
|
||||
*/
|
||||
final class Shell {
|
||||
private Shell() { }
|
||||
/**
|
||||
* Checks if <code>string</code> consists of only chars.
|
||||
* @param string String to check
|
||||
* @return <code>true</code>, if <code>string</code> has only chars<br />
|
||||
* <code>false</code>, if <code>string</code> has other signs
|
||||
*/
|
||||
private static boolean isCharString(String string) {
|
||||
for (int j = 0; j < string.length(); j++) {
|
||||
if (string.charAt(j) - 'a' < 0
|
||||
|| string.charAt(j) - 'a' > 25) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Main method for the Student Administration including the Shell.
|
||||
* Validation for input.
|
||||
* @param args are not handled at the moment
|
||||
* @throws IOException
|
||||
*/
|
||||
public static void main(String[] args) throws IOException {
|
||||
Trie t = new Trie();
|
||||
boolean runtime = true;
|
||||
BufferedReader br = new BufferedReader(
|
||||
new InputStreamReader(System.in));
|
||||
while (runtime) {
|
||||
System.out.print("trie> ");
|
||||
String input = br.readLine();
|
||||
String[] splited = input.split(" ");
|
||||
char ch = splited[0].charAt(0);
|
||||
ch = Character.toLowerCase(ch);
|
||||
try {
|
||||
switch(ch) {
|
||||
case 'n' :
|
||||
if (splited.length != 1) {
|
||||
System.out.println("Error! Wrong Parameter! "
|
||||
+ "check HELP");
|
||||
break;
|
||||
}
|
||||
t = new Trie();
|
||||
break;
|
||||
case 'a' :
|
||||
if (splited.length != 3) {
|
||||
System.out.println("Error! Wrong Parameter! "
|
||||
+ "check HELP");
|
||||
break;
|
||||
}
|
||||
if (!isCharString(splited[1])) {
|
||||
System.out.println("Error! Wrong Parameter! "
|
||||
+ "check HELP");
|
||||
break;
|
||||
}
|
||||
if (Integer.parseInt(splited[2]) < 0) {
|
||||
System.out.println("Error! Wrong Parameter! "
|
||||
+ "check HELP");
|
||||
break;
|
||||
}
|
||||
if (!t.add(splited[1], Integer.parseInt(splited[2]))) {
|
||||
System.out.println("Error! " + splited[1]
|
||||
+ " is already present.");
|
||||
}
|
||||
break;
|
||||
case 'c' :
|
||||
if (splited.length != 3) {
|
||||
System.out.println("Error! Wrong Parameter! "
|
||||
+ "check HELP");
|
||||
break;
|
||||
}
|
||||
if (!isCharString(splited[1])) {
|
||||
System.out.println("Error! Wrong Parameter! "
|
||||
+ "check HELP");
|
||||
break;
|
||||
}
|
||||
if (Integer.parseInt(splited[2]) < 0) {
|
||||
System.out.println("Error! Wrong Parameter! "
|
||||
+ "check HELP");
|
||||
break;
|
||||
}
|
||||
if (!t.change(splited[1], Integer.parseInt(splited[2]))) {
|
||||
System.out.println("Error! " + splited[1]
|
||||
+ " does not yet exist");
|
||||
}
|
||||
break;
|
||||
case 'd' :
|
||||
if (splited.length != 2) {
|
||||
System.out.println("Error! Wrong Parameter! "
|
||||
+ "check HELP");
|
||||
break;
|
||||
}
|
||||
if (!isCharString(splited[1])) {
|
||||
System.out.println("Error! Wrong Parameter! "
|
||||
+ "check HELP");
|
||||
break;
|
||||
}
|
||||
if (!t.delete(splited[1])) {
|
||||
System.out.println("Error! " + splited[1]
|
||||
+ " does not yet exist");
|
||||
}
|
||||
break;
|
||||
case 'p' :
|
||||
if (splited.length != 2) {
|
||||
System.out.println("Error! Wrong Parameter! "
|
||||
+ "check HELP");
|
||||
break;
|
||||
}
|
||||
if (!isCharString(splited[1])) {
|
||||
System.out.println("Error! Wrong Parameter! "
|
||||
+ "check HELP");
|
||||
break;
|
||||
}
|
||||
if (t.points(splited[1]) != null) {
|
||||
System.out.println(t.points(splited[1]));
|
||||
} else {
|
||||
System.out.println("Error! " + splited[1]
|
||||
+ " does not yet exist");
|
||||
}
|
||||
|
||||
break;
|
||||
case 't' :
|
||||
if (splited.length != 1) {
|
||||
System.out.println("Error! Wrong Parameter! "
|
||||
+ "check HELP");
|
||||
break;
|
||||
}
|
||||
System.out.println(t.toString());
|
||||
break;
|
||||
case 'h' :
|
||||
if (splited.length != 1) {
|
||||
System.out.println("Error! Wrong Parameter! "
|
||||
+ "check HELP");
|
||||
break;
|
||||
}
|
||||
System.out.println("NEW Creates a new empty Trie ");
|
||||
System.out.println("ADD adds <name> with <points>");
|
||||
System.out.println("CHANGE change <points> of <name>");
|
||||
System.out.println("DELETE deletes <name>");
|
||||
System.out.println("POINTS displays points of <name>");
|
||||
System.out.println("TRIE displays hole Trie");
|
||||
System.out.println("HELP display this help");
|
||||
System.out.println("QUIT exit Shell");
|
||||
break;
|
||||
case 'q' :
|
||||
if (splited.length != 1) {
|
||||
System.out.println("Error! Wrong Parameter! check HELP");
|
||||
break;
|
||||
}
|
||||
runtime = false;
|
||||
break;
|
||||
default :
|
||||
System.out.println("Error! Wrong command check HELP");
|
||||
}
|
||||
} catch (NumberFormatException e) {
|
||||
System.out.println("Error! Wrong Parameter! check HELP");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
BIN
Tries/Trie.class
Normal file
BIN
Tries/Trie.class
Normal file
Binary file not shown.
103
Tries/Trie.java
Normal file
103
Tries/Trie.java
Normal file
@@ -0,0 +1,103 @@
|
||||
/**
|
||||
* Provides methods to manipulate the Trie. <br />
|
||||
* The Trie only saves the root Node of which every Trie-Operation starts.
|
||||
*/
|
||||
public class Trie {
|
||||
|
||||
/**
|
||||
* The root Node of the Trie.
|
||||
*/
|
||||
private Node root;
|
||||
/**
|
||||
* creates new Trie.
|
||||
*/
|
||||
public Trie() {
|
||||
this.root = new Node();
|
||||
}
|
||||
|
||||
/**
|
||||
* adds new Student <code>key</code> with
|
||||
* points <code>points</code> to the Trie.
|
||||
* @param key Student to add
|
||||
* @param points points of Student
|
||||
* @return <code>true</code> if add was successful or <br />
|
||||
* <code>false</code> if Student already exists
|
||||
*/
|
||||
public boolean add(String key, Integer points) {
|
||||
Node iterator = this.root;
|
||||
for (int i = 0; i < key.length(); i++) {
|
||||
if (iterator.getChild(key.charAt(i)) == null) {
|
||||
new Node(key.charAt(i), iterator);
|
||||
}
|
||||
iterator = iterator.getChild(key.charAt(i));
|
||||
}
|
||||
if (iterator.getPoints() == null) {
|
||||
iterator.setPoints(points);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* deletes Student <code>key</code> in the Trie.
|
||||
* @param key Student to delete
|
||||
* @return <code>true</code> if delete was successful or <br />
|
||||
* <code>false></code> if Student does not exist
|
||||
*/
|
||||
public boolean delete(String key) {
|
||||
Node hlp = this.root.find(key);
|
||||
if (hlp == null) {
|
||||
return false;
|
||||
}
|
||||
if (hlp.getPoints() != null) {
|
||||
hlp.deleteMe();
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* changes points <code>points</code> of Student <code>key</code>
|
||||
* in the Trie.
|
||||
* @param key Student to change
|
||||
* @param points points of Student to change
|
||||
* @return <code>true</code> if change was successful or<br />
|
||||
* <code>false</code> if Student does not exist
|
||||
*/
|
||||
public boolean change(String key, Integer points) {
|
||||
Node hlp = this.root.find(key);
|
||||
if (hlp == null) {
|
||||
return false;
|
||||
}
|
||||
if (hlp.getPoints() != null) {
|
||||
hlp.setPoints(points);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for points of Student <code>key</code> in the Trie.
|
||||
* @param key Student to search for
|
||||
* @return <code>points</code> of Student or<br />
|
||||
* <code>null</code> if Student does not exist
|
||||
*/
|
||||
public Integer points(String key) {
|
||||
Node hlp = this.root.find(key);
|
||||
if (hlp != null) {
|
||||
return hlp.getPoints();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to print the hole Trie.
|
||||
* @return <code>string</code> of the Trie in the requested format
|
||||
*/
|
||||
public String toString() {
|
||||
return this.root.toString();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user