Skip to content

Commit ad4d516

Browse files
committed
add symbol graph
1 parent ed9d468 commit ad4d516

File tree

5 files changed

+176
-14
lines changed

5 files changed

+176
-14
lines changed

cmd/symbol-graph/main.go

+68
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
/*
2+
Execution: go run cmd/symbol-graph/main.go filename.txt delimiter
3+
Data files: https://algs4.cs.princeton.edu/41graph/routes.txt
4+
https://algs4.cs.princeton.edu/41graph/movies.txt
5+
https://algs4.cs.princeton.edu/41graph/moviestiny.txt
6+
https://algs4.cs.princeton.edu/41graph/moviesG.txt
7+
https://algs4.cs.princeton.edu/41graph/moviestopGrossing.txt
8+
9+
% go run cmd/symbol-graph/main.go routes.txt " "
10+
JFK
11+
MCO
12+
ATL
13+
ORD
14+
LAX
15+
PHX
16+
LAS
17+
18+
% go run cmd/symbol-graph/main.go movies.txt "/"
19+
Tin Men (1987)
20+
Hershey, Barbara
21+
Geppi, Cindy
22+
Jones, Kathy (II)
23+
Herr, Marcia
24+
...
25+
Blumenfeld, Alan
26+
DeBoy, David
27+
Bacon, Kevin
28+
Woodsman, The (2004)
29+
Wild Things (1998)
30+
Where the Truth Lies (2005)
31+
Tremors (1990)
32+
...
33+
Apollo 13 (1995)
34+
Animal House (1978)
35+
36+
37+
Assumes that input file is encoded using UTF-8.
38+
% iconv -f ISO-8859-1 -t UTF-8 movies-iso8859.txt > movies.txt
39+
*/
40+
41+
package main
42+
43+
import (
44+
"fmt"
45+
"os"
46+
"strings"
47+
48+
"github.com/shellfly/algo"
49+
"github.com/shellfly/algo/stdin"
50+
)
51+
52+
func main() {
53+
sg := algo.NewSymbolGraph(os.Args[1])
54+
g := sg.G()
55+
stdin := stdin.NewStdIn()
56+
for !stdin.IsEmpty() {
57+
source := strings.Trim(stdin.ReadString(), " ")
58+
if sg.Contains(source) {
59+
s := sg.Index(source)
60+
for _, v := range g.Adj(s) {
61+
fmt.Println(" ", sg.Name(v))
62+
}
63+
fmt.Println()
64+
} else {
65+
fmt.Println("input not contains source: ", source)
66+
}
67+
}
68+
}

graph.go

+9
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,15 @@ func NewGraph(in *stdin.In) *Graph {
2828
return g
2929
}
3030

31+
// NewGraphV ...
32+
func NewGraphV(v int) *Graph {
33+
adj := make([]*Bag, v)
34+
for i := 0; i < v; i++ {
35+
adj[i] = NewBag()
36+
}
37+
return &Graph{v: v, e: 0, adj: adj}
38+
}
39+
3140
// V ...
3241
func (g *Graph) V() int {
3342
return g.v

st.go

+23-14
Original file line numberDiff line numberDiff line change
@@ -18,33 +18,38 @@ func (k StringKey) compareTo(other interface{}) int {
1818
return 0
1919
}
2020

21-
// ST is symbol table
22-
type ST struct{}
21+
// ST is symbol table implemented by go map[string]int
22+
type ST map[string]int
2323

24-
// Put add new key value pair into the st
25-
func (st ST) Put(key, value interface{}) {
24+
// NewST ...
25+
func NewST() ST {
26+
return make(ST)
27+
}
2628

29+
// Put add new key value pair into the st
30+
func (st ST) Put(key string, val int) {
31+
st[key] = val
2732
}
2833

2934
// Get add new key value pair into the st
30-
func (st ST) Get(key interface{}) (value interface{}) {
31-
return nil
35+
func (st ST) Get(key string) int {
36+
return st[key]
3237
}
3338

3439
// Delete ...
35-
func (st ST) Delete(key interface{}) {
36-
return
40+
func (st ST) Delete(key string) {
41+
delete(st, key)
3742
}
3843

3944
// Contains ...
40-
func (st ST) Contains(key interface{}) bool {
41-
return false
42-
45+
func (st ST) Contains(key string) bool {
46+
_, ok := st[key]
47+
return ok
4348
}
4449

4550
// Size ...
4651
func (st ST) Size() int {
47-
return 0
52+
return len(st)
4853
}
4954

5055
// IsEmpty add new key value pair into the st
@@ -53,6 +58,10 @@ func (st ST) IsEmpty() bool {
5358
}
5459

5560
// Keys ...
56-
func (st ST) Keys() []interface{} {
57-
return nil
61+
func (st ST) Keys() []string {
62+
keys := make([]string, 0, len(st))
63+
for k := range st {
64+
keys = append(keys, k)
65+
}
66+
return keys
5867
}

stdin/in.go

+12
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,17 @@ type In struct {
1212
scanner *bufio.Scanner
1313
}
1414

15+
// NewInByLine return a pointer of In
16+
func NewInByLine(path string) *In {
17+
inFile, err := os.Open(path)
18+
if err != nil {
19+
fmt.Println(err)
20+
panic("Can not open file: " + path)
21+
}
22+
scanner := bufio.NewScanner(inFile)
23+
return &In{scanner}
24+
}
25+
1526
// NewIn return a pointer of In
1627
func NewIn(path string) *In {
1728
inFile, err := os.Open(path)
@@ -31,6 +42,7 @@ func (in In) IsEmpty() bool {
3142

3243
// ReadString return next string by delimiter of ' '
3344
func (in In) ReadString() string {
45+
3446
return in.scanner.Text()
3547
}
3648

symbol_graph.go

+64
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
package algo
2+
3+
import (
4+
"strings"
5+
6+
"github.com/shellfly/algo/stdin"
7+
)
8+
9+
// SymbolGraph ...
10+
type SymbolGraph struct {
11+
st ST
12+
keys []string
13+
g *Graph
14+
}
15+
16+
// NewSymbolGraph ...
17+
func NewSymbolGraph(filename string) *SymbolGraph {
18+
st := NewST()
19+
in := stdin.NewInByLine(filename)
20+
for !in.IsEmpty() {
21+
a := strings.Split(in.ReadString(), " ")
22+
for i := 0; i < len(a); i++ {
23+
if !st.Contains(a[i]) {
24+
st.Put(a[i], st.Size())
25+
}
26+
}
27+
}
28+
29+
keys := make([]string, st.Size())
30+
for _, name := range st.Keys() {
31+
keys[st.Get(name)] = name
32+
}
33+
34+
g := NewGraphV(st.Size())
35+
in = stdin.NewInByLine(filename)
36+
for !in.IsEmpty() {
37+
a := strings.Split(in.ReadString(), " ")
38+
v := st.Get(a[0])
39+
for i := 1; i < len(a); i++ {
40+
g.AddEdge(v, st.Get(a[i]))
41+
}
42+
}
43+
return &SymbolGraph{st, keys, g}
44+
}
45+
46+
// Contains ...
47+
func (s *SymbolGraph) Contains(key string) bool {
48+
return s.st.Contains(key)
49+
}
50+
51+
// Index ...
52+
func (s *SymbolGraph) Index(key string) int {
53+
return s.st.Get(key)
54+
}
55+
56+
// Name ...
57+
func (s *SymbolGraph) Name(v int) string {
58+
return s.keys[v]
59+
}
60+
61+
// G ...
62+
func (s *SymbolGraph) G() *Graph {
63+
return s.g
64+
}

0 commit comments

Comments
 (0)