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.Fields para 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.Builder para montar a string de saída no formato palavra: contagem por 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

  1. Definimos o texto e removemos pontos com strings.ReplaceAll para não afetar as palavras.
  2. strings.Fields divide o texto em palavras, ignorando espaços múltiplos.
  3. Criamos um map contagem para armazenar a frequência.
  4. Para cada palavra, convertemos para minúsculas com strings.ToLower e incrementamos o contador.
  5. Extraímos as chaves do map para um slice e ordenamos com sort.Strings.
  6. Usamos um strings.Builder e fmt.Fprintf para escrever cada linha no formato palavra: contagem.
  7. 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: Go e go seriam contados separadamente.
  • Não remover pontuação: divertido. seria uma palavra diferente de divertido.
  • 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