For loop 递归函数中的GO-switch语句

For loop 递归函数中的GO-switch语句,for-loop,recursion,go,switch-statement,For Loop,Recursion,Go,Switch Statement,我有一个算法,我正试图实现,但目前我完全没有线索如何做到这一点,从技术角度来看 我们有5个浮点数: mySlice:=[float1、float2、float3、float4、float5] 和switch语句: aFloat := mySlice[index] switch aFloat { case 1: { //do something } case 2: { //do something } case 3:

我有一个算法,我正试图实现,但目前我完全没有线索如何做到这一点,从技术角度来看

我们有5个浮点数:

mySlice:=[float1、float2、float3、float4、float5]

和switch语句:

aFloat := mySlice[index]

switch aFloat {
  case 1:
    {
       //do something 
    }
  case 2:
    {
       //do something 
    }
  case 3:
    {
       //do something 
    }
  case 4:
    {
       //do something 
    }
  case 5:
    {
       //do something 
    }
  default:
    {
       //somehow go back to slice, take the next smallest and run
       //through the switch statement again
    }
}
我想做的事情如下:

  • 识别mySlice ex的最小元素:
    smallestFloat
  • 通过switch语句运行
    smallestFloat
  • 如果
    smallestFloat
    设置为默认情况,则从mySlice获取下一个最小的float
  • 再次执行步骤2
  • 我已经用for循环和步骤2完成了第一步,但是我被第3步和第4步卡住了。我现在还不知道如何将下一个最小的float从mySlice重新输入到switch语句中

    如果能对我的问题有所了解,我将不胜感激

    编辑:我想把我的解决方案放到上面介绍的算法中会很好

  • 创建另一个切片,它将是mySlice的排序版本
  • 创建一个map[int]值,其中索引将对应于值在未排序切片中的位置,但映射的项目将以与排序切片相同的顺序插入

  • 结果:一个值排序映射,其各自的索引对应于原始未排序切片的位置

    这里是一个使用最小优先级队列的实现。浮点数的原始输入切片没有更改。它可以在计算机上运行

    注意:在处理递归函数时,您需要对堆栈溢出感到厌倦。 Go只在有限的情况下进行尾部递归优化。关于这方面的更多信息, 参考

    这个特定的示例甚至比摊销O(logn)时间做得更好,因为它不必中途调整优先级队列的大小。这就保证了O(logn)

    主程序包
    进口(
    “fmt”
    )
    func main(){
    切片:=[]浮点64{2,1,13,4,22,0,5,7,3}
    fmt.Printf(“之前的订单:%v\n”,切片)
    队列:=NewMinPQ(切片)
    for!queue.Empty(){
    doSmallest(队列)
    }
    fmt.Printf(“在%v\n之后的订单”,切片)
    }
    func doSmallest(队列*MinPQ){
    if queue.Empty(){
    返回
    }
    v:=queue.Dequeue()
    开关v{
    案例1:
    fmt.Println(“Do”,v)
    案例2:
    fmt.Println(“Do”,v)
    案例3:
    fmt.Println(“Do”,v)
    案例4:
    fmt.Println(“Do”,v)
    案例5:
    fmt.Println(“Do”,v)
    违约:
    //没有命中,使用下一个值再次执行。
    doSmallest(队列)
    }
    }
    //MinPQ表示最小优先级队列。
    //它被实现为一个二进制堆。
    //
    //可以将已排队的值退出队列,但将执行此操作
    //按照最小项目首先返回的顺序。
    类型MinPQ结构{
    值[]float64//原始输入列表--顺序从未更改。
    索引[]int//将索引列表放入值切片中。
    index int//索引列表的当前大小。
    }
    //NewMinPQ为给定的输入集创建一个新的MinPQ堆。
    func NewMinPQ(集合[]浮点64)*MinPQ{
    m:=新(MinPQ)
    m、 值=设置
    m、 索引=生成([]整数,1,len(集))
    //初始化优先级队列。
    //使用集合的索引作为值,而不是浮点数
    //他们自己。因为这些可能不会被重新订购。
    对于i:=范围集{
    m、 索引=附加(m.索引,i)
    m、 索引++
    m、 游泳(m.index)
    }
    返回m
    }
    //如果堆为空,则Empty返回true。
    func(m*MinPQ)Empty()bool{return m.index==0}
    //“出列”将删除最小的项并将其返回。
    //如果堆为空,则返回nil。
    func(m*MinPQ)出列()浮点64{
    如果m.Empty(){
    返回0
    }
    最小值:=m.指数[1]
    m、 指数[1],m指数[m指数]=m指数[m指数],m指数[1]
    m、 索引--
    m、 水槽(1)
    m、 指数=m指数[:m指数+1]
    返回m.值[min]
    }
    //如果元素x大于元素y,则返回true。
    func(m*MinPQ)大于(x,y int)布尔{
    返回m.values[m.index[x]>m.values[m.index[y]]
    }
    //sink将树向下排列。
    func(m*MinPQ)接收器(k int){
    适用于2*k 1及以上(k/2,k){
    m、 指数[k],m.指数[k/2]=m.指数[k/2],m.指数[k]
    k/=2
    }
    }
    
    我已经应用了这种方法,但它不是我所需要的。我需要切片的每个元素保持在它的原始位置。正如在我的算法中提到的,我需要
    识别
    最小值并检索值,而不是修改元素的索引。在这种情况下,我将查看我在回答中提到的优先级队列。它可以使用列表索引作为值来构造。这样,您的切片可以保持原样,但您仍然可以在摊销O(对数n)时间内找到最小的浮动。而每次在切片上循环就是O(N)时间。映射不是有序结构。而且也不能保证在同一张地图的不同迭代之间键的顺序是相同的。谢谢你的提示。我会留意的
    
    package main
    
    import (
        "fmt"
    )
    
    func main() {
        slice := []float64{2, 1, 13, 4, 22, 0, 5, 7, 3}
        fmt.Printf("Order before: %v\n", slice)
    
        queue := NewMinPQ(slice)
    
        for !queue.Empty() {
            doSmallest(queue)
        }
    
        fmt.Printf("Order after: %v\n", slice)
    }
    
    func doSmallest(queue *MinPQ) {
        if queue.Empty() {
            return
        }
    
        v := queue.Dequeue()
    
        switch v {
        case 1:
            fmt.Println("Do", v)
        case 2:
            fmt.Println("Do", v)
        case 3:
            fmt.Println("Do", v)
        case 4:
            fmt.Println("Do", v)
        case 5:
            fmt.Println("Do", v)
        default:
            // No hit, do it all again with the next value.
            doSmallest(queue)
        }
    }
    
    // MinPQ represents a Minimum priority queue.
    // It is implemented as a binary heap.
    //
    // Values which are enqueued can be dequeued, but will be done
    // in the order where the smallest item is returned first.
    type MinPQ struct {
        values  []float64 // Original input list -- Order is never changed.
        indices []int     // List of indices into values slice.
        index   int       // Current size of indices list.
    }
    
    // NewMinPQ creates a new MinPQ heap for the given input set.
    func NewMinPQ(set []float64) *MinPQ {
        m := new(MinPQ)
        m.values = set
        m.indices = make([]int, 1, len(set))
    
        // Initialize the priority queue.
        // Use the set's indices as values, instead of the floats
        // themselves. As these may not be re-ordered.
        for i := range set {
            m.indices = append(m.indices, i)
            m.index++
            m.swim(m.index)
        }
    
        return m
    }
    
    // Empty returns true if the heap is empty.
    func (m *MinPQ) Empty() bool { return m.index == 0 }
    
    // Dequeue removes the smallest item and returns it.
    // Returns nil if the heap is empty.
    func (m *MinPQ) Dequeue() float64 {
        if m.Empty() {
            return 0
        }
    
        min := m.indices[1]
    
        m.indices[1], m.indices[m.index] = m.indices[m.index], m.indices[1]
        m.index--
        m.sink(1)
        m.indices = m.indices[:m.index+1]
        return m.values[min]
    }
    
    // greater returns true if element x is greater than element y.
    func (m *MinPQ) greater(x, y int) bool {
        return m.values[m.indices[x]] > m.values[m.indices[y]]
    }
    
    // sink reorders the tree downwards.
    func (m *MinPQ) sink(k int) {
        for 2*k <= m.index {
            j := 2 * k
    
            if j < m.index && m.greater(j, j+1) {
                j++
            }
    
            if m.greater(j, k) {
                break
            }
    
            m.indices[k], m.indices[j] = m.indices[j], m.indices[k]
            k = j
        }
    }
    
    // swim reorders the tree upwards.
    func (m *MinPQ) swim(k int) {
        for k > 1 && m.greater(k/2, k) {
            m.indices[k], m.indices[k/2] = m.indices[k/2], m.indices[k]
            k /= 2
        }
    }