statistics - syc - porque en latinoamerica no se pronuncia la z
Encontrar la media del conjunto de ints (8)
Bienvenido. pescado, espero que su estancia sea agradable.
El siguiente pseudocódigo muestra cómo hacerlo en el caso en que la suma se ajuste dentro de un tipo de entero, y redondea al entero más cercano.
En su muestra, los números suman suma a 16, dividiendo por 3 le da 5 1/3, que redondea a 5.
sum = 0
for i = 1 to array.size
sum = sum + array[i]
sum = sum / array.size
sum = round (sum)
Supongamos que tiene una matriz de int (en cualquier idioma con tamaño fijo). ¿Cómo calcularías el int más cercano a su media?
Editar: para que quede claro, el resultado no tiene que estar presente en la matriz. Es decir, para la matriz de entrada [3, 6, 7] el resultado esperado es 5. También supongo que necesitamos especificar una dirección de redondeo particular, por lo tanto, redondee hacia abajo si está igualmente cerca de dos números.
Editar: Esto no es tarea. No he tenido tarea en cinco años. Y esta es mi primera vez en stackoverflow, así que por favor se agradable!
Editar: El enfoque obvio de resumir y dividir puede desbordarse, así que estoy tratando de pensar que un enfoque que sea desbordante sea seguro, tanto para arreglos grandes como para grandes. Creo que manejar el desbordamiento correctamente (sin hacer trampa y usar un tipo diferente) es, con mucho, la parte más difícil de este problema.
Calcule la suma sumando los números hacia arriba, y dividiendo por el número de ellos, con el redondeo:
mean = (int)((sum + length/2) / length;
Si le preocupa el desbordamiento, puede hacer algo como:
int mean = 0, remainder = 0
foreach n in number
mean += n / length
remainder += n % length
if remainder > length
mean += 1
remainder -= length
if remainder > length/2
mean += 1
print "mean is: " mean
tenga en cuenta que esto no es muy rápido.
Esta es una forma rápida, razonablemente desbordante de seguridad y que puede funcionar cuando la cantidad de elementos no se conoce de antemano.
// The length of someListOfNumbers doesn''t need to be known in advance.
int mean(SomeType someListOfNumbers) {
double mean = 0, count = 0;
foreach(element; someListOfNumbers) {
count++;
mean += (element - mean) / count;
}
if(count == 0) {
throw new UserIsAnIdiotException(
"Problem exists between keyboard and chair.");
}
return cast(int) floor(mean);
}
Este pseudocódigo encuentra el promedio y cubre el problema del desbordamiento:
double avg = 0
int count = 0
for x in array:
count += 1
avg = avg * (count - 1) / count // readjust old average
avg += x / count // add in new number
Después de eso, puede aplicar su código de redondeo. Si no hay una manera fácil de redondear en su idioma, entonces algo como esto funcionará (redondea cuando excede de .5):
int temp = avg - int(avg) // finds decimal portion
if temp <= 0.5
avg = int(avg) // round down
else
avg = int(avg) + 1 // round up
Garantizado para no desbordarse:
length ← length of list
average ← 0
for each result in the list do:
average ← average + ( result / length )
end for
Esto tiene problemas significativos con la precisión si estás usando ints debido al truncamiento (el promedio de seis 4''s sale como 0)
Montaje de ARM. =] No probado. No se desbordará Nunca. (Espero.)
Probablemente se pueda optimizar un poco. (¿Tal vez usar FP / LR?) = S Tal vez THUMB funcionará mejor aquí.
.arm
; r0 = pointer to array of integers
; r1 = number of integers in array
; returns mean in r0
mean:
stmfd sp!, {r4,r5}
mov r5, r1
mov r2, 0 ; sum_lo
mov r3, 0 ; sum_hi
cmp r1, 0 ; Check for empty array
bz .end
.loop:
ldr r4, [r0], #4
add r2, r2, r4
adc r3, r3, #0 ; Handle overflow
sub r1, r1, #1 ; Next
bnz .loop
.end:
div r0, r2, r3, r5 ; Your own 64-bit/32-bit divide: r0 = (r3r2) / r5
bx lr
Pseudocódigo para obtener el promedio :
double mean = 0
int count = 0
foreach int number in numbers
count++
mean += number - mean / count
round(mean) // rounds up
floor(mean + 0.5) // rounds up
ceil(mean - 0.5) // rounds down
El redondeo generalmente implica agregar 0.5, luego truncar (piso), por lo que 3.5 redondea hasta 4. Si desea que 3.5 redondee a 3, haga el código de redondeo usted mismo, pero en reversa: resta 0.5, luego encuentre el techo.
Editar: requisitos actualizados (sin desbordamiento)
um ... ¿qué hay de simplemente calcular la media y luego redondear a un número entero? round(mean(thearray))
La mayoría de los idiomas tienen instalaciones que le permiten especificar el método de redondeo.
EDITAR: Entonces, esta pregunta realmente trata sobre evitar el desbordamiento, no sobre el redondeo. Permítame dejar en claro que estoy de acuerdo con aquellos que han dicho (en los comentarios) que no es algo de lo que preocuparse en la práctica, ya que rara vez sucede, y cuando lo hace, siempre puede salirse con la suya usando un tipo de datos más grande.
Veo que muchas otras personas han dado respuestas que básicamente consisten en dividir cada número en la matriz por el recuento de la matriz y luego sumarlos. Ese también es un buen enfoque. Pero solo por diversión, aquí hay una alternativa (en pseudocódigo C-ish):
int sum_offset = 0;
for (int i = 1; i < length(array); i++)
sum_offset += array[i] - array[i-1];
// round by your method of choice
int mean_offset = round((float)sum_offset / length(array));
int mean = mean_offset + array[0];
O de otra manera de hacer lo mismo:
int min = INT_MAX, max = INT_MIN;
for (int i = 0; i < length(array); i++) {
if (array[i] < min) min = array[i];
if (array[i] > max) max = array[i];
}
int sum_offset = max - min;
// round by your method of choice
int mean_offset = round((float)sum_offset / length(array));
int mean = mean_offset + min;
Por supuesto, debe asegurarse de que sum_offset
no se desborde, lo que puede suceder si la diferencia entre los elementos de la matriz más grande y más pequeña es mayor que INT_MAX. En ese caso, reemplace las últimas cuatro líneas con algo como esto:
// round by your method of choice
int mean_offset = round((float)max / length(array) - (float)min / length(array));
int mean = mean_offset + min;
Trivia: este método, o algo así, también funciona bastante bien para calcular mentalmente la media de una matriz cuyos elementos se agrupan muy juntos.