GoLang'da dizeleri nasıl karşılaştırırım?


93

Go dize karşılaştırması söz konusu olduğunda 'gerçek' bir sonuç üretemiyorum. Sorunu açıklamak için aşağıdakileri yazdım ve çıktının ekran görüntüsünü ekledim

// string comparison in Go
package main
import "fmt"
import "bufio"
import "os"

func main() {
    var isLetterA bool 

    fmt.Println("Enter the letter a")
    reader := bufio.NewReader(os.Stdin)
    input, _ := reader.ReadString('\n')

    if(input == "a") {
        isLetterA = true
    } else {
        isLetterA = false 
    }

    fmt.Println("You entered",input)
    fmt.Println("Is it the letter a?",isLetterA)

}

misal


windows kullanıcıları cevabımı kontrol ediyor :)
Daksh Miglani

Yanıtlar:


132

==Go'daki dizeleri karşılaştırmak için doğru operatördür. Bununla birlikte, STDIN'den okuduğunuz dizeler reader.ReadStringiçermez "a", ancak "a\n"(yakından bakarsanız, örnek çıktınızda fazladan satır sonunu görürsünüz).

Kullanabilirsiniz strings.TrimRightGirişinizden sondaki beyaz boşlukları kaldırmak işlevi :

if strings.TrimRight(input, "\n") == "a" {
    // ...
}

9

Platformdan Bağımsız Kullanıcılar veya Windows kullanıcıları için yapabilecekleriniz:

çalışma zamanını içe aktar:

import (
    "runtime"
    "strings"
)

ve sonra dizeyi şu şekilde kesin:

if runtime.GOOS == "windows" {
  input = strings.TrimRight(input, "\r\n")
} else {
  input = strings.TrimRight(input, "\n")
}

şimdi bunu şu şekilde karşılaştırabilirsiniz:

if strings.Compare(input, "a") == 0 {
  //....yourCode
}

STDIN'i birden fazla platformda kullanırken bu daha iyi bir yaklaşımdır.

Açıklama

Bunun nedeni, Windows satırlarında "\r\n"CRLF olarak bilinen satırların bitmesi , ancak UNIX satırlarında "\n"LF olarak bilinen ile bitmesi ve bu nedenle pencereleri "\n"kırparken unix tabanlı işletim sistemlerinde düzeltme yapıyoruz "\r\n".


4
Ayrılmaya gerek yok. İkinci bağımsız değişken bir kesme kümesidir, bir son ek değildir ve kesme kümesindeki herhangi bir karakter herhangi bir sırada / kombinasyonda kırpılacaktır. Her ikisinde de "\ r \ n" nin kırpılması yeterli olacaktır.
Jason Carlson

1

Başına gelen / sonraki beyaz boşluk karakterlerinin olmadığını varsayarsak, dizge eşitliğini sağlamanın birkaç yolu vardır. Bunlardan bazıları:

İşte bazı temel kıyaslama sonuçları (bu testlerde strings.EqualFold(.., ..)en yüksek performanslı seçenek gibi görünüyor):

goos: darwin
goarch: amd64
BenchmarkStringOps/both_strings_equal::equality_op-4               10000        182944 ns/op
BenchmarkStringOps/both_strings_equal::strings_equal_fold-4        10000        114371 ns/op
BenchmarkStringOps/both_strings_equal::fold_caser-4                10000       2599013 ns/op
BenchmarkStringOps/both_strings_equal::lower_caser-4               10000       3592486 ns/op

BenchmarkStringOps/one_string_in_caps::equality_op-4               10000        417780 ns/op
BenchmarkStringOps/one_string_in_caps::strings_equal_fold-4        10000        153509 ns/op
BenchmarkStringOps/one_string_in_caps::fold_caser-4                10000       3039782 ns/op
BenchmarkStringOps/one_string_in_caps::lower_caser-4               10000       3861189 ns/op

BenchmarkStringOps/weird_casing_situation::equality_op-4           10000        619104 ns/op
BenchmarkStringOps/weird_casing_situation::strings_equal_fold-4    10000        148489 ns/op
BenchmarkStringOps/weird_casing_situation::fold_caser-4            10000       3603943 ns/op
BenchmarkStringOps/weird_casing_situation::lower_caser-4           10000       3637832 ns/op

Oldukça az seçenek olduğundan, kıyaslama oluşturacak kod burada.

package main

import (
    "fmt"
    "strings"
    "testing"

    "golang.org/x/text/cases"
    "golang.org/x/text/language"
)

func BenchmarkStringOps(b *testing.B) {
    foldCaser := cases.Fold()
    lowerCaser := cases.Lower(language.English)

    tests := []struct{
        description string
        first, second string
    }{
        {
            description: "both strings equal",
            first: "aaaa",
            second: "aaaa",
        },
        {
            description: "one string in caps",
            first: "aaaa",
            second: "AAAA",
        },
        {
            description: "weird casing situation",
            first: "aAaA",
            second: "AaAa",
        },
    }

    for _, tt := range tests {
        b.Run(fmt.Sprintf("%s::equality op", tt.description), func(b *testing.B) {
            for i := 0; i < b.N; i++ {
                benchmarkStringEqualsOperation(tt.first, tt.second, b)
            }
        })

        b.Run(fmt.Sprintf("%s::strings equal fold", tt.description), func(b *testing.B) {
            for i := 0; i < b.N; i++ {
                benchmarkStringsEqualFold(tt.first, tt.second, b)
            }
        })

        b.Run(fmt.Sprintf("%s::fold caser", tt.description), func(b *testing.B) {
            for i := 0; i < b.N; i++ {
                benchmarkStringsFoldCaser(tt.first, tt.second, foldCaser, b)
            }
        })

        b.Run(fmt.Sprintf("%s::lower caser", tt.description), func(b *testing.B) {
            for i := 0; i < b.N; i++ {
                benchmarkStringsLowerCaser(tt.first, tt.second, lowerCaser, b)
            }
        })
    }
}

func benchmarkStringEqualsOperation(first, second string, b *testing.B) {
    for n := 0; n < b.N; n++ {
        _ = strings.ToLower(first) == strings.ToLower(second)
    }
}

func benchmarkStringsEqualFold(first, second string, b *testing.B) {
    for n := 0; n < b.N; n++ {
        _ = strings.EqualFold(first, second)
    }
}

func benchmarkStringsFoldCaser(first, second string, caser cases.Caser, b *testing.B) {
    for n := 0; n < b.N; n++ {
        _ = caser.String(first) == caser.String(second)
    }
}

func benchmarkStringsLowerCaser(first, second string, caser cases.Caser, b *testing.B) {
    for n := 0; n < b.N; n++ {
        _ = caser.String(first) == caser.String(second)
    }
}

0

Golang'daki dizelerin içindeki içerik, ==operatör kullanılarak karşılaştırılabilir . Sonuçlar olarak beklenen değilseniz gibi bazı gizli karakterler olabilir \n, \rYani başparmak genel bir kural olarak, sağladığı fonksiyonlar kullananlar kaldırmayı deneyin, boşluk vb stringsgolang içinde paketin.

Örnek için, strings.TrimSpaceişlev kullanılarak boşluklar kaldırılabilir . İhtiyacınız olan herhangi bir karakteri kaldırmak için özel bir işlev de tanımlayabilirsiniz. strings.TrimFuncişlevi size daha fazla güç verebilir.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.