为了账号安全,请及时绑定邮箱和手机立即绑定

去比较两个结构是否大于

去比较两个结构是否大于

Go
三国纷争 2022-04-20 20:41:47
我正在尝试比较两张扑克牌结构,看看哪张扑克牌比另一张更好。我在网上找到的所有用于比较围棋结构的东西都是为了比较是否相等,但在这种情况下,我想说黑桃 A 比梅花 7 更有价值。鉴于 Go 没有提供开箱即用的 Java 比较器接口,我想创建自己的函数来使用循环进行卡片比较,但我收到了错误消息:# cards/cardcard/Card.go:12:19: cannot use Ranks (type [13]string) as type []string in argument to indexOfSlicecard/Card.go:14:26: cannot use Ranks (type [13]string) as type []string in argument to indexOfSlicecard/Card.go:15:20: cannot use Suits (type [4]string) as type []string in argument to indexOfSlice这是我的卡包:package Cardvar Suits = [4]string {"hearts", "spades", "diamonds", "clubs"}var Ranks = [13]string {"2", "3", "4", "5", "6", "7", "8", "9", "10", "jack", "queen", "king", "ace"}type Card struct {        Value string        Suit string}// if the index in the slices is greater for a than for b, then a must be greater valuefunc CardIsGreater(a Card, b Card) bool {        if indexOfSlice(a.Value, Ranks) > indexOfSlice(b.Value, Ranks) {                return true;        } else if indexOfSlice(a.Value, Ranks) == indexOfSlice(b.Value, Ranks) {                if indexOfSlice(a.Suit, Suits) > indexOfSlice(b.Suit, Suits) {                        return true;                }        } else {                return false;        }        // lets ignore for a second that invalid ranks or suits will break this comparator        return false;}// finds the index of a suit or value in a slicefunc indexOfSlice(element string, slice []string) int {        for i, _ := range slice {                if slice[i] == element {                        return i;                }        }        return -1;}这是我的主要包:package mainimport (    "fmt"    "cards/card")在这种情况下,如何让 indexOfSlice 辅助函数接受一个字符串切片作为其参数之一?如果我从谷歌搜索的首页阅读随机教程,它看起来应该可以工作:https ://nanxiao.gitbooks.io/golang-101-hacks/content/posts/pass-slice-as-a-函数参数.html这个堆栈溢出答案解释说,Go 基本上是在强制执行类型安全,因为类型 []string 可以通过许多事情来满足:https ://stackoverflow.com/a/44606795/7255394 。如果是这种情况,那么我该如何解决这个问题?此外,这甚至是比较结构的正确方法吗?在将 Ace of Spaces 与 Ace of Hearts 进行比较的情况下,需要在 Suits And Ranks 切片 (!!) 上循环 4 次才能实际进行比较。
查看完整描述

2 回答

?
慕村9548890

TA贡献1884条经验 获得超4个赞

Suits并且Ranks不是切片。它们是数组。数组是固定大小的类型,与切片不同。您不能将数组发送到需要切片的函数。因此,将它们声明为没有大小,它们将成为切片:

var Suits=[]string{...}
var Ranks=[]string{...}

或者,如果要将它们保留为数组,则必须将切片传递给需要切片的函数:

indexOfSlice(str,Suits[:])

关于更好的方法的问题:您可以使用地图:

var Suits=map[string]int{"hearts":0, "spades":1, "diamonds":2, "clubs":3}

然后:

rankSuit=Suits[str]


查看完整回答
反对 回复 2022-04-20
?
元芳怎么了

TA贡献1798条经验 获得超7个赞

我会抽象你的类型,并为它们添加一些实用功能。


Card为,Suit和,创建自定义类型Rank允许您将比较和有效性函数附加到它们中的每一个。


如果您想要一个与ComparableJava 类似的界面,那么您也可以自己创建一个非常小的界面。为您的类型实现必要的功能以满足接口将很简单CompareTo,不过,我认为我提供的解决方案对类型的封装更好一些并且更容易测试。


我已经添加了在两张牌相等的情况下比较Suit的逻辑,但我不完全确定这背后的原因,因为通常打出相同等级的牌被认为是相等的牌。CardRank


祝你好运!


卡片/card.go


func New(s Suit, r Rank) (*Card, error) {

    if !s.Valid() {

        return nil, errors.New("invalid suit")

    }


    if !r.Valid() {

        return nil, errors.New("invalid rank")

    }


    return &Card{suit: s, rank: r}, nil

}


type Card struct {

    suit Suit

    rank Rank

}


func (c *Card) Cmp(c2 *Card) int {

    rankCmp := c.rank.Cmp(c2.rank)

    if rankCmp != 0 {

        return rankCmp

    }


    if c.suit < c2.suit {

        return -1

    }


    if c.suit > c2.suit {

        return 1

    }


    return 0

}

卡片/rank.go


type Rank string


var ranks = []Rank{"2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K", "A"}


func (r Rank) Cmp(r2 Rank) int {

    for _, rank := range ranks {

        if rank == r {

            return -1

        }


        if rank == r2 {

            return 1

        }

    }


    return 0

}


func (r Rank) Valid() bool {

    for _, rank := range ranks {

        if r == rank {

            return true

        }

    }


    return false

}

卡/suit.go


type Suit int


const (

    unknown  Suit = 1

    Hearts   Suit = 2

    Spades   Suit = 3

    Diamonds Suit = 4

    Clubs    Suit = 5

    sentinel Suit = 6

)


func (s Suit) Valid() bool {

    return s > unknown && s < sentinel

}

main.go


func main() {

    c1, err := cards.New(Hearts, "2")

    if err != nil {

        fmt.Println(err)

        return

    }


    c2, err := New(cards.Diamonds, "A")

    if err != nil {

        fmt.Println(err)

        return

    }


    c3, err := New(cards.Spades, "A")

    if err != nil {

        fmt.Println(err)

        return

    }


    fmt.Printf("c1 - c2: %d\n", c1.Cmp(c2))

    fmt.Printf("c2 - c3: %d\n", c2.Cmp(c3))

    fmt.Printf("c1 - c3: %d\n", c1.Cmp(c3))

}


查看完整回答
反对 回复 2022-04-20
  • 2 回答
  • 0 关注
  • 118 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信