Golang 比较两个字符串包含相同的词
Golang Compare Two Strings contains same words
我正在尝试检查一个数组是否包含另一个数组的特定单词,如下所示:
示例:“红心 3”和“红心 5”匹配,因为它们都是
心中应该 return true.
示例:“红心 7”和“红心 7”
clubs" 匹配,因为它们都具有值 7 并且应该 return
是的。
示例:“Jack of spades”仅匹配另一个“Jack of spades”
并且应该 return 为真。
我将如何在 golang 中执行此操作。我尝试了一系列步骤,但我回到了原点,到目前为止我所拥有的是:
func compare(firstString, secondString string) bool {
return false
}
compare("3 of hearts", "5 of hearts")
## This should return true
func compare(f, s string) bool {
arr1, arr2 := strings.Split(f, " "), strings.Split(s, " ")
for _, v1 := range arr1 {
for _, v2 := range arr2 {
if v1 == v2 {
return true
}
}
}
return false
}
我是 golang 的新手,但无需循环两次即可获得此信息的最佳方法是:
func compare(firstString, secondString string) bool {
f, s := strings.Split(f, " "), strings.Split(secondString, " ")
if f[0] == s[0] || f[2] == f[2] {
return true
}
return false
}
compare("3 of hearts", "5 of hearts")
## This should return true
compare("7 of hearts", "7 of clubs")
## This should return true
compare("Jack of spades", "Jack of spades")
## This should return true
compare("5 of hearts", "7 of clubs")
## This should return false
我不知道你到底想做什么。 (我的意思是你好世界很无聊)
不过从问题来看,至少我知道可能和扑克有关。
所以你应该先设计扑克牌相关的结构
然后你需要一个方法来从字符串中获取对象
最后,设计一个卡片的Equal功能,至此大功告成。
type Card struct{}
func GetCardFromStr(str string) (*Card, error)
func (card *Card) Equal(card2 *Card, criteria criteria) bool
示例代码
package main
import (
"fmt"
"strconv"
"strings"
)
type Suit uint8
const (
Spades Suit = iota + 1
Hearts
Diamonds
Clubs
)
var suitMap map[string]Suit
func init() {
suitMap = map[string]Suit{"spades": Spades, "hearts": Hearts, "diamonds": Diamonds, "clubs": Clubs}
}
func StrToSuit(str string) Suit {
if suit, exists := suitMap[strings.ToLower(str)]; exists {
return suit
}
return 0
}
type Card struct {
point int // 1-13 // ace, 2 to 10, Jack J, Queen Q, King K
suit Suit // spades ♠️, hearts ♥️, diamonds ♦️, clubs ♣️ // emoji suit: https://emojipedia.org/search/?q=Suit
}
func NewCard(point int, suit Suit) (*Card, error) {
if point < 0 || point > 13 {
return nil, fmt.Errorf("illegal point: '%d', it should in the range: 1~13", point)
}
return &Card{point, suit}, nil // you can consider checking the suit.
}
func (card *Card) String() string {
return fmt.Sprintf("%s%d", map[Suit]string{
Spades: "♠️",
Hearts: "♥️",
Diamonds: "♦️",
Clubs: "♣️",
}[card.suit], card.point)
}
type criteria uint8
const (
Loose criteria = 1 << iota // one of them match
// ... // others
Strict // all match
)
func (card *Card) Equal(card2 *Card, criteria criteria) bool {
if criteria == Strict {
if card.point == card2.point && (card.suit == card2.suit && card.suit != 0) {
return true
}
return false
}
if card.point == card2.point || (card.suit == card2.suit && card.suit != 0) {
return true
}
return false
}
func GetCardFromStr(str string) (*Card, error) {
slice := strings.Split(str, " ")
if slice == nil {
return nil, fmt.Errorf("can't convert string to the card")
}
alphaMap := map[string]int{
"ace": 1,
"jack": 11, "queen": 12, "king": 13,
}
cardPoint := 0
var cardSuit Suit
for _, elem := range slice {
elem = strings.ToLower(elem)
if cardPoint == 0 {
checkPoint := true
if point, exists := alphaMap[elem]; exists {
cardPoint = point
checkPoint = false
}
if checkPoint {
if point, err := strconv.Atoi(elem); err == nil {
cardPoint = point
}
}
}
if cardSuit == 0 {
if suit := StrToSuit(elem); suit != 0 {
cardSuit = suit
}
}
}
if cardPoint == 0 {
return nil, fmt.Errorf("can't convert string to the card (unknown point)")
}
if cardSuit == 0 {
return nil, fmt.Errorf("can't convert string to the card (unknown suit)")
}
return NewCard(cardPoint, cardSuit)
}
func main() {
for caseNumber, data := range []struct {
s1 string
s2 string
criteria
}{
{"-5 hearts", "5 hearts", Loose}, // error illegal point: '-5', it should in the range: 1~13
{"0", "", Loose}, // error can't convert string to the card (unknown point)
{"3 of hearts", "3 of hearts", Loose}, // true
{"3 of hearts", "5 of hearts", Loose}, // true
{"7 of hearts", "7 of clubs", Loose}, // true
{"Jack of spades", "Jack of spades", Strict}, // true
{"Jack of spades", "Jack spades", Strict}, // true
{"Jack of spades", "Jack hearts", Strict}, // false
{"Jack of spades", "Jack", Strict}, // error can't convert string to the card (unknown suit)
{"Jack of spades", "spades", Strict}, // error can't convert string to the card (unknown point)
{"player Foo: 1 of clubs ", "player bar: I get an Ace of spades !!", Loose}, // true
} {
card1, err := GetCardFromStr(data.s1)
if err != nil {
fmt.Printf("case:%d errMsg:%s\n", caseNumber, err)
continue
}
card2, err := GetCardFromStr(data.s2)
if err != nil {
fmt.Printf("case:%d errMsg:%s\n", caseNumber, err)
continue
}
fmt.Printf("criteria %d, %s equal %s: %v\n",
data.criteria, card1, card2, card1.Equal(card2, data.criteria),
)
}
}
使用上面的代码,相信大家不会对比较感到困惑,也能避免downvote
然后你可以把问题转向如何优化函数GetCardFromStr
只使用loop one层、regexp 、检测更多边...
严格来说,我不是在回答问题,只是为你的问题方向提供参考。希望大家不要介意,祝你好运。
我正在尝试检查一个数组是否包含另一个数组的特定单词,如下所示:
示例:“红心 3”和“红心 5”匹配,因为它们都是 心中应该 return true.
示例:“红心 7”和“红心 7” clubs" 匹配,因为它们都具有值 7 并且应该 return 是的。
示例:“Jack of spades”仅匹配另一个“Jack of spades” 并且应该 return 为真。
我将如何在 golang 中执行此操作。我尝试了一系列步骤,但我回到了原点,到目前为止我所拥有的是:
func compare(firstString, secondString string) bool {
return false
}
compare("3 of hearts", "5 of hearts")
## This should return true
func compare(f, s string) bool {
arr1, arr2 := strings.Split(f, " "), strings.Split(s, " ")
for _, v1 := range arr1 {
for _, v2 := range arr2 {
if v1 == v2 {
return true
}
}
}
return false
}
我是 golang 的新手,但无需循环两次即可获得此信息的最佳方法是:
func compare(firstString, secondString string) bool {
f, s := strings.Split(f, " "), strings.Split(secondString, " ")
if f[0] == s[0] || f[2] == f[2] {
return true
}
return false
}
compare("3 of hearts", "5 of hearts")
## This should return true
compare("7 of hearts", "7 of clubs")
## This should return true
compare("Jack of spades", "Jack of spades")
## This should return true
compare("5 of hearts", "7 of clubs")
## This should return false
我不知道你到底想做什么。 (我的意思是你好世界很无聊) 不过从问题来看,至少我知道可能和扑克有关。
所以你应该先设计扑克牌相关的结构
然后你需要一个方法来从字符串中获取对象
最后,设计一个卡片的Equal功能,至此大功告成。
type Card struct{}
func GetCardFromStr(str string) (*Card, error)
func (card *Card) Equal(card2 *Card, criteria criteria) bool
示例代码
package main
import (
"fmt"
"strconv"
"strings"
)
type Suit uint8
const (
Spades Suit = iota + 1
Hearts
Diamonds
Clubs
)
var suitMap map[string]Suit
func init() {
suitMap = map[string]Suit{"spades": Spades, "hearts": Hearts, "diamonds": Diamonds, "clubs": Clubs}
}
func StrToSuit(str string) Suit {
if suit, exists := suitMap[strings.ToLower(str)]; exists {
return suit
}
return 0
}
type Card struct {
point int // 1-13 // ace, 2 to 10, Jack J, Queen Q, King K
suit Suit // spades ♠️, hearts ♥️, diamonds ♦️, clubs ♣️ // emoji suit: https://emojipedia.org/search/?q=Suit
}
func NewCard(point int, suit Suit) (*Card, error) {
if point < 0 || point > 13 {
return nil, fmt.Errorf("illegal point: '%d', it should in the range: 1~13", point)
}
return &Card{point, suit}, nil // you can consider checking the suit.
}
func (card *Card) String() string {
return fmt.Sprintf("%s%d", map[Suit]string{
Spades: "♠️",
Hearts: "♥️",
Diamonds: "♦️",
Clubs: "♣️",
}[card.suit], card.point)
}
type criteria uint8
const (
Loose criteria = 1 << iota // one of them match
// ... // others
Strict // all match
)
func (card *Card) Equal(card2 *Card, criteria criteria) bool {
if criteria == Strict {
if card.point == card2.point && (card.suit == card2.suit && card.suit != 0) {
return true
}
return false
}
if card.point == card2.point || (card.suit == card2.suit && card.suit != 0) {
return true
}
return false
}
func GetCardFromStr(str string) (*Card, error) {
slice := strings.Split(str, " ")
if slice == nil {
return nil, fmt.Errorf("can't convert string to the card")
}
alphaMap := map[string]int{
"ace": 1,
"jack": 11, "queen": 12, "king": 13,
}
cardPoint := 0
var cardSuit Suit
for _, elem := range slice {
elem = strings.ToLower(elem)
if cardPoint == 0 {
checkPoint := true
if point, exists := alphaMap[elem]; exists {
cardPoint = point
checkPoint = false
}
if checkPoint {
if point, err := strconv.Atoi(elem); err == nil {
cardPoint = point
}
}
}
if cardSuit == 0 {
if suit := StrToSuit(elem); suit != 0 {
cardSuit = suit
}
}
}
if cardPoint == 0 {
return nil, fmt.Errorf("can't convert string to the card (unknown point)")
}
if cardSuit == 0 {
return nil, fmt.Errorf("can't convert string to the card (unknown suit)")
}
return NewCard(cardPoint, cardSuit)
}
func main() {
for caseNumber, data := range []struct {
s1 string
s2 string
criteria
}{
{"-5 hearts", "5 hearts", Loose}, // error illegal point: '-5', it should in the range: 1~13
{"0", "", Loose}, // error can't convert string to the card (unknown point)
{"3 of hearts", "3 of hearts", Loose}, // true
{"3 of hearts", "5 of hearts", Loose}, // true
{"7 of hearts", "7 of clubs", Loose}, // true
{"Jack of spades", "Jack of spades", Strict}, // true
{"Jack of spades", "Jack spades", Strict}, // true
{"Jack of spades", "Jack hearts", Strict}, // false
{"Jack of spades", "Jack", Strict}, // error can't convert string to the card (unknown suit)
{"Jack of spades", "spades", Strict}, // error can't convert string to the card (unknown point)
{"player Foo: 1 of clubs ", "player bar: I get an Ace of spades !!", Loose}, // true
} {
card1, err := GetCardFromStr(data.s1)
if err != nil {
fmt.Printf("case:%d errMsg:%s\n", caseNumber, err)
continue
}
card2, err := GetCardFromStr(data.s2)
if err != nil {
fmt.Printf("case:%d errMsg:%s\n", caseNumber, err)
continue
}
fmt.Printf("criteria %d, %s equal %s: %v\n",
data.criteria, card1, card2, card1.Equal(card2, data.criteria),
)
}
}
使用上面的代码,相信大家不会对比较感到困惑,也能避免downvote
然后你可以把问题转向如何优化函数GetCardFromStr
只使用loop one层、regexp 、检测更多边...
严格来说,我不是在回答问题,只是为你的问题方向提供参考。希望大家不要介意,祝你好运。