Desafio Go
Contador de palavras com Builder
Enunciado
Escreva um programa que leia uma string texto (pode ser fixa) e conte quantas vezes cada palavra aparece. Use strings.Fields para separar as palavras, normalize para minúsculas com strings.ToLower e imprima o resultado ordenado alfabeticamente. Use strings.Builder para montar a saída formatada.
Requisitos
- Use
strings.Fieldspara dividir o texto em palavras. - Normalize cada palavra para minúsculas com
strings.ToLower. - Conte a frequência de cada palavra usando um
map[string]int. - Ordene as palavras alfabeticamente e use
strings.Builderpara montar a string de saída no formatopalavra: contagempor linha.
Código inicial
package main
import (
"fmt"
"sort"
"strings"
)
func main() {
texto := "Go é divertido. Go é rápido. Python também é divertido."
// Seu código aqui
}
Saída esperada
divertido: 2
em: 0
é: 3
go: 2
python: 1
rápido: 1
também: 1
Ver dica
Após contar, extraia as chaves do map para um slice, ordene com sort.Strings e itere sobre elas escrevendo no Builder com fmt.Fprintf(&b, "%s: %d\n", palavra, contagem).
Mostrar solução
package main
import (
"fmt"
"sort"
"strings"
)
func main() {
texto := "Go é divertido. Go é rápido. Python também é divertido."
// Remove pontuação simples substituindo por espaço
texto = strings.ReplaceAll(texto, ".", "")
palavras := strings.Fields(texto)
contagem := make(map[string]int)
for _, p := range palavras {
p = strings.ToLower(p)
contagem[p]++
}
// Extrai e ordena as chaves
chaves := make([]string, 0, len(contagem))
for k := range contagem {
chaves = append(chaves, k)
}
sort.Strings(chaves)
// Monta a saída com strings.Builder
var b strings.Builder
for _, k := range chaves {
fmt.Fprintf(&b, "%s: %d\n", k, contagem[k])
}
fmt.Print(b.String())
}
Passo a passo
- Definimos o texto e removemos pontos com
strings.ReplaceAllpara não afetar as palavras. strings.Fieldsdivide o texto em palavras, ignorando espaços múltiplos.- Criamos um map
contagempara armazenar a frequência. - Para cada palavra, convertemos para minúsculas com
strings.ToLowere incrementamos o contador. - Extraímos as chaves do map para um slice e ordenamos com
sort.Strings. - Usamos um
strings.Builderefmt.Fprintfpara escrever cada linha no formatopalavra: contagem. - Imprimimos o conteúdo do Builder com
fmt.Print.
Por que funciona
strings.Fields lida com espaços em branco de forma robusta. O map acumula as contagens e a ordenação garante saída consistente. O strings.Builder evita concatenações repetidas, sendo eficiente para montar a saída final.
Erros comuns
- Não normalizar para minúsculas:
Goegoseriam contados separadamente. - Não remover pontuação:
divertido.seria uma palavra diferente dedivertido. - Iterar diretamente sobre o map sem ordenar: a ordem de saída seria aleatória.
- Usar
+para concatenar dentro do loop: menos eficiente que o Builder.
Outra forma de resolver
Usar sort.Slice com uma slice de structs {palavra, contagem}:
type par struct {
palavra string
count int
}
var pares []par
for p, c := range contagem {
pares = append(pares, par{p, c})
}
sort.Slice(pares, func(i, j int) bool { return pares[i].palavra < pares[j].palavra })
Essa abordagem é útil se você precisar ordenar por contagem também.
Saída esperada
divertido: 2
em: 0
é: 3
go: 2
python: 1
rápido: 1
também: 1