Как считать слова в файле - PullRequest
0 голосов
/ 31 марта 2019

Я хотел сделать функцию для подсчета слов в файле, чтобы найти позиции каждого слова в файле, я хочу, чтобы вывод был,

a, позиция: 0

ааа, позиция: 1

ахед, позиция: 2

Я уже пробовал это считать слова, но я не мог использовать его, чтобы получить позиции слов

scanner := bufio.NewScanner(strings.NewReader(input))

// Set the split function for the scanning operation.
scanner.Split(bufio.ScanWords)

// Count the words.
count := 0
for scanner.Scan() {
    count++
}

if err := scanner.Err(); err != nil {
    fmt.Fprintln(os.Stderr, "reading input:", err)
}

fmt.Printf("%d\n", count)

Могу ли я использовать цикл для этого?Потому что я хотел бы проиндексировать позицию.Например, слово [позиция] == слово [позиция + 1], чтобы узнать, совпадает ли слово в определенной позиции со словом в следующей позиции.

Ответы [ 2 ]

1 голос
/ 31 марта 2019

Вы можете прочитать входную строку по одному символу за раз.Таким образом, вы получаете полный контроль над данными, которые вы хотите вывести.В Go символы называются рунами:

b, err := ioutil.ReadFile("test.txt")
if err != nil {
    panic(err)
}

reader := bytes.NewReader(b)
// Word is temporary word buffer that we use to collect characters for current word.
word := strings.Builder{}
wordPos := 0
line := 0
pos := 0
for {
    // Read next character
    if r, _, err := reader.ReadRune(); err != nil {
        if err == io.EOF {
            // Output last word if this is end of file
            fmt.Println(word.String(), "line:", line, "position:", wordPos)
            break
        } else {
            panic(err)
        }
    } else {
        // If current character is new line reset position counters and word buffer.
        if r == '\n' {
            fmt.Println(word.String(), "line:", line, "position:", wordPos)
            word.Reset()
            pos = 0
            wordPos = 0
            line++
        } else if r == ' ' { // Found word separator: output word, reset word buffer and set next word position.
            fmt.Println(word.String(), "line:", line, "position:", wordPos)
            word.Reset()
            wordPos = pos + 1
            pos++
        } else { // Just a regular character: write it to word buffer.
            word.WriteRune(r)
            pos++
        }
    }
}

Я использую strings.Builder, чтобы избавиться от ненужного копирования строк.

Также вы должны настроить этот пример для работы с крайними случаями, такими как пустая строкаи, возможно, другие.

1 голос
/ 31 марта 2019

Представьте себе, что у вас есть testfile.txt:

this is fine

Вы можете использовать этот go-скрипт для циклического перебора каждого слова и печати слова с его текущей позицией:

package main

import (
    "bufio"
    "fmt"
    "os"
)

func main() {
    // initiate file-handle to read from
    fileHandle, err := os.Open("testfile.txt")

    // check if file-handle was initiated correctly
    if err != nil {
        panic(err)
    }

    // make sure to close file-handle upon return
    defer fileHandle.Close()

    // initiate scanner from file handle
    fileScanner := bufio.NewScanner(fileHandle)

    // tell the scanner to split by words
    fileScanner.Split(bufio.ScanWords)

    // initiate counter
    count := 0

    // for looping through results
    for fileScanner.Scan() {
        fmt.Printf("word: '%s' - position: '%d'\n", fileScanner.Text(), count)
        count++
    }

    // check if there was an error while reading words from file
    if err := fileScanner.Err(); err != nil {
        panic(err)
    }

    // print total word count
    fmt.Printf("total word count: '%d'", count)
}

Вывод:

$ go run main.go
word: 'this' - position: '0'
word: 'is' - position: '1'
word: 'fine' - position: '2'
total word count: '3'

Если вы хотите сравнить слова по индексу, вы можете сначала загрузить их в фрагмент.

Представьте, что у вас есть текстовый файл:

fine this is fine

Используйте этокод:

package main

import (
    "bufio"
    "fmt"
    "os"
)

func main() {
    // initiate file-handle to read from
    fileHandle, err := os.Open("testfile.txt")

    // check if file-handle was initiated correctly
    if err != nil {
        panic(err)
    }

    // make sure to close file-handle upon return
    defer fileHandle.Close()

    // initiate scanner from file handle
    fileScanner := bufio.NewScanner(fileHandle)

    // tell the scanner to split by words
    fileScanner.Split(bufio.ScanWords)

    // initiate wordsSlice
    var wordSlice []string

    // for looping through results
    for fileScanner.Scan() {
        wordSlice = append(wordSlice, fileScanner.Text())
    }

    // check if there was an error while reading words from file
    if err := fileScanner.Err(); err != nil {
        panic(err)
    }

    // loop through word slice and print word with index
    for i, w := range wordSlice {
        fmt.Printf("word: '%s' - position: '%d'\n", w, i)
    }

    // compare words by index
    firstWordPos := 0
    equalsWordPos := 3
    if wordSlice[firstWordPos] == wordSlice[equalsWordPos] {
        fmt.Printf("word at position '%d' and '%d' is equal: '%s'\n", firstWordPos, equalsWordPos, wordSlice[firstWordPos])
    }

    // print total word count
    fmt.Printf("total word count: '%d'", len(wordSlice))
}

Выход:

$ go run main.go
word: 'fine' - position: '0'
word: 'this' - position: '1'
word: 'is' - position: '2'
word: 'fine' - position: '3'
word at position '0' and '3' is equal: 'fine'
total word count: '4'
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...