Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added Trie #162

Open
wants to merge 11 commits into
base: master
Choose a base branch
from
Open
32 changes: 32 additions & 0 deletions examples/trie/trie.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// Copyright (c) 2015, Emir Pasic. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package main

import (
"fmt"
trie "github.com/emirpasic/gods/trees/trie"
)

func main() {
fmt.Println("a")
t := trie.New()
words := []string{"sam", "john", "tim", "jose", "rose",
"cat", "dog", "dogg", "roses"}
for i := 0; i < len(words); i++ {
t.Insert(words[i])
}
wordsToFind := []string{
"sam", "john", "tim", "jose", "rose",
"cat", "dog", "dogg", "roses", "rosess", "ans", "san",
}
for i := 0; i < len(wordsToFind); i++ {
found := t.Contains(wordsToFind[i])
if found {
fmt.Printf("Word \"%s\" found in trie\n", wordsToFind[i])
} else {
fmt.Printf("Word \"%s\" not found in trie\n", wordsToFind[i])
}
}
}
36 changes: 36 additions & 0 deletions lists/arraylist/arraylist.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,22 @@ func (list *List) Add(values ...interface{}) {
}
}

// Reverse reverse the list
func (list *List) Reverse() {
var s = list.Size()

if s < 1 {
return
}

var temp = list.elements[0]
for i := 0; i < s / 2; i++ {
temp = list.elements[i]
list.elements[i] = list.elements[s - 1 - i]
list.elements[s - 1 - i] = temp
}
}

// Get returns the element at index.
// Second return parameter is true if index is within bounds of the array and array is not empty, otherwise false.
func (list *List) Get(index int) (interface{}, bool) {
Expand Down Expand Up @@ -126,6 +142,17 @@ func (list *List) Size() int {
return list.size
}

// Count returns number of occurences of a given value in the list
func (list *List) Count(value interface{}) int {
var count = 0
for i := 0; i < list.Size(); i++ {
if list.elements[i] == value {
count++
}
}
return count
}

// Clear removes all elements from the list.
func (list *List) Clear() {
list.size = 0
Expand Down Expand Up @@ -183,6 +210,15 @@ func (list *List) Set(index int, value interface{}) {
list.elements[index] = value
}

// Replace replaces all occurences of "value" by "by"
func (list *List) Replace(value interface{}, by interface{}) {
for i := 0; i < list.Size(); i++ {
if list.elements[i] == value {
list.elements[i] = by
}
}
}

// String returns a string representation of container
func (list *List) String() string {
str := "ArrayList\n"
Expand Down
54 changes: 54 additions & 0 deletions lists/arraylist/arraylist_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,60 @@ func TestListAdd(t *testing.T) {
}
}

func TestListReverse(t *testing.T) {
list := New()
list.Add("a", "b", "c")
list.Reverse()
if actualValue, ok := list.Get(0); actualValue != "c" || !ok {
t.Errorf("Got %v expected %v", actualValue, "c")
}
if actualValue, ok := list.Get(1); actualValue != "b" || !ok {
t.Errorf("Got %v expected %v", actualValue, "b")
}
if actualValue, ok := list.Get(2); actualValue != "a" || !ok {
t.Errorf("Got %v expected %v", actualValue, "a")
}
}

func TestListCount(t *testing.T){
list := New()
list.Add("a", "b", "c", "b", "b", "a", "d", "e", "f", "e")
if actualValue := list.Count("a"); actualValue != 2 {
t.Errorf("Got %v expected %v", actualValue, 2)
}
if actualValue := list.Count("b"); actualValue != 3 {
t.Errorf("Got %v expected %v", actualValue, 3)
}
if actualValue := list.Count("c"); actualValue != 1 {
t.Errorf("Got %v expected %v", actualValue, 1)
}
if actualValue := list.Count("z"); actualValue != 0 {
t.Errorf("Got %v expected %v", actualValue, 0)
}
}

func TestListReplace(t *testing.T){
list := New()
list.Add("a", "b", "c", "c", "a")
list.Replace("a", "z")
if actualValue, ok := list.Get(0); actualValue != "z" || !ok {
t.Errorf("Got %v expected %v", actualValue, "z")
}
if actualValue, ok := list.Get(1); actualValue != "b" || !ok {
t.Errorf("Got %v expected %v", actualValue, "b")
}
if actualValue, ok := list.Get(2); actualValue != "c" || !ok {
t.Errorf("Got %v expected %v", actualValue, "c")
}
if actualValue, ok := list.Get(3); actualValue != "c" || ok {
t.Errorf("Got %v expected %v", actualValue, "c")
}
list.Remove(0)
if actualValue, ok := list.Get(0); actualValue != "z" || !ok {
t.Errorf("Got %v expected %v", actualValue, "z")
}
}

func TestListIndexOf(t *testing.T) {
list := New()

Expand Down
3 changes: 3 additions & 0 deletions lists/lists.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ type List interface {
Get(index int) (interface{}, bool)
Remove(index int)
Add(values ...interface{})
Count(value interface{})
Reverse()
Replace(value interface{}, by interface{})
Contains(values ...interface{}) bool
Sort(comparator utils.Comparator)
Swap(index1, index2 int)
Expand Down
83 changes: 83 additions & 0 deletions trees/trie/iterator.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
package trie

import "github.com/emirpasic/gods/containers"

func assertIteratorImplementation() {
var _ containers.ReverseIteratorWithIndex = (*Iterator)(nil)
}

// Iterator holding the iterator's state
type Iterator struct {
words []string
trie *Trie
index int
}

// Iterator returns a stateful iterator whose values can be fetched by an index.
func (trie *Trie) Iterator() Iterator {
s := make([]string, 10)
findWords(trie.root, "", s)
return Iterator{words:s, trie: trie, index:-1}
}

// Next moves the iterator to the next element and returns true if there was a next element in the container.
// If Next() returns true, then next element's index and value can be retrieved by Index() and Value().
// If Next() was called for the first time, then it will point the iterator to the first element if it exists.
// Modifies the state of the iterator.
func (iterator *Iterator) Next() bool {
if iterator.index < iterator.heap.Size() {
iterator.index++
}
return iterator.words.withinRange(iterator.index)
}

// Prev moves the iterator to the previous element and returns true if there was a previous element in the container.
// If Prev() returns true, then previous element's index and value can be retrieved by Index() and Value().
// Modifies the state of the iterator.
func (iterator *Iterator) Prev() bool {
if iterator.index >= 0 {
iterator.index--
}
return iterator.words.withinRange(iterator.index)
}

// Value returns the current element's value.
// Does not modify the state of the iterator.
func (iterator *Iterator) Value() interface{} {
value, _ := iterator.words.list.Get(iterator.index)
return value
}

// Index returns the current element's index.
// Does not modify the state of the iterator.
func (iterator *Iterator) Index() int {
return iterator.index
}

// Begin resets the iterator to its initial state (one-before-first)
// Call Next() to fetch the first element if any.
func (iterator *Iterator) Begin() {
iterator.index = -1
}

// End moves the iterator past the last element (one-past-the-end).
// Call Prev() to fetch the last element if any.
func (iterator *Iterator) End() {
iterator.index = iterator.words.Size()
}

// First moves the iterator to the first element and returns true if there was a first element in the container.
// If First() returns true, then first element's index and value can be retrieved by Index() and Value().
// Modifies the state of the iterator.
func (iterator *Iterator) First() bool {
iterator.Begin()
return iterator.Next()
}

// Last moves the iterator to the last element and returns true if there was a last element in the container.
// If Last() returns true, then last element's index and value can be retrieved by Index() and Value().
// Modifies the state of the iterator.
func (iterator *Iterator) Last() bool {
iterator.End()
return iterator.Prev()
}
30 changes: 30 additions & 0 deletions trees/trie/serialization.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package trie

import "github.com/emirpasic/gods/containers"

func assertSerializationImplementation() {
var _ containers.JSONSerializer = (*Trie)(nil)
var _ containers.JSONDeserializer = (*Trie)(nil)
}

// ToJSON outputs the JSON representation of the heap.
func (t *Trie) ToJSON() ([]byte, error) {
elements := make([]interface{})
it := trie.Iterator(t)
for it.Next() {
elements.append(it.Value())
}
return json.Marshal(&elements)
}

// FromJSON populates the tree from the input JSON representation.
func (t *Trie) FromJSON(data []byte) error {
elements := make([]interface{})
err := json.Unmarshal(data, &elements)
if err == nil {
for _, value := range elements {
t.insert(value)
}
}
return err
}
107 changes: 107 additions & 0 deletions trees/trie/trie.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
package trie

const (
// AlphabetSize total characters in english alphabet
AlphabetSize = 26
)

<<<<<<< HEAD
Copy link
Owner

Choose a reason for hiding this comment

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

@sepehrs1378 Conflicts?

Copy link
Author

Choose a reason for hiding this comment

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

Sorry about that. My friend fixed it.

type TrieNode struct {
children [AlphabetSize]*TrieNode
isWordEnd bool
}

type Trie struct {
root *TrieNode
}

// New returns a pointer pointing to a new Trie
func New() *Trie {
return &Trie{
root: &TrieNode{},
}
}

// Insert inserts a word into the Trie
func (t *Trie) Insert(word string) {
=======
type trieNode struct {
children [AlphabetSize]*trieNode
isWordEnd bool
}

type trie struct {
root *trieNode
nodesCount int
}

// New returns a pointer pointing to a new trie
func New() *trie {
return &trie{
root: &trieNode{},
}
}

// Insert inserts a word into the trie
func (t *trie) Insert(word string) {
>>>>>>> 2896b350131353759aacf42da7047972425068eb
wordLength := len(word)
current := t.root
for i := 0; i < wordLength; i++ {
index := word[i] - 'a'
if current.children[index] == nil {
<<<<<<< HEAD
current.children[index] = &TrieNode{}
=======
current.children[index] = &trieNode{}
t.nodesCount++
>>>>>>> 2896b350131353759aacf42da7047972425068eb
}
current = current.children[index]
}
current.isWordEnd = true
}

<<<<<<< HEAD
// Contains checks whether the Trie has the given word or not
func (t *Trie) Contains(word string) bool {
=======
// Contains checks whether the trie has the given word or not
func (t *trie) Contains(word string) bool {
>>>>>>> 2896b350131353759aacf42da7047972425068eb
wordLength := len(word)
current := t.root
for i := 0; i < wordLength; i++ {
index := word[i] - 'a'
if current.children[index] == nil {
return false
}
current = current.children[index]
}

return current.isWordEnd
<<<<<<< HEAD
}

func (trie *TrieNode, value string, values []string) findWords(){
for i := 0; i< 26 ; i++ {
if trie.isWordEnd {
values.append(value+string(i+'a'))
}
if trie.children[i] != nil {
findWords(trie.children[i], value+string(i+'a'), values)
}
}
=======
}

// NodesCount returns number of nodes in the tree.
func (t *trie) NodesCount() int {
return t.nodesCount
}

// Empty returns true if tree does not contain any nodes except for root
func (t *trie) Empty() bool {
return t.nodesCount == 0
>>>>>>> 2896b350131353759aacf42da7047972425068eb
}
Loading