我正试图在旅行中解决equivalent binary trees运动。这就是我所做的;
package main
import "tour/tree"
import "fmt"
// Walk walks the tree t sending all values
// from the tree to the channel ch.
func Walk(t *tree.Tree, ch chan int) {
if t.Left != nil {
Walk(t.Left, ch)
}
ch <- t.Value
if t.Right != nil {
Walk(t.Right, ch)
}
}
// Same determines whether the trees
// t1 and t2 contain the same values.
func Same(t1, t2 *tree.Tree) bool {
ch1 := make(chan int)
ch2 := make(chan int)
go Walk(t1, ch1)
go Walk(t2, ch2)
for k := range ch1 {
select {
case g := <-ch2:
if k != g {
return false
}
default:
break
}
}
return true
}
func main() {
fmt.Println(Same(tree.New(1), tree.New(1)))
fmt.Println(Same(tree.New(1), tree.New(2)))
}
然而,我无法找到如何在树木中留下更多元素的信号。我无法在close(ch)
上使用Walk()
,因为它会在所有值发送之前使通道关闭(因为递归。)任何人都可以帮我一把吗?
答案 0 :(得分:90)
func Walk(t *tree.Tree, ch chan int) {
defer close(ch) // <- closes the channel when this function returns
var walk func(t *tree.Tree)
walk = func(t *tree.Tree) {
if t == nil {
return
}
walk(t.Left)
ch <- t.Value
walk(t.Right)
}
walk(t)
}
答案 1 :(得分:20)
这里是使用此处和Google Group主题
中的创意的完整解决方案package main
import "fmt"
import "code.google.com/p/go-tour/tree"
// Walk walks the tree t sending all values
// from the tree to the channel ch.
func Walk(t *tree.Tree, ch chan int) {
var walker func(t *tree.Tree)
walker = func (t *tree.Tree) {
if (t == nil) {
return
}
walker(t.Left)
ch <- t.Value
walker(t.Right)
}
walker(t)
close(ch)
}
// Same determines whether the trees
// t1 and t2 contain the same values.
func Same(t1, t2 *tree.Tree) bool {
ch1, ch2 := make(chan int), make(chan int)
go Walk(t1, ch1)
go Walk(t2, ch2)
for {
v1,ok1 := <- ch1
v2,ok2 := <- ch2
if v1 != v2 || ok1 != ok2 {
return false
}
if !ok1 {
break
}
}
return true
}
func main() {
fmt.Println("1 and 1 same: ", Same(tree.New(1), tree.New(1)))
fmt.Println("1 and 2 same: ", Same(tree.New(1), tree.New(2)))
}
答案 2 :(得分:16)
如果您的Walk函数本身没有递归,您可以使用close()。即步行只会:
func Walk(t *tree.Tree, ch chan int) {
walkRecurse(t, ch)
close(ch)
}
其中walkRecurse或多或少是你当前的Walk函数,但是在walkRecurse上递归。 (或者你重写Walk是迭代的 - 授予,更多是hazzle) 使用这种方法,您的Same()函数必须知道通道是closed,这是通过表单的通道接收来完成的
k, ok1 := <-ch
g, ok2 := <-ch
当ok1
和ok2
不同,或者false
另一种方式,但可能不是在练习的精神,是计算树中节点的数量:
func Same(t1, t2 *tree.Tree) bool {
countT1 := countTreeNodes(t1)
countT2 := countTreeNodes(t2)
if countT1 != countT2 {
return false
}
ch1 := make(chan int)
ch2 := make(chan int)
go Walk(t1, ch1)
go Walk(t2, ch2)
for i := 0; i < countT1; i++ {
if <-ch1 != <-ch2 {
return false
}
}
return true
}
你必须实现countTreeNodes()函数,它应该计算* Tree中节点的数量
答案 3 :(得分:7)
我就是这样做的,区别在于你可以将import Tkinter as tk
import random
class die(object):
def __init__(self, value, display):
self.value = random.randint(1,6)
self.display = tk.Label(display,
text = str(self.value),
font = ('Garamond', 56),
bg = 'white',
relief = 'ridge',
borderwidth = 5)
self.display.pack(side = 'left')
def rollDice(self):
self.value = random.randint(1,6)
print self.value #to show value is in fact changing
self.display.config(text = str(self.value))
class DiceRoller(object):
def __init__(self):
self.gameWin = tk.Tk()
self.gameWin.title('Dice Roller')
self.gameFrame = tk.Frame(self.gameWin)
self.dice = []
self.Row1 = tk.Frame(self.gameWin)
for i in range(1,4):
self.dice.append(die(i, self.Row1))
self.topFrame = tk.Frame(self.gameWin)
self.rollBtn = tk.Button(self.topFrame,
text = 'Roll Again',
command = self.rollDice,
font = ('Garamond', 56))
self.rollBtn.pack(side = 'bottom')
self.gameFrame.pack()
self.Row1.pack()
self.topFrame.pack()
self.gameWin.mainloop()
def rollDice(self):
for die in self.dice:
die.rollDice()
DiceRoller()
包装到匿名函数中并在其中包含Walk
。因此,您不必定义其他命名的递归函数
defer close(ch)
答案 4 :(得分:3)
以下是我提出的解决方案:
func Walker(t *tree.Tree, ch chan int){
if t==nil {return}
Walker(t.Left,ch)
ch<-t.Value
Walker(t.Right,ch)
}
func Walk(t *tree.Tree, ch chan int){
Walker(t,ch)
close(ch)
}
func Same(t1, t2 *tree.Tree) bool{
ch:=make(chan int)
dh:=make(chan int)
go Walk(t1,ch)
go Walk(t2,dh)
for i:=range ch {
j,ok:=<-dh
if(i!=j||!ok) {return false}
}
return true
}
答案 5 :(得分:2)
你得到的几乎是正确的,没有必要使用select
语句,因为你经常会经历default
这个案例,这是我的解决方案无需计算节点数发辫:
func Same(t1, t2 *tree.Tree) bool {
ch1, ch2 := make(chan int), make(chan int)
go Walk(t1, ch1)
go Walk(t2, ch2)
for i := range ch1 {
j, more := <-ch2
if more {
if i != j { return false }
} else { return false }
}
return true
}
答案 6 :(得分:2)
这是我的解决方法。
package main
import (
"golang.org/x/tour/tree"
"fmt"
)
// Walk walks the tree t sending all values
// from the tree to the channel ch.
func Walk(t *tree.Tree, ch chan int) {
if t == nil {
return
}
Walk(t.Left, ch)
ch <- t.Value
Walk(t.Right, ch)
}
// Same determines whether the trees
// t1 and t2 contain the same values.
func Same(t1, t2 *tree.Tree) bool {
ch1 := make(chan int)
ch2 := make(chan int)
go func() {
Walk(t1, ch1)
close(ch1)
}()
go func() {
Walk(t2, ch2)
close(ch2)
}()
for {
v1, ok1 := <- ch1
v2, ok2 := <- ch2
if ok1 == false && ok2 == false {
return true
}
if v1 != v2 {
return false
}
}
return false
}
func main() {
fmt.Println(Same(tree.New(1), tree.New(1)))
fmt.Println(Same(tree.New(1), tree.New(2)))
}
答案 7 :(得分:2)
package main
import (
"fmt"
"golang.org/x/tour/tree"
)
// Walk walks the tree t sending all values
// from the tree to the channel ch.
func Walk(t *tree.Tree, ch chan int) {
if t != nil {
Walk(t.Left, ch)
ch <- t.Value
Walk(t.Right, ch)
}
}
// Same determines whether the trees
// t1 and t2 contain the same values.
func Same(t1, t2 *tree.Tree) bool {
ch1, ch2 := make(chan int), make(chan int)
go func() { Walk(t1, ch1); close(ch1) }()
go func() { Walk(t2, ch2); close(ch2) }()
for v1 := range ch1 {
if v1 != <-ch2 {
return false
}
}
return true
}
func main() {
fmt.Println(Same(tree.New(1), tree.New(1)))
fmt.Println(Same(tree.New(2), tree.New(1)))
}
答案 8 :(得分:2)
这是我的解决方案。它适当地检查两个序列长度的差异。
package main
import "code.google.com/p/go-tour/tree"
import "fmt"
func Walk(t *tree.Tree, ch chan int) {
var walker func (t *tree.Tree)
walker = func (t *tree.Tree) {
if t.Left != nil {
walker(t.Left)
}
ch <- t.Value
if t.Right != nil {
walker(t.Right)
}
}
walker(t)
close(ch)
}
func Same(t1, t2 *tree.Tree) bool {
chana := make (chan int)
chanb := make (chan int)
go Walk(t1, chana)
go Walk(t2, chanb)
for {
n1, ok1 := <-chana
n2, ok2 := <-chanb
if n1 != n2 || ok1 != ok2 {
return false
}
if (!ok1) {
break
}
}
return true;
}
答案 9 :(得分:2)
虽然我的第一个直觉是包裹递归步行和关闭频道,但我觉得这不符合练习的精神。
练习文本包含以下信息:
函数
tree.New(k)
构造一个随机结构化(但始终排序)的二叉树,其中包含值k, 2k, 3k, ..., 10k
。
其中明确指出生成的树只有10个节点。
因此,在本练习的精神和简洁性中,我采用了以下解决方案:
package main
import (
"fmt"
"golang.org/x/tour/tree"
)
func Walk(t *tree.Tree, ch chan int) {
if t.Left != nil {
Walk(t.Left, ch)
}
ch <- t.Value
if t.Right != nil {
Walk(t.Right, ch)
}
}
func Same(t1, t2 *tree.Tree) bool {
ch1 := make(chan int)
ch2 := make(chan int)
defer close(ch1)
defer close(ch2)
go Walk(t1, ch1)
go Walk(t2, ch2)
for i := 0; i < 10; i++ {
if <-ch1 != <-ch2 {
return false
}
}
return true
}
func main() {
fmt.Println(Same(tree.New(1), tree.New(2)))
}
如果目标是在任意大小的树上运行,那么对封闭通道做出反应是更好的解决方案,但我觉得这是一个简单的练习,故意放置约束以使新Gopher更容易。
答案 10 :(得分:1)
之前的所有答案都没有解决有关Same
功能的任务。问题是:
// Same determines whether the trees
// t1 and t2 contain the same values.
func Same2(t1, t2 *tree.Tree) bool
不应该考虑树的结构。这就是为什么跟随测试失败,在两行中都给出了错误:
fmt.Println("Should return true:", Same(tree.New(1), tree.New(1)))
fmt.Println("Should return false:", Same(tree.New(1), tree.New(2)))
记住?
函数tree.New(k)构造一个随机结构(但总是排序)的二叉树,其中包含值k,2k,3k,...,10k。
您只需检查两棵树是否具有相同的值。任务说明清楚地注意到:
Same(tree.New(1), tree.New(1))
应返回true
,Same(tree.New(1), tree.New(2))
应返回false
。
因此,要解决此任务,您需要缓冲一棵树的所有结果,并检查第二棵树中的值是否在第一棵树中。
这是我的解决方案,它不是理想的:):
// Same determines whether the trees
// t1 and t2 contain the same values.
func Same(t1, t2 *tree.Tree) bool {
ch1, ch2 := make(chan int), make(chan int)
go Walk(t1, ch1)
go Walk(t2, ch2)
var tv1 = []int{}
for v := range ch1 {
tv1 = append(tv1, v)
}
inArray := func(arr []int, value int) bool {
for a := range arr {
if arr[a] == value {
return true
}
}
return false
}
for v2 := range ch2 {
if !inArray(tv1, v2) {
return false
}
}
return true
}
答案 11 :(得分:1)
尝试使用地图结构来解决这个问题。
html = """<!DOCTYPE html>
<html>
<head>
<title>Home</title>
</head>
<body>
<h1>Welcome!</h1>
</body>
</html>"""
with open('html_file.html', 'w') as f:
f.write(html)
import webbrowser, os
webbrowser.open('file://' + os.path.realpath('html_file.html'))
答案 12 :(得分:0)
这是一个非递归解决方案(即在大输入上不会有堆栈空间问题),它也不需要单独的访问地图 - 它只使用单个堆栈数据结构。避免访问过的地图的技巧是从堆栈中删除访问过的条目,而是为访问过的条目创建新的 tree.Tree
实例,删除左侧,这样它就不会重新访问左侧。
package main
import "fmt"
import "golang.org/x/tour/tree"
func Pop(stack []*tree.Tree) (*tree.Tree, []*tree.Tree) {
last := len(stack) - 1
node := stack[last]
stack[last] = nil
return node, stack[:last]
}
// Walk walks the tree t sending all values
// from the tree to the channel ch.
func Walk(t *tree.Tree, ch chan int) {
defer close(ch)
stack := []*tree.Tree{t}
var node *tree.Tree
for len(stack) > 0 {
node, stack = Pop(stack)
if node.Left != nil {
stack = append(stack, &tree.Tree{nil, node.Value, node.Right}, node.Left)
continue
}
ch <- node.Value
if node.Right != nil {
stack = append(stack, node.Right)
}
}
}
// Same determines whether the trees
// t1 and t2 contain the same values.
func Same(t1, t2 *tree.Tree) bool {
ch1, ch2 := make(chan int), make(chan int)
go Walk(t1, ch1)
go Walk(t2, ch2)
for {
v1, ok1 := <-ch1
v2, ok2 := <-ch2
if v1 != v2 {
return false
}
if !ok1 || !ok2 {
return ok1 == ok2
}
}
}
func PrintTree(t *tree.Tree) {
ch := make(chan int)
go Walk(t, ch)
for i := range ch {
fmt.Printf("%d ", i)
}
fmt.Println()
}
func main() {
PrintTree(tree.New(1))
PrintTree(&tree.Tree{Value: 1, Right: &tree.Tree{Value: 2}})
fmt.Println("1 and 2 same (false): ", Same(tree.New(1), tree.New(2)))
fmt.Println("1 and 1 same (true): ", Same(tree.New(1), tree.New(1)))
fmt.Println("empty same (true): ", Same(&tree.Tree{}, &tree.Tree{}))
fmt.Println("diff length same (false): ", Same(&tree.Tree{Value: 1}, &tree.Tree{Value: 2, Left: &tree.Tree{Value: 2}}))
}
输出为:
1 2 3 4 5 6 7 8 9 10
1 2
1 and 2 same (false): false
1 and 1 same (true): true
empty same (true): true
diff length same (false): false
答案 13 :(得分:0)
如果一个人正在使用带有 Walk
逻辑的递归调用,并且希望向渠道消费者发出信号表明没有更多项目,那么似乎可以将大部分 Walk
逻辑放入第二个函数,调用第二个函数,等待它完成,然后关闭通道。
在下面的示例中,第二个(“inner Walk”)函数是一个直接位于 Walk
函数内部的“闭包”,但并非必须如此。
package main
import "golang.org/x/tour/tree"
import "fmt"
// Walk walks the tree t sending all values
// from the tree to the channel ch.
func Walk(t *tree.Tree, ch chan int) {
defer close(ch)
var iw func(*tree.Tree)
iw = func(it *tree.Tree) {
if it == nil {
return
}
iw(it.Left)
ch <- it.Value
iw(it.Right)
}
iw(t)
}
// Same determines whether the trees
// t1 and t2 contain the same values.
func Same(t1, t2 *tree.Tree) bool {
ch1 := make(chan int)
ch2 := make(chan int)
go Walk(t1, ch1)
go Walk(t2, ch2)
for {
v1, more1 := <- ch1
v2, more2 := <- ch2
if (!more1 && !more2) {
return true
}
if more1 != more2 || v1 != v2 {
return false
}
}
}
func main() {
fmt.Println(Same(tree.New(1), tree.New(1)))
fmt.Println(Same(tree.New(1), tree.New(2)))
}
答案 14 :(得分:0)
到目前为止,在该线程中还没有看到它。我使用了just for func
中介绍的nil频道技术关闭通道的问题已通过在goroutine实例中启动它们来解决。
我想我可以检查更多表现出色的人。
package main
import (
"fmt"
"reflect"
"sort"
"golang.org/x/tour/tree"
)
// Walk walks the tree t sending all values
// from the tree to the channel ch.
func Walk(t *tree.Tree, ch chan int) {
ch <- t.Value
if t.Right != nil {
Walk(t.Right, ch)
}
if t.Left != nil {
Walk(t.Left, ch)
}
}
// Same determines whether the trees
// t1 and t2 contain the same values.
func Same(t1, t2 *tree.Tree) bool {
c1 := make(chan int)
s1 := []int{}
go func() {
Walk(t1, c1)
close(c1)
}()
c2 := make(chan int)
s2 := []int{}
go func() {
Walk(t2, c2)
close(c2)
}()
for c1 != nil || c2 != nil {
select {
case v, ok := <-c1:
if !ok {
c1 = nil
sort.Ints(s1)
continue
}
s1 = append(s1, v)
case v, ok := <-c2:
if !ok {
c2 = nil
sort.Ints(s2)
continue
}
s2 = append(s2, v)
}
}
return reflect.DeepEqual(s1, s2)
}
func main() {
fmt.Println(Same(tree.New(1), tree.New(1)))
}
答案 15 :(得分:0)
package main
import (
"fmt"
"golang.org/x/tour/tree"
)
// Walk walks the tree t sending all values
// from the tree to the channel ch.
func Walk(t *tree.Tree, ch chan int) {
walkRecursive(t, ch)
close(ch)
}
func walkRecursive(t *tree.Tree, ch chan int) {
if t == nil {
return
}
walkRecursive(t.Left, ch)
ch <- t.Value
walkRecursive(t.Right, ch)
}
// Same determines whether the trees
// t1 and t2 contain the same values.
func Same(t1, t2 *tree.Tree) bool {
ch1 := make(chan int)
ch2 := make(chan int)
go Walk(t1, ch1)
go Walk(t2, ch2)
for {
v1, ok1 := <-ch1
v2, ok2 := <-ch2
if ok1 != ok2 {
return false
}
if !ok1 {
return true
}
if v1 != v2 {
return false
}
}
}
func main() {
fmt.Println(Same(tree.New(1), tree.New(2)))
}
答案 16 :(得分:0)
这是我的解决方案,没有defer
的魔力。我认为这会更容易阅读,所以值得分享:)
奖金:此版本实际上解决了巡演中的问题并给出了适当的结果。
package main
import (
"golang.org/x/tour/tree"
"fmt"
)
// Walk walks the tree t sending all values
// from the tree to the channel ch.
func Walk(t *tree.Tree, ch chan int) {
walkRecursive(t, ch)
close(ch)
}
func walkRecursive(t *tree.Tree, ch chan int) {
if t != nil {
walkRecursive(t.Left, ch)
ch <- t.Value
walkRecursive(t.Right, ch)
}
}
// Same determines whether the trees
// t1 and t2 contain the same values.
func Same(t1, t2 *tree.Tree) bool {
var br bool
ch1, ch2 := make(chan int), make(chan int)
go Walk(t1, ch1)
go Walk(t2, ch2)
for i:= range ch1 {
if i == <-ch2 {
br = true
} else {
br = false
break
}
}
return br
}
func main() {
ch := make(chan int)
go Walk(tree.New(1), ch)
for i := range ch {
fmt.Println(i)
}
fmt.Println(Same(tree.New(1), tree.New(2)))
fmt.Println(Same(tree.New(1), tree.New(1)))
fmt.Println(Same(tree.New(2), tree.New(1)))
}
所以输出如下:
1
2
3
4
5
6
7
8
9
10
false
true
false
答案 17 :(得分:0)
一个明确的答案:
package main
import "golang.org/x/tour/tree"
import "fmt"
// Walk walks the tree t sending all values
// from the tree to the channel ch.
func Walk(t *tree.Tree, ch chan int) {
if t == nil {
return
}
Walk(t.Left, ch)
ch <- t.Value
Walk(t.Right, ch)
}
func WalkATree(t *tree.Tree, ch chan int) {
Walk(t, ch)
close(ch)
}
// Same determines whether the trees
// t1 and t2 contain the same values.
func Same(t1, t2 *tree.Tree) bool {
ch1 := make(chan int)
ch2 := make(chan int)
go WalkATree(t1, ch1)
go WalkATree(t2, ch2)
var v1, v2 int
var ok1, ok2 bool
for {
v1, ok1 = <- ch1
v2, ok2 = <- ch2
if !ok1 && !ok2 {
return true
}
if !ok1 && ok2 || ok1 && !ok2 {
return false
}
if v1 != v2 {
return false
}
}
}
func main() {
fmt.Println(Same(tree.New(1), tree.New(1)))
}
答案 18 :(得分:0)
对于有兴趣的人,如果你想知道如何在不创建单独的递归函数的情况下解决这个问题,这里是一个使用堆栈的答案:
func Walk(t *tree.Tree, ch chan int) {
defer close(ch)
visitStack := []*tree.Tree{t}
visited := make(map[*tree.Tree]bool, 1)
for len(visitStack) > 0 {
var n *tree.Tree
n, visitStack = visitStack[len(visitStack)-1], visitStack[:len(visitStack)-1]
if visited[n] {
ch <- n.Value
continue
}
if n.Right != nil {
visitStack = append(visitStack, n.Right)
}
visitStack = append(visitStack, n)
if n.Left != nil {
visitStack = append(visitStack, n.Left)
}
visited[n] = true
}
}
答案 19 :(得分:0)
这里的解决方案并不依赖于不同的树长度,也不依赖于遍历顺序:
package main
import (
"fmt"
"golang.org/x/tour/tree"
)
// Walk walks the tree t sending all values
// from the tree to the channel ch.
func Walk(t *tree.Tree, ch chan int) {
var walk func(*tree.Tree)
walk = func(tr *tree.Tree) {
if tr == nil {
return
}
walk(tr.Left)
ch <- tr.Value
walk(tr.Right)
}
walk(t)
close(ch)
}
func merge(ch chan int, m map[int]int) {
for i := range ch {
count, ok := m[i]
if ok {
m[i] = count + 1
} else {
m[i] = 1
}
}
}
// Same determines whether the trees
// t1 and t2 contain the same values.
func Same(t1, t2 *tree.Tree) bool {
ch1 := make(chan int, 100)
ch2 := make(chan int, 100)
m := make(map[int]int)
go Walk(t1, ch1)
go Walk(t2, ch2)
merge(ch1, m)
merge(ch2, m)
for _, count := range m {
if count != 2 {
return false
}
}
return true
}
答案 20 :(得分:0)
因为问题只是说树只有10个节点,所以在阅读其他答案后,我的回答是:
func Walk(t *tree.Tree, ch chan int) {
defer close(ch)
var walker func(t *tree.Tree)
walker = func(t *tree.Tree) {
if t == nil {
return
}
walker(t.Left)
ch <- t.Value
walker(t.Right)
}
walker(t)
}
func Same(t1, t2 *tree.Tree) bool {
ch1, ch2 := make(chan int), make(chan int)
go Walk(t1, ch1)
go Walk(t2, ch2)
for range make([]struct{}, 10) {
if <-ch1 != <-ch2 {
return false
}
}
return true
}
答案 21 :(得分:0)
这就是我使用Inorder Traversal
的方式package main
import (
"fmt"
"golang.org/x/tour/tree"
)
// Walk walks the tree t sending all values
// from the tree to the channel ch.
func Walk(t *tree.Tree, ch chan int) {
if t != nil {
Walk(t.Left, ch)
ch <- t.Value
Walk(t.Right, ch)
}
}
// Same determines whether the trees
// t1 and t2 contain the same values.
func Same(t1, t2 *tree.Tree) bool {
c1, c2 := make(chan int), make(chan int)
go Walk(t1, c1)
go Walk(t2, c2)
if <-c1 == <-c2 {
return true
} else {
return false
}
}
func main() {
t1 := tree.New(1)
t2 := tree.New(8)
fmt.Println("the two trees are same?", Same(t1, t2))
}
答案 22 :(得分:0)
我写了两个版本,总是把两个频道都读到最后:
package main
import (
"fmt"
"golang.org/x/tour/tree"
)
func Walk(t *tree.Tree, ch chan int) {
var walker func(t *tree.Tree)
walker = func(t *tree.Tree) {
if t == nil {
return
}
walker(t.Left)
ch <- t.Value
walker(t.Right)
}
walker(t)
close(ch)
}
func Same(t1, t2 *tree.Tree, sameChan func(ch1, ch2 chan int) bool) bool {
ch1, ch2 := make(chan int), make(chan int)
go Walk(t1, ch1)
go Walk(t2, ch2)
return sameChan(ch1, ch2)
}
func sameChan1(ch1, ch2 chan int) bool {
areSame := true
for {
v1, ok1 := <-ch1
v2, ok2 := <-ch2
if !ok1 && !ok2 {
return areSame
}
if !ok1 || !ok2 || v1 != v2 {
areSame = false
}
}
}
func sameChan2(ch1, ch2 chan int) bool {
areSame := true
for v1 := range ch1 {
v2, ok2 := <-ch2
if !ok2 || v1 != v2 {
areSame = false
}
}
for _ = range ch2 {
areSame = false
}
return areSame
}
func main() {
fmt.Println(Same(tree.New(1), tree.New(1), sameChan1))
fmt.Println(Same(tree.New(2), tree.New(1), sameChan1))
fmt.Println(Same(tree.New(1), tree.New(2), sameChan1))
fmt.Println(Same(tree.New(1), tree.New(1), sameChan2))
fmt.Println(Same(tree.New(2), tree.New(1), sameChan2))
fmt.Println(Same(tree.New(1), tree.New(2), sameChan2))
}
答案 23 :(得分:0)
我的版本
package main
import (
"fmt"
"golang.org/x/tour/tree"
)
// Walk walks the tree t sending all values
// from the tree to the channel ch.
func WalkRec(t *tree.Tree, ch chan int) {
if t == nil {
return
}
WalkRec(t.Left, ch)
ch <- t.Value
WalkRec(t.Right, ch)
}
func Walk(t *tree.Tree, ch chan int) {
WalkRec(t, ch)
close(ch)
}
// Same determines whether the trees
// t1 and t2 contain the same values.
func Same(t1, t2 *tree.Tree) bool {
ch1 := make(chan int)
ch2 := make(chan int)
go Walk(t1, ch1)
go Walk(t2, ch2)
for {
x, okx := <-ch1
y, oky := <-ch2
switch {
case okx != oky:
return false
case x != y:
return false
case okx == oky && okx == false:
return true
}
}
}
func main() {
ch := make(chan int)
go Walk(tree.New(1), ch)
fmt.Println(Same(tree.New(1), tree.New(1)))
fmt.Println(Same(tree.New(2), tree.New(1)))
fmt.Println(Same(tree.New(1), tree.New(2)))
}
答案 24 :(得分:0)
你应该避免让打开的频道无人看管,或者线程可以永远等待,永远不会结束。
package main
import "code.google.com/p/go-tour/tree"
import "fmt"
func WalkRecurse(t *tree.Tree, ch chan int) {
if t == nil {
return
}
WalkRecurse(t.Left, ch)
ch <- t.Value
WalkRecurse(t.Right, ch)
}
// Walk walks the tree t sending all values
// from the tree to the channel ch.
func Walk(t *tree.Tree, ch chan int) {
WalkRecurse(t, ch)
close(ch)
}
// Same determines whether the trees
// t1 and t2 contain the same values.
func Same(t1, t2 *tree.Tree) bool {
var ch1, ch2 chan int = make(chan int), make(chan int)
go Walk(t1, ch1)
go Walk(t2, ch2)
ret := true
for {
v1, ok1 := <- ch1
v2, ok2 := <- ch2
if ok1 != ok2 {
ret = false
}
if ok1 && (v1 != v2) {
ret = false
}
if !ok1 && !ok2 {
break
}
}
return ret
}
func main() {
ch := make(chan int)
go Walk(tree.New(1), ch)
for v := range ch {
fmt.Print(v, " ")
}
fmt.Println()
fmt.Println(Same(tree.New(1), tree.New(1)))
fmt.Println(Same(tree.New(1), tree.New(2)))
}