Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
.DS_Store
9 changes: 9 additions & 0 deletions hw3_Trie/.idea/compiler.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

17 changes: 17 additions & 0 deletions hw3_Trie/.idea/gradle.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions hw3_Trie/.idea/misc.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 10 additions & 0 deletions hw3_Trie/.idea/modules.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

13 changes: 13 additions & 0 deletions hw3_Trie/.idea/modules/bor.iml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

13 changes: 13 additions & 0 deletions hw3_Trie/.idea/modules/bor_main.iml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

17 changes: 17 additions & 0 deletions hw3_Trie/.idea/modules/bor_test.iml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 14 additions & 0 deletions hw3_Trie/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
group 'ru.spbau'
version '1.0-SNAPSHOT'

apply plugin: 'java'

sourceCompatibility = 1.8

repositories {
mavenCentral()
}

dependencies {
testCompile group: 'junit', name: 'junit', version: '4.12'
}
Binary file added hw3_Trie/gradle/wrapper/gradle-wrapper.jar
Binary file not shown.
6 changes: 6 additions & 0 deletions hw3_Trie/gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#Mon Oct 02 23:10:25 MSK 2017
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-3.5-rc-2-bin.zip
2 changes: 2 additions & 0 deletions hw3_Trie/settings.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
rootProject.name = 'bor'

245 changes: 245 additions & 0 deletions hw3_Trie/src/main/java/ru/spbau/solikov/src/Trie.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,245 @@
package ru.spbau.solikov.src;

import java.io.*;
import java.util.HashMap;
import java.util.Map;

/**
* Implementation of data structure "trie" that can store strings over some finite alphabet
*/
public class Trie implements Serializable {

private static final int ALPHABET_SIZE = 26;

/**
* Function to obtain the letter in String from integer
*
* @param i number of letter
* @return string
*/
private static String getCharForNumber(int i) {
return i > 0 && i < 27 ? String.valueOf((char) (i + 64)) : null;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

не стоит использовать в коде магические константы

}

private static final Map<String, Integer> alphabet;

static {
alphabet = new HashMap<String, Integer>();
for (int i = 0; i < ALPHABET_SIZE; i++) {
alphabet.put(getCharForNumber(i + 1), i);
}
}

/**
* Implementation of trie's node with static array
*/
private class TrieNode implements Serializable {
private boolean isTerminal = false;
private int size = 0;
private TrieNode nodes[] = new TrieNode[ALPHABET_SIZE];
}

private TrieNode root;

public Trie() {
root = new TrieNode();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

лучше совместить с инициализацией

}

/**
* Function that adds string from letters of alphabet to the trie.
* Returns true if the trie didn't have that string before.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

это не нужно в общем описании, для этого есть тег @return ниже
а вот что в описание стоит добавить, так это асимптотику операции

* False otherwise.
* Supports size.
*
* @param element string to be added
* @return true if element already in trie, false otherwise
*/
public boolean add(String element) {

TrieNode current = root;
int index = -1;
int indexLastElement = 0;

for (int i = 0; i < element.length(); i++) {
indexLastElement = i;
char c = element.charAt(i);
index = alphabet.get(Character.toString(c));
if (current.nodes[index] != null) {
current = current.nodes[index];
} else {
current.nodes[index] = new TrieNode();
current = current.nodes[index];
}
}

if (current.isTerminal) {
return false;
}

current.isTerminal = true;


current.size++;
current = root;
for (int i = 0; i <= indexLastElement; i++) {
char c = element.charAt(i);
int indexCurrent = alphabet.get(Character.toString(c));
current.size++;
current = current.nodes[indexCurrent];
}
return true;

}

/**
* Checks if element is in trie.
*
* @param element to be checked
* @return true if element is in trie, false otherwise
*/
public boolean contains(String element) {

TrieNode current = root;

for (int i = 0; i < element.length(); i++) {
char c = element.charAt(i);
int index = alphabet.get(Character.toString(c));
if (current.nodes[index] != null) {
current = current.nodes[index];
} else {
return false;
}
}

return current.isTerminal;
}

/**
* Removes element from trie. If that element is not prefix of any other element in trie,
* then deletes all nodes till last terminal vertex from up to down.
*
* @param element to be removed
* @return true if element was in trie, false otherwise
*/
public boolean remove(String element) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

это какая-то очень сложная функция, предлагаю выделить из неё несколько вспомогательных с хорошими именами. а то может и в класс ноды какую-нибудь функциональность убрать


TrieNode current = root;
TrieNode lastElement = root;
int indexLastElement = 0;
int index = -1;

for (int i = 0; i < element.length(); i++) {
char c = element.charAt(i);
index = alphabet.get(Character.toString(c));

if (current.isTerminal) {
lastElement = current;
indexLastElement = i;
}

if (current.nodes[index] != null) {
current = current.nodes[index];
} else {
return false;
}
}

if (current.isTerminal) {
for (int i = 0; i < ALPHABET_SIZE; i++) {
if (current.nodes[i] != null) {
current.isTerminal = false;
current = root;
for (int j = 0; j <= indexLastElement; j++) {
char c = element.charAt(j);
int indexCurrent = alphabet.get(Character.toString(c));
current.size--;
current = current.nodes[indexCurrent];
}
return true;
}
}

removePath(lastElement, element.substring(indexLastElement));

current = root;
for (int i = 0; i <= indexLastElement; i++) {
char c = element.charAt(i);
int indexCurrent = alphabet.get(Character.toString(c));
current.size--;
current = current.nodes[indexCurrent];
}
return true;
}
return false;
}

private void removePath(TrieNode node, String element) {

if (element.length() == 0) {
return;
}

removePath(node.nodes[alphabet.get(Character.toString(element.charAt(0)))], element.substring(1));
node.nodes[alphabet.get(Character.toString(element.charAt(0)))] = null;

}

/**
* Returns number of strings stored in trie. Is equal to number of terminal vertices.
*
* @return size
*/
public int size() {
return (root != null) ? root.size : 0;
}

/**
* Returns number of strings started with prefix stored in trie.
* Is equal to number of terminal vertices in subtrie of last prefix letter's node.
*
* @param prefix to be checked for size
* @return size
*/
public int howManyStartsWithPrefix(String prefix) {

TrieNode current = root;

for (int i = 0; i < prefix.length(); i++) {
char c = prefix.charAt(i);
int index = alphabet.get(Character.toString(c));
if (current.nodes[index] != null) {
current = current.nodes[index];
} else {
return 0;
}
}

return current.size;
}

/**
* Takes output stream and serializes class Trie to that stream with standard Java method
*
* @param out stream in what it will write Trie
* @throws IOException exceptions that could appear while writing
*/
public void serialize(OutputStream out) throws IOException {
ObjectOutputStream oos = new ObjectOutputStream(out);
oos.writeObject(this);
oos.flush();
oos.close();
}

/**
* Takes input stream and reads class from that stream with standard Java method
*
* @param in stream from what it will read information about Trie
* @throws IOException exceptions that could appear while reading
* @throws ClassNotFoundException exception if there's no such file
*/
public void deserialize(InputStream in) throws IOException, ClassNotFoundException {
ObjectInputStream oin = new ObjectInputStream(in);
Trie other = (Trie) oin.readObject();
this.root = other.root;
}
}
Loading