Làm cách nào để so sánh các chuỗi trong GoLang?


89

Tôi không thể tạo ra kết quả 'true' khi so sánh chuỗi Go. Tôi đã viết phần sau để giải thích vấn đề và đính kèm ảnh chụp màn hình đầu ra

// 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)

}

thí dụ


người sử dụng cửa sổ kiểm tra câu trả lời của tôi :)
Daksh Miglani

Câu trả lời:


128

==là toán tử chính xác để so sánh các chuỗi trong cờ vây. Tuy nhiên, các chuỗi mà bạn đọc từ STDIN reader.ReadStringkhông chứa "a", nhưng "a\n"(nếu bạn nhìn kỹ, bạn sẽ thấy thêm dấu ngắt dòng trong đầu ra ví dụ của mình).

Bạn có thể sử dụng strings.TrimRightchức năng để xóa khoảng trắng ở cuối khỏi đầu vào của mình:

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

9

Đối với Người dùng độc lập nền tảng hoặc người dùng Windows, những gì bạn có thể làm là:

nhập thời gian chạy:

import (
    "runtime"
    "strings"
)

và sau đó cắt chuỗi như thế này:

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

bây giờ bạn có thể so sánh nó như thế:

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

Đây là một cách tiếp cận tốt hơn khi bạn đang sử dụng STDIN trên nhiều nền tảng.

Giải trình

Điều này xảy ra bởi vì trên các dòng windows kết thúc bằng "\r\n"CRLF, nhưng trên các dòng UNIX kết thúc bằng "\n"nó được gọi là LF và đó là lý do tại sao chúng ta cắt "\n"trên hệ điều hành dựa trên unix trong khi chúng ta cắt "\r\n"trên windows.


4
Không cần phải phân biệt. Đối số thứ hai là một tập hợp cắt, không phải là một hậu tố và bất kỳ ký tự nào trong tập hợp cắt sẽ được cắt bớt, theo bất kỳ thứ tự / kết hợp nào. Việc cắt bớt "\ r \ n" sẽ là đủ trên cả hai.
Jason Carlson

1

Giả sử không có ký tự khoảng trắng nào viết trước / nối tiếp, vẫn có một số cách để khẳng định sự bình đẳng chuỗi. Một số trong số đó là:

Dưới đây là một số kết quả điểm chuẩn cơ bản (trong các bài kiểm tra này, strings.EqualFold(.., ..)có vẻ như là lựa chọn hiệu quả nhất):

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

Vì có khá nhiều tùy chọn, vì vậy đây là mã để tạo điểm chuẩn.

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

Nội dung bên trong chuỗi trong Golang có thể được so sánh bằng ==toán tử. Nếu kết quả không như mong đợi, có thể có một số ký tự ẩn như \n,, \rdấu cách, v.v. Vì vậy, theo nguyên tắc chung, hãy thử xóa những ký tự đó bằng cách sử dụng các hàm được cung cấp bởi stringsgói trong golang.

Đối với Instance, có thể loại bỏ khoảng trắng bằng strings.TrimSpacehàm. Bạn cũng có thể xác định một hàm tùy chỉnh để loại bỏ bất kỳ ký tự nào bạn cần. strings.TrimFuncchức năng có thể cung cấp cho bạn nhiều quyền lực hơn.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.