For loop 递归函数中的GO-switch语句
我有一个算法,我正试图实现,但目前我完全没有线索如何做到这一点,从技术角度来看 我们有5个浮点数: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:
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
}
}
我想做的事情如下:
smallestFloat
smallestFloat
smallestFloat
设置为默认情况,则从mySlice获取下一个最小的float结果:一个值排序映射,其各自的索引对应于原始未排序切片的位置这里是一个使用最小优先级队列的实现。浮点数的原始输入切片没有更改。它可以在计算机上运行 注意:在处理递归函数时,您需要对堆栈溢出感到厌倦。 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
}
}