o elemento que corresponde à mediana de um vetor e
a moda dos elementos de um vetor.
Estas funções devem receber como parâmetro um vetor de números reais e um número inteiro indicando o tamanho deste vetor. Tente criar funções auxiliares para facilitar a organização do código.
Passo 1
O enunciado pede funções que recebam um vetor de números reais e seu tamanho (um inteiro) e retornem os seguintes valores:
a soma dos elementos do vetor;
a média dos elementos do vetor;
o desvio padrão dos elementos do vetor;
o número de elementos repetidos no vetor;
o elemento que corresponde à mediana do vetor;
a moda dos elementos do vetor.
Informações relevantes dadas (implícitas no enunciado):
Cada função receberá dois parâmetros: um ponteiro para um vetor de números reais e um inteiro que indica o tamanho do vetor. Em termos matemáticos: o vetor será (x_1, x_2, \dots, x_n) e o inteiro é n.
Não foi especificado tratamento de casos como n \le 0 ou empates na moda; será necessário escolher uma política e documentá‑la.
Foi sugerido “criar funções auxiliares” para organizar o código.
O enunciado pediu explicitamente funções — não pediu uma linguagem, então vou implementar em linguagem C (ferramenta comum em provas e exercícios de programação) e criar funções auxiliares para copiar e ordenar o vetor, além de uma função comparadora para o qsort.
Passo 2
Decisão de métodos e políticas (explicando o porquê, conforme pedido):
Linguagem: C. É uma escolha padrão para exercícios de algoritmos; o código fica claro e próximo do que costuma ser exigido em provas.
Ordenação: vou usar a função padrão qsort da biblioteca C para simplificar e focar nas funções pedidas (o custo será O(n\log n)). Para não modificar o vetor original, vou sempre trabalhar numa cópia quando precisar de ordenação.
Média: usarei a fórmula clássica:
\bar{x} = \dfrac{1}{n}\sum_{i=1}^{n} x_i.
Desvio padrão: como não foi especificado se é a amostral ou populacional, escolho o desvio padrão populacional (fórmula mais direta) — isto é,
Observação: se a prova pedir amostral, a fórmula é com (n-1) no denominador; aqui uso n.
Mediana: após ordenar os n valores (em ordem crescente), se n for ímpar a mediana é o elemento do meio; se n for par a mediana é a média dos dois elementos centrais. Em termos de índices (0‑based): elemento central é o índice (n-1)/2 quando n é ímpar; quando n é par usamos a média de a[n/2 - 1] e a[n/2].
Moda: para números reais podem existir empates na frequência. Vou definir a política de desempate: retornar o menor valor (em sentido numérico) entre os que têm maior frequência. Como trabalhar com números reais pode ter problemas de igualdade por precisão, assumo que os valores no vetor são comparáveis com igualdade direta (ou seja, valores exatamente iguais). Essa é uma escolha habitual em exercícios que trabalham com arrays de reais vindos de entrada exata.
Número de elementos repetidos: a expressão é ambígua. Vou adotar esta definição (e explicá‑la): o número de elementos que fazem parte de grupos com frequência maior que 1, contando todas as ocorrências. Exemplo: para (1,1,1,2,3,3) o retorno será 5 (porque existem três ocorrências de 1 e duas de 3, totalizando 5 elementos que são repetidos). Se preferir a outra interpretação (número de valores distintos que se repetem — aqui seria 2 para o mesmo exemplo), dá para ajustar facilmente.
Tratamento de casos inválidos: se n \le 0, as funções que retornam número real (média, desvio, mediana, moda) retornarão NAN (valor especial de math.h) para indicar resultado indefinido; soma retorna 0 para conveniência; contagem de repetidos retorna 0.
Passo 3
Explicação detalhada e algoritmo para cada função (passo a passo para entender e poder reproduzir na prova):
Soma
Fórmula: \displaystyle S=\sum_{i=1}^{n} x_i.
Algoritmo: somar iterativamente cada elemento num acumulador s.
Complexidade: O(n).
Média
Fórmula já dada: \bar{x} = \dfrac{S}{n}, onde S é a soma.
Implementação prática: reaproveitar a função soma para calcular \bar{x}.
Implementação prática (duas passagens, estável o suficiente para provas):
Passo A: calcular \bar{x}.
Passo B: somar (x_i - \bar{x})^2 para todos i.
Passo C: dividir por n e tirar raiz quadrada.
Complexidade: O(n).
Mediana
Procedimento:
Fazer uma cópia do vetor e ordenar essa cópia em ordem crescente.
Se n é ímpar, retornar o valor central.
Se n é par, retornar a média dos dois centrais.
Observação: copiar o vetor garante que a função não altere a entrada original.
Moda
Procedimento eficiente após ordenação:
Ordenar o vetor copiado.
Passar pelo vetor contando frequência máxima maxfreq e o valor ligado a essa frequência mode.
Como o vetor está ordenado em ordem crescente, o primeiro valor que alcançar maxfreq será o menor entre empates — isso implementa nossa política de desempate.
Complexidade: ordenação domina, O(n\log n).
Número de elementos repetidos (minha definição escolhida)
Após ordenar a cópia:
Percorrer a cópia identificando blocos de valores iguais; para cada bloco com frequência f > 1, somar f ao contador de repetidos.
copy_and_sort: aloca (com malloc) uma cópia do vetor original, copia os conteúdos e chama qsort nela. Retorna ponteiro para cópia ordenada (ou NULL se erro).
Essas auxiliares ajudam a manter cada função pequena e legível.
Gestão de memória:
Funções que chamam copy_and_sort liberam a cópia com free antes de retornar.
Em caso de falha de alocação, algumas funções retornam NAN ou um valor de erro (-1 para contagem, embora eu prefira 0 ou NAN como documentado).
Complexidade final:
Soma/média/desvio: O(n).
Mediana/moda/contagem repetidos: O(n\log n) por causa da ordenação.
Passo 5
Exemplos pequenos para fixar (conceito — aqui só para treinar mentalmente, sem código):
Vetor: (2, 1, 4, 2, 3), n=5
Soma: 2+1+4+2+3 = 12.
Média: \bar{x} = 12/5 = 2,4.
Ordenado: (1,2,2,3,4)
Mediana: elemento central = 2.
Moda: 2 (frequência 2).
Repetidos: grupo 2 tem frequência 2 → repetidos = 2.
Vetor: (1,1,1,2,3,3), n=6
Repetidos = 3 (do valor 1) + 2 (do valor 3) = 5.
Moda = 1 (freq 3).
Passo 6
Pronto para o código: a seguir eu criei as funções conforme explicado. Elas usam double para valores reais, int para tamanho, qsort para ordenação e math.h para sqrt e NAN. Incluí também um main de exemplo que demonstra o uso de todas as funções.
Resposta
#include<stdio.h>#include<stdlib.h>#include<string.h>#include<math.h>/* Comparador para qsort (ordem crescente) */staticintcmp_double(constvoid *a, constvoid *b) {
double da = *(constdouble*)a;
double db = *(constdouble*)b;
if (da < db) return-1;
if (da > db) return1;
return0;
}
/* Cria uma cópia ordenada do vetor v (retorna ponteiro alocado ou NULL em erro).
O chamador deve liberar com free(). */staticdouble *copy_and_sort(constdouble *v, int n) {
if (n <= 0) returnNULL;
double *c = (double*) malloc((size_t)n * sizeof(double));
if (!c) returnNULL;
memcpy(c, v, (size_t)n * sizeof(double));
qsort(c, (size_t)n, sizeof(double), cmp_double);
return c;
}
/* Soma dos elementos */doublesoma(constdouble *v, int n) {
if (n <= 0) return0.0;
double s = 0.0;
for (int i = 0; i < n; ++i) s += v[i];
return s;
}
/* Média aritmética: retorna NAN se n <= 0 */doublemedia(constdouble *v, int n) {
if (n <= 0) return NAN;
double s = soma(v, n);
return s / (double)n;
}
/* Desvio padrão populacional: retorna NAN se n <= 0 */doubledesvio_padrao(constdouble *v, int n) {
if (n <= 0) return NAN;
double mu = media(v, n);
double ssd = 0.0; /* soma dos quadrados das diferenças */for (int i = 0; i < n; ++i) {
double d = v[i] - mu;
ssd += d * d;
}
double var = ssd / (double)n;
if (var < 0 && var > -1e-15) var = 0.0; /* proteção numérica */returnsqrt(var);
}
/* Número de elementos repetidos (minha definição: conta todas as ocorrências
que pertencem a valores com frequência > 1).
Ex.: (1,1,1,2,3,3) -> retorna 5.
Retorna 0 se n <= 0. */intnumero_elementos_repetidos(constdouble *v, int n) {
if (n <= 0) return0;
double *a = copy_and_sort(v, n);
if (!a) return0; /* em caso de falha de alocação, devolve 0 */int count = 0;
int i = 0;
while (i < n) {
int j = i + 1;
while (j < n && a[j] == a[i]) ++j;
int freq = j - i;
if (freq > 1) count += freq;
i = j;
}
free(a);
return count;
}
/* Mediana: retorna NAN se n <= 0.
Se n ímpar, retorna o valor do meio; se par, retorna a média dos dois do meio. */doublemediana(constdouble *v, int n) {
if (n <= 0) return NAN;
double *a = copy_and_sort(v, n);
if (!a) return NAN;
double med;
if (n % 2 == 1) {
med = a[(n - 1) / 2];
} else {
med = (a[n/2 - 1] + a[n/2]) / 2.0;
}
free(a);
return med;
}
/* Moda: retorna o valor (double) com maior frequência.
Em caso de empate, retorna o menor valor (política definida).
Retorna NAN se n <= 0. */doublemoda(constdouble *v, int n) {
if (n <= 0) return NAN;
double *a = copy_and_sort(v, n);
if (!a) return NAN;
double best_val = a[0];
int best_freq = 1;
int i = 0;
while (i < n) {
int j = i + 1;
while (j < n && a[j] == a[i]) ++j;
int freq = j - i;
if (freq > best_freq) {
best_freq = freq;
best_val = a[i];
}
/* se freq == best_freq não atualizamos: mantendo o primeiro (menor) valor */
i = j;
}
free(a);
return best_val;
}
/* Exemplo de uso */intmain(void) {
double v[] = {2.0, 1.0, 4.0, 2.0, 3.0};
int n = (int)(sizeof(v)/sizeof(v[0]));
printf("Vetor: ");
for (int i = 0; i < n; ++i) printf("%g ", v[i]);
printf("\n");
printf("Soma: %g\n", soma(v, n));
printf("Media: %g\n", media(v, n));
printf("Desvio padrao: %g\n", desvio_padrao(v, n));
printf("Numero de elementos repetidos: %d\n", numero_elementos_repetidos(v, n));
printf("Mediana: %g\n", mediana(v, n));
printf("Moda: %g\n", moda(v, n));
return0;
}