Desenvolva um programa na linguagem C que receba do usuário um número inteiro N que indicará uma quantidade de números com casas decimais que serão lidos. O usuário deverá digitar os N números e em seguida deverá ser questionado se ele quer realizar uma busca ou sair do programa. Se o usuário optar por fazer a busca, ele deverá digitar um número e o programa deverá responder se o número fora digitado anteriormente e quantas vezes ele foi digitado. Após a resposta do programa (se o número foi ou não digitado e quantas vezes foi digitado), o usuário deverá ser questionado se ele deseja perguntar por outro número ou se deseja sair do programa, repetindo o procedimento até que o usuário responda por sair do programa.

Passo 1

O enunciado pede um programa que: receberá um número inteiro N (quantidade de valores com casas decimais) e em seguida lerá N números. Depois disso, repetidamente o programa deve perguntar ao usuário se ele quer realizar uma busca ou sair. Se o usuário escolher buscar, ele digita um número e o programa responde se esse número foi digitado anteriormente e quantas vezes ele aparece entre os N números lidos. Após cada busca, o programa volta a perguntar se o usuário deseja fazer outra busca ou sair, repetindo até o usuário escolher sair.
Informações dadas (lista clara):
  • O usuário fornece um inteiro N.
  • Serão fornecidos N números com casas decimais (valores reais).
  • Depois de ler os N números, o programa entra em um laço de interação: perguntar “buscar ou sair”, em caso de busca receber um número e informar presença/contagem, e repetir até o usuário sair.

Passo 2

Decisões de projeto (por que escolhemos cada coisa):
  • Vamos armazenar os N números em um vetor (array) dinâmico para suportar qualquer N informado em tempo de execução. Em C, isso significa usar malloc para alocar um array de double de tamanho N.
  • Usaremos o tipo double para representar os números com casas decimais (valores reais). Em C, double tem precisão suficiente para a maioria dos usos didáticos.
  • Para a interação “buscar ou sair” usaremos um laço while que só termina quando o usuário responde que quer sair.
  • Para contar quantas vezes um número pesquisado aparece, faremos uma varredura do array e incrementaremos um contador sempre que encontrarmos igualdade com o número pesquisado.
    Observação importante sobre igualdade de ponto-flutuante: comparar double com == é normalmente perigoso quando os números são resultados de cálculos. Aqui, tanto o número armazenado quanto o número pesquisado serão lidos do teclado e convertidos pelo mesmo analisador de ponto-flutuante. Isso faz com que, na prática, se o usuário digitar exatamente a mesma representação decimal (por exemplo 1.25 nas duas vezes), ambos sejam convertidos para o mesmo valor binário e a comparação == funcione como o usuário espera. Se você quiser tolerância (por exemplo, aceitar 1,2500001 como igual a 1,25), poderia usar uma comparação com epsilon. Aqui vamos manter == por simplicidade e porque a entrada/consulta vem do usuário na mesma forma textual.

Passo 3

Algoritmo em alto nível (pseudocódigo explicadinho):
  1. Ler inteiro N. Se N \le 0 avisar e encerrar (validação).
  2. Alocar vetor arr de N elementos do tipo double.
  3. Para i=0 até N-1: ler arr[i] (um double).
  4. Entrar em laço infinito:
    a. Perguntar ao usuário se deseja buscar (digitar s para sim ou n para não).
    b. Se o usuário digitar n → sair do laço (encerrar programa).
    c. Se o usuário digitar s → ler um double x a ser buscado. Fazer contador count = 0. Para cada elemento do vetor, se arr[i] == x então count++. Depois:
    • Se count > 0 mostrar que o número foi digitado e quantas vezes.
    • Senão mostrar que o número não foi digitado.
      d. Repetir (volta ao passo a).
  5. Liberar memória e encerrar.

Passo 4

Detalhes de implementação em C e funções usadas (pequena “aula” prática):
  • Ler valores: usaremos scanf("%d", &N) para inteiros e scanf("%lf", &x) para double. "%lf" é o especificador de formato correto para double no scanf.
  • Alocação dinâmica: double *arr = malloc(N * sizeof(double)); — aqui arr aponta para um bloco de memória capaz de guardar N valores double. Sempre verifique se malloc retornou NULL.
  • Varredura e contagem: um laço for (int i = 0; i < N; ++i) é suficiente.
  • Leitura de respostas (s/n): ao usar scanf para ler um caractere, é importante consumir espaços em branco anteriores com o formato " %c" (observe o espaço antes de %c), isso faz o scanf pular qualquer newline ou espaço remanescente.
  • Boas práticas: checar o retorno do scanf para detectar entradas inválidas; liberar a memória com free(arr) antes de terminar.
  • Mensagens ao usuário: sempre explique o que digitar, por exemplo “Digite ‘s’ para buscar ou ‘n’ para sair”.

Passo 5

Como contar as ocorrências passo a passo (explicação operativa):
  • Supondo que o número pesquisado seja x (variável double x no código), inicializamos int count = 0.
  • Percorremos o vetor: para cada índice i, comparamos arr[i] == x. Se for verdade, fazemos count = count + 1.
  • Após terminar a varredura, o valor de count diz quantas vezes x aparece.
  • Interpretação dos resultados:
    • Se \text{count} > 0: o número foi digitado anteriormente e aparece \text{count} vezes.
    • Se \text{count} = 0: o número não foi digitado anteriormente.

Passo 6

Tratamento de entradas inválidas, casos de borda e alternativas:
  • Se o usuário digitar um N inválido (por exemplo zero ou negativo ou uma entrada não-numérica), o programa deve informar e encerrar ou pedir novamente. Aqui implementaremos a verificação e encerramento simples com mensagem de erro.
  • Se malloc falhar, encerramos com mensagem de erro.
  • Se o usuário digitar algo que não pode ser convertido para double na leitura dos números ou na busca, o scanf falhará e podemos encerrar com uma mensagem de entrada inválida.
  • Alternativa para igualdade: se quiser tolerância, comparar com uma pequena constante eps do tipo if (fabs(arr[i] - x) < eps). Isso é útil quando há operações matemáticas; para entradas puras do teclado, comparar com == é aceitável.

Passo 7

Complexidade e comportamento:
  • Tempo para contar ocorrências de um número: O(N) por busca (varredura simples do vetor).
  • Espaço usado: O(N) para armazenar os N valores.
  • Para um número moderado de buscas e N moderado, esse algoritmo é perfeitamente aceitável. Se houvesse muitas buscas e N muito grande, poderíamos pensar em usar uma tabela de frequência (hash map) para fazer cada busca em tempo médio O(1). Em C puro, isso complica um pouco e a solução por varredura é a mais simples para provas e exercícios.

Passo 8

Dicas para a hora da prova / pontos a observar:
  • Explique no enunciado do código o que cada parte faz (comentários).
  • Valide entradas ao máximo para evitar comportamentos estranhos.
  • Lembre-se do especificador "%lf" para double no scanf.
  • Ao perguntar pelo usuário se continua, aceite tanto maiúsculas quanto minúsculas ('S' ou 's').
  • Sempre liberar a memória alocada com free.

Resposta

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
int main(void) {
int N;
printf(“Digite um inteiro N (quantidade de números): “);
if (scanf(”%d”, &N) != 1 || N <= 0) {
printf(“Valor de N invalido. Encerrando.\n”);
return 1;
}
double *arr = malloc(N * sizeof(double));
if (arr == NULL) {
    printf("Erro na alocacao de memoria. Encerrando.\n");
    return 1;
}

for (int i = 0; i < N; ++i) {
    printf("Digite o numero %d: ", i + 1);
    if (scanf("%lf", &arr[i]) != 1) {
        printf("Entrada invalida. Encerrando.\n");
        free(arr);
        return 1;
    }
}

char opc;
while (1) {
    printf("Deseja realizar uma busca? (s para sim / n para nao): ");
    if (scanf(" %c", &opc) != 1) {
        printf("Entrada invalida. Encerrando.\n");
        break;
    }
    opc = (char) tolower((unsigned char) opc);

    if (opc == 'n') {
        break;
    } else if (opc == 's') {
        double x;
        printf("Digite o numero a buscar: ");
        if (scanf("%lf", &x) != 1) {
            printf("Entrada invalida. Encerrando.\n");
            break;
        }
        int count = 0;
        for (int i = 0; i < N; ++i) {
            if (arr[i] == x) {
                count++;
            }
        }
        if (count > 0) {
            printf("O numero foi digitado %d vez(es).\n", count);
        } else {
            printf("O numero nao foi digitado anteriormente.\n");
        }
        /* o laço continua e pergunta novamente */
    } else {
        printf("Opcao invalida. Digite 's' para sim ou 'n' para nao.\n");
    }
}

free(arr);
printf("Programa encerrado.\n");
return 0;
}

Exercícios relacionados