Golang比较两个字符串是否包含相同的单词。

huangapple go评论116阅读模式
英文:

Golang Compare Two Strings contains same words

问题

我正在尝试检查一个数组是否包含另一个数组中的特定单词,像这样:

  • 例子:"3 of hearts" 和 "5 of hearts" 匹配,因为它们都是红心,应该返回 true。

  • 例子:"7 of hearts" 和 "7 of clubs" 匹配,因为它们都有值为 7,应该返回 true。

  • 例子:"Jack of spades" 只与另一个 "Jack of spades" 匹配,应该返回 true。

在 Golang 中,你可以这样实现:

import (
	"strings"
)

func compare(firstString, secondString string) bool {
	firstArray := strings.Split(firstString, " ")
	secondArray := strings.Split(secondString, " ")

	// 检查花色是否匹配
	if firstArray[len(firstArray)-1] != secondArray[len(secondArray)-1] {
		return false
	}

	// 检查值是否匹配
	if firstArray[0] != secondArray[0] {
		return false
	}

	return true
}

compare("3 of hearts", "5 of hearts")
// 这应该返回 true

这段代码将字符串按空格分割成数组,并逐个比较数组元素。首先检查花色是否匹配,然后检查值是否匹配。如果两个条件都满足,则返回 true,否则返回 false。

英文:

I am trying check if an array contains a particular word with another array like so:

  • Example: "3 of hearts" and "5 of hearts" match because they are both
    hearts and should return true.

  • Example: "7 of hearts" and "7 of
    clubs" match because they both have the value 7 and should return
    true.

  • Example: "Jack of spades" only matches another "Jack of spades"
    and should return true.

How would I go about doing this in golang. I tried a bunch of steps and I'm back in square one what I have so far is this:

func compare(firstString, secondString string) bool {
	return false
}

compare("3 of hearts", "5 of hearts")
## This should return true

答案1

得分: 1

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
}

<kbd>go playground</kbd>

英文:
func compare(f, s string) bool {
	arr1, arr2 := strings.Split(f, &quot; &quot;), strings.Split(s, &quot; &quot;)
	for _, v1 := range arr1 {
		for _, v2 := range arr2 {
			if v1 == v2 {
				return true
			}
		}
	}
	return false
}

<kbd>go playground</kbd>

答案2

得分: 1

我对golang还比较新,但是不需要两次循环来实现这个的最佳方法是:

func compare(firstString, secondString string) bool {
    f, s := strings.Split(firstString, " "), strings.Split(secondString, " ")
    if f[0] == s[0] || f[2] == f[2] {
        return true
    }
    return false
}

compare("3 of hearts", "5 of hearts")
## 这应该返回true

compare("7 of hearts", "7 of clubs")
## 这应该返回true

compare("Jack of spades", "Jack of spades")
## 这应该返回true

compare("5 of hearts", "7 of clubs")
## 这应该返回false
英文:

I'm fairly new to golang but the best way to get this without needing to loop twice would be:

func compare(firstString, secondString string) bool {
    f, s := strings.Split(f, &quot; &quot;), strings.Split(secondString, &quot; &quot;)
    if f[0] == s[0] || f[2] == f[2] {
        return true
    }
    return false
}

compare(&quot;3 of hearts&quot;, &quot;5 of hearts&quot;)
## This should return true

compare(&quot;7 of hearts&quot;, &quot;7 of clubs&quot;)
## This should return true

compare(&quot;Jack of spades&quot;, &quot;Jack of spades&quot;)
## This should return true

compare(&quot;5 of hearts&quot;, &quot;7 of clubs&quot;)
## This should return false

</details>



# 答案3
**得分**: 1

我不知道你真正想做什么(我的意思是,Hello World很无聊),但从问题中,我至少知道它可能与扑克有关。

所以你首先应该设计与扑克牌相关的**结构**。

然后你需要一个方法来从字符串中**获取对象**。

最后,设计一个卡牌的**相等**函数,然后完成。

----

1. `type Card struct{}`
2. `func GetCardFromStr(str string) (*Card, error)`
3. `func (card *Card) Equal(card2 *Card, criteria criteria) bool`

### 示例代码

```go
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),
		)
	}
}

通过使用上述代码,我相信没有人会对比较感到困惑,你将能够避免被投票降级。

然后你可以将问题转化为如何优化函数GetCardFromStr仅使用一层循环正则表达式、检测更多边缘情况


严格来说,我并没有回答你的问题,只是提供了关于你问题方向的参考。希望你不介意,祝你好运。

英文:

I don't know what you really want to do. (I mean hello world is boring)
But from the question, at least I know that it might be related to poker.

So you should first design the structure related to the playing cards.

Then you need a method to get the object from the string

Finally, design an Equal function of the card, then done.


  1. type Card struct{}
  2. func GetCardFromStr(str string) (*Card, error)
  3. func (card *Card) Equal(card2 *Card, criteria criteria) bool

Example Code

package main

import (
	&quot;fmt&quot;
	&quot;strconv&quot;
	&quot;strings&quot;
)

type Suit uint8

const (
	Spades Suit = iota + 1
	Hearts
	Diamonds
	Clubs
)

var suitMap map[string]Suit

func init() {
	suitMap = map[string]Suit{&quot;spades&quot;: Spades, &quot;hearts&quot;: Hearts, &quot;diamonds&quot;: Diamonds, &quot;clubs&quot;: 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 &lt; 0 || point &gt; 13 {
		return nil, fmt.Errorf(&quot;illegal point: &#39;%d&#39;, it should in the range: 1~13&quot;, point)
	}
	return &amp;Card{point, suit}, nil // you can consider checking the suit.
}

func (card *Card) String() string {
	return fmt.Sprintf(&quot;%s%d&quot;, map[Suit]string{
		Spades:   &quot;&quot;,
		Hearts:   &quot;&quot;,
		Diamonds: &quot;&quot;,
		Clubs:    &quot;&quot;,
	}[card.suit], card.point)
}

type criteria uint8

const (
	Loose criteria = 1 &lt;&lt; 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 &amp;&amp; (card.suit == card2.suit &amp;&amp; card.suit != 0) {
			return true
		}
		return false
	}
	if card.point == card2.point || (card.suit == card2.suit &amp;&amp; card.suit != 0) {
		return true
	}
	return false
}

func GetCardFromStr(str string) (*Card, error) {
	slice := strings.Split(str, &quot; &quot;)
	if slice == nil {
		return nil, fmt.Errorf(&quot;can&#39;t convert string to the card&quot;)
	}
	alphaMap := map[string]int{
		&quot;ace&quot;:  1,
		&quot;jack&quot;: 11, &quot;queen&quot;: 12, &quot;king&quot;: 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(&quot;can&#39;t convert string to the card (unknown point)&quot;)
	}
	if cardSuit == 0 {
		return nil, fmt.Errorf(&quot;can&#39;t convert string to the card (unknown suit)&quot;)
	}

	return NewCard(cardPoint, cardSuit)
}

func main() {
	for caseNumber, data := range []struct {
		s1 string
		s2 string
		criteria
	}{
		{&quot;-5 hearts&quot;, &quot;5 hearts&quot;, Loose},                                            // error illegal point: &#39;-5&#39;, it should in the range: 1~13
		{&quot;0&quot;, &quot;&quot;, Loose},                                                            // error can&#39;t convert string to the card (unknown point)
		{&quot;3 of hearts&quot;, &quot;3 of hearts&quot;, Loose},                                       // true
		{&quot;3 of hearts&quot;, &quot;5 of hearts&quot;, Loose},                                       // true
		{&quot;7 of hearts&quot;, &quot;7 of clubs&quot;, Loose},                                        // true
		{&quot;Jack of spades&quot;, &quot;Jack of spades&quot;, Strict},                                // true
		{&quot;Jack of spades&quot;, &quot;Jack spades&quot;, Strict},                                   // true
		{&quot;Jack of spades&quot;, &quot;Jack hearts&quot;, Strict},                                   // false
		{&quot;Jack of spades&quot;, &quot;Jack&quot;, Strict},                                          // error can&#39;t convert string to the card (unknown suit)
		{&quot;Jack of spades&quot;, &quot;spades&quot;, Strict},                                        // error can&#39;t convert string to the card (unknown point)
		{&quot;player Foo: 1 of clubs &quot;, &quot;player bar: I get an Ace of spades !!&quot;, Loose}, // true
	} {
		card1, err := GetCardFromStr(data.s1)
		if err != nil {
			fmt.Printf(&quot;case:%d errMsg:%s\n&quot;, caseNumber, err)
			continue
		}
		card2, err := GetCardFromStr(data.s2)
		if err != nil {
			fmt.Printf(&quot;case:%d errMsg:%s\n&quot;, caseNumber, err)
			continue
		}
		fmt.Printf(&quot;criteria %d, %s equal %s: %v\n&quot;,
			data.criteria, card1, card2, card1.Equal(card2, data.criteria),
		)
	}
}

<kbd>go playground</kbd>

By using the above code, I believe no one will be confused about the comparison, and you will be able to avoid the downvote.

and then you can turn the question to how to optimize the function GetCardFromStr <sup>use loop one layer only、 regexp、detection of more edges...</sup>


Strictly speaking, I am not answering the question but only providing reference to the direction of your question. I hope you don't mind, and good luck.

huangapple
  • 本文由 发表于 2022年5月18日 06:27:57
  • 转载请务必保留本文链接:https://go.coder-hub.com/72281334.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定