gpt4 book ai didi

sorting - golang sort.Sort随机输出并且是错误的

转载 作者:IT王子 更新时间:2023-10-29 02:25:37 28 4
gpt4 key购买 nike

我有一个应用于结构的自定义排序函数。完整代码是 here on play.golang.org .

type Stmt struct {
Name string
After []string
}

func sortStmts(stmts []Stmt) []Stmt {
sort.Sort(ByAfter(stmts))
return stmts
}

type ByAfter []Stmt

func (a ByAfter) Len() int { return len(a) }
func (a ByAfter) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
func (a ByAfter) Less(i, j int) bool {
isLess := true

//fmt.Printf("%s.%+v is being compared with %s.%+v\n", a[i].Name, a[i].After, a[j].Name, a[j].After)

for _, v := range a[i].After {
if a[j].Name == v {
isLess = false
break
}
}

if isLess {
//fmt.Printf("%s.%+v is Before %s.%+v\n", a[i].Name, a[i].After, a[j].Name, a[j].After)
} else {
//fmt.Printf("%s.%+v is After %s.%+v\n", a[i].Name, a[i].After, a[j].Name, a[j].After)
}

return isLess
}

我的目的是自动创建一组正确排序的 sql create 语句,以便从属表排在第一位。

所以如果 Stmt{Name: "user_role", After: []string{"user", "role"} } 存在,那么在有序列表中 user_role 应该在 userrole 之后。

在我们开始添加更多值之前,这似乎工作得很好。才进去查了一下,才发现可能是第一次碰巧走运,但确实没有任何一致性。

我在排序函数中做错了什么结果是随机的。我特别想知道为什么“role”项没有出现在“user_role”项之前,即使我已将它指定为 user_role 出现在 role 之后。

最佳答案

您的“Less”函数不可传递。也就是说,如果 A < B 且 B < C,则它也必须满足 A < C。

您无法使用常规排序函数指定部分顺序并获得排序后的输出。相反,您需要实现 topological sort .

这是对您的数据的简单实现(除了我删除了重复的“密码”条目)。

package main

import "fmt"

type Stmt struct {
Name string
After []string
}

func topSort(ss []Stmt) []string {
after := map[string][]string{} // things that must come after
counts := map[string]int{} // number unsatified preconditions
zc := map[string]struct{}{} // things with zero count
for _, s := range ss {
for _, a := range s.After {
after[a] = append(after[a], s.Name)
}
counts[s.Name] = len(s.After)
if len(s.After) == 0 {
zc[s.Name] = struct{}{}
}
}

r := []string{}
for len(zc) > 0 {
for n := range zc {
r = append(r, n)
for _, a := range after[n] {
counts[a]--
if counts[a] == 0 {
zc[a] = struct{}{}
}
}
delete(zc, n)
}
}
return r
}

func main() {
stmts := []Stmt{
{Name: "app", After: []string{"app_user"}},
{Name: "billingplan", After: []string{}},
{Name: "campaign", After: []string{"app_user"}},
{Name: "campaign_app", After: []string{"campaign", "app"}},
{Name: "campaign_ip", After: []string{"campaign", "ip"}},
{Name: "campaign_operator", After: []string{"campaign", "operator"}},
{Name: "campaign_sponsor", After: []string{"campaign", "sponsor"}},
{Name: "campaign_subscriberfilter", After: []string{"campaign", "subscriber_filters"}},
{Name: "campaign_url", After: []string{"campaign", "url"}},
{Name: "contentpartner", After: []string{"app_user"}},
{Name: "filter_criteria", After: []string{"campaign", "subscriber_filters"}},
{Name: "ip", After: []string{"app_user"}},
{Name: "mobile_registered", After: []string{"campaign", "app"}},
{Name: "operator", After: []string{}},
{Name: "passwords", After: []string{"app_user"}},
{Name: "publish_package", After: []string{}},
{Name: "role", After: []string{}},
{Name: "sponsor", After: []string{"app_user"}},
{Name: "subscriber_dbs", After: []string{}},
{Name: "subscriber_filters", After: []string{"subscriber_dbs"}},
{Name: "timezone", After: []string{}},
{Name: "url", After: []string{"app_user"}},
{Name: "app_user", After: []string{}},
{Name: "user_role", After: []string{"app_user", "role"}},
}
r := topSort(stmts)
for _, s := range r {
fmt.Println(s)
}
}

关于sorting - golang sort.Sort随机输出并且是错误的,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29025460/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com