Solicitação de algoritmo 10 – repetição de valores no vetor
A solicitação foi enviada por Jean Vitor Vieira, que já apresentou uma versão quase pronta do código. Segue a seguir o enunciado.
Enunciado: elaborar uma função que retorna o número que mais se repete em um vetor e quantas vezes esse número aparece (em caso de igualdade, o primeiro encontrado tem preferência) no array.
O Jean elaborou a função mostrada a seguir. A função retorna na variável “qtd_repeticao” a quantidade de vezes que o determinado número se repete no array. Caso seja fornecido um array inválido, retorna a constante HUGE_VAL (constante pertencente a biblioteca math.h) e ZERO em “qtd_repeticao”.
Na solicitação do Jean ele avisa que somente conseguiu elaborar o código para achar o valor que mais se repete no vetor, mas não conseguiu achar quantas vezes ele se repete.
double repetido(double* valores, unsigned int qtd_numeros, unsigned int *qtd_repeticao){
if (!valores || qtd_numeros==0) {
*qtd_repeticao=0;
return HUGE_VAL;
}
//*qtd_repeticao+=1; não sei aonde implementar esse contador;
unsigned int cont1=0, cont2=-1;
double maisRepetido;
for(unsigned int i=0;i<qtd_numeros-1;i++){
for(unsigned int j=i+1;j<qtd_numeros;j++){
if(valores[i]==valores[j]){
cont1++;
}
if(cont1>cont2){
maisRepetido=valores[i];
}
cont2=cont1;
cont1=0;
}
}
return maisRepetido;
}
Entendendo inicialmente a função implementada pelo Jean, veja que ela recebe um vetor de elementos do tipo double e a quantidade de elementos existentes nesse vetor. O retorno da função é o valor que mais se repete, mas também terá quantas vezes esse valor repete, valor armazenado na variável “qtd_repeticao” que é passada por referência. Um detalhe pensado pelo Jean é que as variáveis com o tamanho do vetor e com a quantidade de repetições são unsigned int, ou seja, elas somente aceitam o valor zero ou valores positivos (o que é efetivamente esperado para os valores dessas variáveis). A função também pode retornar um HUGE_VAL (conforme instrução na linha 5), que é uma constante existente na math.h é que possui o maior valor double representável no computador que executa o código.
Para não deixar a função “solta”, elaborei o código da função main(). Também fiz algumas modificações na função para retirar aqueles unsigned int e ficar mais fácil de entender o código (o uso da unsigned int feito pelo Jean está correto, mas esse é um aprimoramento de código que prefiro fazer somente depois de ter resolvido o problema).
#include <stdio.h>
#include <math.h>
double repetido(double* valores, int qtd_numeros, int *qtd_repeticao){
if (!valores || qtd_numeros==0) {
*qtd_repeticao=0;
return HUGE_VAL;
}
*qtd_repeticao=1000;
int cont1=0, cont2=-1;
double maisRepetido;
for(int i=0;i<qtd_numeros-1;i++){
for(int j=i+1;j<qtd_numeros;j++){
if(valores[i]==valores[j]){
cont1++;
}
if(cont1>cont2){
maisRepetido=valores[i];
}
cont2=cont1;
cont1=0;
}
}
return maisRepetido;
}
int main(void) {
int qtd;
double vet[] = {1.0,2,3,3,4.0}, valor;
valor = repetido(vet,5,&qtd);
printf("%f %i", valor, qtd);
return 0;
}
Na minha main() apenas criei um vetor de valores double, uma variável para armazenar o valor que mais se repete e uma variável para armazenar quantas vezes esse valor repete (que é passada por referência). Na função repetido() eu coloquei a linha 10 que apenas atribui o valor 1000 a variável com a quantidade de repetições. O resultado da execução do código mostrará que o valor que mais repete é o 3 e que ele repete 1000 vezes.
Posso dizer que o Jean fez a parte difícil. Vejo pelo código dele que, na linha 8, ele já sabia que precisaria incrementar a variável que conta a repetição. Só acho que ele pensou em fazer o processo muito antes. Para esse problema, o primeiro passo envolve descobrir qual o valor que mais repete e somente depois é possível contar quantas vezes ele repete. Por isso adicionei ao código abaixo as linhas 28-33.
#include <stdio.h>
#include <math.h>
double repetido(double* valores, int qtd_numeros, int *qtd_repeticao){
if (!valores || qtd_numeros==0) {
*qtd_repeticao=0;
return HUGE_VAL;
}
int cont1=0, cont2=-1;
double maisRepetido;
for(int i=0;i<qtd_numeros-1;i++){
for(int j=i+1;j<qtd_numeros;j++){
if(valores[i]==valores[j]){
cont1++;
}
if(cont1>cont2){
maisRepetido=valores[i];
}
cont2=cont1;
cont1=0;
}
}
*qtd_repeticao = 0;
for(int i=0;i<qtd_numeros;i++){
if (valores[i] == maisRepetido) {
*qtd_repeticao+=1;
}
}
return maisRepetido;
}
int main(void) {
int qtd;
double vet[] = {1.0,2,3,3,4.0}, valor;
valor = repetido(vet,5,&qtd);
printf("%f %i", valor, qtd);
return 0;
}
Veja que linha 28 eu inicializei a variável. A função deveria fazer isso mesmo que na linha 38 (na função principal main()) eu inicializasse a variável. Embora o resultado fosse o mesmo, é importante a função garantir a devida inicialização das variáveis. Com isso, mesmo que seja esquecido de inicializar a variável na função principal, mesmo assim o resultado não será incoerente.