Contador de Ocorrência: a ambiguidade de contar padrões sobrepostos
Contar quantas vezes uma palavra ou trecho aparece dentro de um texto parece uma operação de busca simples, mas esconde uma decisão de design nem sempre óbvia: o que fazer quando ocorrências se sobrepõem? Contar "aa" dentro de "aaa" pode legitimamente retornar 1 (tratando ocorrências como não-sobrepostas, avançando o cursor de busca para depois de cada match encontrado) ou 2 (contando toda posição inicial possível, incluindo sobreposições — "aa" começa na posição 0 e também na posição 1 de "aaa"). As duas respostas são "corretas" dependendo da definição adotada — não existe uma resposta matematicamente única sem especificar qual das duas contagens está sendo pedida.
Por que a maioria das ferramentas escolhe não-sobreposta
A contagem não-sobreposta (avançar o cursor para depois de cada match)
é a escolha mais intuitiva para a maioria dos casos de uso reais —
contar quantas vezes uma palavra aparece num texto corrido não deveria
contar "ocorrências parciais sobrepostas" de uma mesma instância da
palavra. É também o comportamento padrão da maioria das funções de
busca de string em linguagens de programação (incluindo
String.prototype.split() do JavaScript, uma forma comum
de implementar essa contagem: dividir o texto pelo termo buscado e
contar quantas divisões ocorreram). A contagem sobreposta é mais
relevante em contextos específicos, como bioinformática (contar
ocorrências de um padrão de DNA, onde sobreposições têm significado
biológico real) — um domínio bem diferente de contagem de palavra em
texto comum.
Sensibilidade a maiúsculas/minúsculas: outra decisão explícita
Outra escolha que precisa ser explícita, não assumida: buscar
"Brasil" deveria contar também "brasil" e "BRASIL" como ocorrências?
Para a maioria dos usos de contagem de palavra em texto livre, ignorar
diferença de caixa é o comportamento mais útil (normalizar ambos os
lados da comparação para minúsculo antes de contar), mas para
contagem de identificadores sensíveis a caso (nomes de variável em
código-fonte, por exemplo, onde nome e Nome
são entidades diferentes), essa normalização removeria informação
relevante — a escolha certa depende do que está sendo contado, não é
universal.