Escrever um programa em C que calcule e imprima o número de caracteres distintos presentes em uma cadeia de caracteres dada. Considerar o tamanho máximo da cadeia como sendo de 80 colunas.
Passo 1
O enunciado pede que você escreva um programa em C que calcule e imprima o número de caracteres distintos presentes em uma cadeia de caracteres dada. Informações fornecidas pelo enunciado (vou listar bem claro):
- O tamanho máximo da cadeia é
80 colunas. - O programa deve ler uma única cadeia de entrada (uma linha) e imprimir a quantidade de caracteres diferentes que aparecem nela.
- Não foi especificado ignorar espaços, pontuação ou diferenciar maiúsculas/minúsculas — portanto vou considerar que todos os caracteres possíveis na linha contam (espaço conta, ponto conta, e
e são diferentes). - A saída esperada é apenas o número de caracteres distintos (seguido de uma nova linha, normalmente).
Passo 2
Decisões e suposições (não te pergunto nada, apenas explico o que vou usar):
- Vou tratar os caracteres considerando seu valor de byte, isto é, cada possível código de caractere distinto (do conjunto de valores de
a ) pode ser contado separadamente. Isso cobre a maioria dos casos práticos de entrada em C. Em resumo, vou usar uma tabela de presença de tamanho 256 . - Vou ler a linha com uma função segura (vou usar
) e garantir espaço suficiente no buffer para até 80 caracteres mais o possível caractere de nova linha e o terminador nulo. Por isso o buffer terá tamanho quando é 80 . - Vou remover o caractere de nova linha lido por
(se existir) para que ele não seja contado como parte da cadeia, pois a intenção usual é contar apenas os caracteres da linha digitada.
Passo 3
Estratégia algorítmica (explicação didática do método):
- Idea geral: percorrer cada caractere da cadeia e marcar que esse caractere já apareceu. Toda vez que encontramos um caractere que ainda não apareceu, incrementamos o contador de distintos.
- Estrutura usada: um vetor
de inteiros com tamanho 256 , inicializado com zeros. A posição indica se já vimos o caractere cujo código de byte é . - Por que
256 ? Porque um tem valores de a e podemos indexar diretamente por esse valor. - Por que converter para
? Em C, o tipo pode ser assinado ou não. Se for assinado, ao usá-lo como índice ele pode gerar índice negativo. Converter para garante índices na faixa – . - Complexidade: para uma cadeia de tamanho
, percorremos a cadeia uma vez, logo é em tempo. A memória usada é constante (o vetor tem tamanho fixo 256 ).
Passo 4
Leitura da entrada e tratamento de nova linha (detalhes práticos):
- Defino
. Vou declarar o buffer como . Explicando: dá espaço para até 80 caracteres reais, mais um possível caractere de nova linha \(\backslash\)ne o terminador nulo\(\backslash\)0. - Uso
para ler a linha. lê no máximo caracteres e sempre termina a string com \(\backslash\)0\). Se houver uma nova linha e couber, ela também ficará em. - Após a leitura, calculo o comprimento com
e, se o último caractere for \(\backslash\)n, eu o substituo por\(\backslash\)0\)para que não seja contado.
Passo 5
Contagem passo a passo (o laço que faz a mágica):
- Inicializo
e . - Percorro a string com um índice
começando em 0 e rodando enquanto . - Para cada caractere faço:
-
— pega o código de byte não-negativo. - Se
então e .
-
- Ao final do laço,
contém o número de caracteres distintos na linha.
Passo 6
Exemplo concreto (para fixar a ideia):
- Se a entrada for a string
: - percorremos:
-> visto pela primeira vez -> ; -
-> visto pela primeira vez -> ; -
-> visto pela primeira vez -> ; -
-> já visto -> sem mudança; -
-> já visto -> sem mudança; -
-> já visto -> sem mudança; - Resultado:
.
- percorremos:
- Se a entrada tiver espaços, por exemplo
, o espaço conta como um caractere separado.
Passo 7
Detalhes de implementação e boas práticas:
- Inicializar
com garante zeros em todas as posições. - Usar
para índices quando for apropriado (por exemplo ao usar ), mas para é suficiente. - Imprimir com
— isso mostra o número e quebra a linha. - Caso a entrada seja vazia (linha só com
\(\backslash\)nou sem caracteres), o programa imprime0 .
Passo 8
Agora que você entendeu tudo passo a passo, aqui está o programa completo em C que implementa exatamente o que descrevemos (leitura segura, remoção de nova linha, tabela de presença de caracteres, contagem e impressão do resultado).
Resposta
#include <stdio.h>
#include <string.h>
#define MAX 80
int main(void) {
char s[MAX + 2]; /* espaço para até 80 chars + possível '\n' + '\0' */
if (fgets(s, sizeof s, stdin) == NULL) return 0;
/* remover nova linha final, se presente */
size_t len = strlen(s);
if (len > 0 && s[len - 1] == '\n') {
s[len - 1] = '\0';
}
int seen[256] = {0};
int count = 0;
for (size_t i = 0; s[i] != '\0'; ++i) {
unsigned char uc = (unsigned char)s[i];
if (!seen[uc]) {
seen[uc] = 1;
++count;
}
}
printf("%d\n", count);
return 0;
}