Skip to content

Commit

Permalink
简化算法
Browse files Browse the repository at this point in the history
  • Loading branch information
eaglexiang committed Dec 13, 2024
1 parent de80293 commit 1687691
Showing 1 changed file with 17 additions and 82 deletions.
99 changes: 17 additions & 82 deletions format.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,98 +2,33 @@ package costwhere

import (
"fmt"
"sort"
"strings"
"time"

"github.com/samber/lo"
)

func formatCosts(c *Costs) (costs []string) {
// 重建栈结构
s := newCostStack()
for _, cost := range c.costs {
path := strings.Split(cost.Path, ";")
s.add(path, cost.Cost)
}

costs = s.root.format("")

return
}

type costStack struct {
root *stackFrame
}

func newCostStack() *costStack {
return &costStack{}
}

func (c *costStack) add(path []string, cost time.Duration) {
if len(path) == 0 {
return
}

root := path[0]

if c.root == nil {
c.root = newStackFrame(root)
return
}

c.root.add(path[1:], cost)
}

type stackFrame struct {
path string
cost time.Duration
children []*stackFrame
}

func newStackFrame(path string) *stackFrame {
return &stackFrame{
path: path,
children: make([]*stackFrame, 0),
}
}

func (s *stackFrame) add(childPath []string, cost time.Duration) {
if len(childPath) == 0 {
s.cost += cost
return
}

childRoot := childPath[0]

child, ok := lo.Find(s.children, func(item *stackFrame) bool {
return item.path == childRoot
arr := lo.Values(c.costs)
sort.Slice(arr, func(i, j int) bool {
if len(arr[i].Path) < len(arr[j].Path) {
return true
}
return arr[i].Path < arr[j].Path
})
if ok {
child.add(childPath[1:], cost)
return
}

newChild := newStackFrame(childRoot)
s.children = append(s.children, newChild)
newChild.add(childPath[1:], cost)

if len(childPath) == 1 {
s.cost -= cost
for i := 0; i < len(arr); i++ {
for j := i + 1; j < len(arr); j++ {
if strings.HasPrefix(arr[j].Path, arr[i].Path) {
arr[i].Cost -= arr[j].Cost
break
}
}
}
}

func (s *stackFrame) format(head string) (costs []string) {
path := s.path
if head != "" {
path = head + ";" + path
}

cost := fmt.Sprintf("%s %d", head, s.cost.Milliseconds())
costs = append(costs, cost)

for _, child := range s.children {
childCosts := child.format(path)
costs = append(costs, childCosts...)
for _, cost := range arr {
text := fmt.Sprintf("%s %d", cost.Path, cost.Cost.Milliseconds())
costs = append(costs, text)
}

return
Expand Down

0 comments on commit 1687691

Please sign in to comment.