중간값 구하기 정보
중간값 구하기
본문
아래의 문제의 답을 도출하는 과정을 프로그래밍 언어로 구현하시오.(php, javascript... 뭐든 좋습니다)
숫자 n 개(중복숫자 가능)를 제시했을 때, 그걸 오름차순으로 정렬했을 때, 한 가운데 오는 숫자를 중간값이라고 정의하겠습니다.
홀수개의 숫자를 제시한 경우
3,2,7,8,6 -> 이와 같이 제시한 경우 오름차순으로 정리하면 2,3,6,7,8 이 되기에 중간값은 6 이 됩니다.
짝수개의 숫자를 제시한 경우
4,5,7,8,3,4 -> 오름차순으로 정리하면 3,4,4,5,7,8 로 정확히 중간이 없으므로 이때는 2개의 중간값중 작은 숫자를 중간값으로 합니다 따라서 4가 중간값이 됩니다.
n 개 (1 <= n <= 1000) 의 1000보다 작은 자연수를 제시했을 때, 그 중간값을 구하시오.
단, php 에서 제공하는 막강한 array sort 관련 함수를 안쓰고 풀어보면 어떨까요. 당연히 sort 함수를 쓰면 훨씬 쉽겠죠..
아래는 그 함수의 일부입니다. 나머지를 채워서 함수를 완성하시오.
$numarray = array(91,23,36,73,........,863); // 자연수를 가지고 있는 배열
// 1 <= count($numarray) <= 1000 입니다.
function get_middle($numarray){
return $mid; // 중간값 출력
}
댓글 10개

이문제는 소트프로그램을 만들라는 거군요
-
채택 0

<?php
set_time_limit(0);
//ini_set('memory_limit','1G');
header('Content-Type: text/html; charset=utf-8');
function microtime_float() {
list($usec, $sec) = explode(" ", microtime());
return (((float)substr((string)$usec, 0, 4) + (float)$sec)) * 1000;
}
function get_excute_time($msg, $start_time){
$end_time = microtime_float();
$time = ($end_time - $start_time) / 1000;
echo "$msg : $time seconds" . PHP_EOL ;
}
$input = 1000;
//임의의 $input 이하의 숫자 $input개 뽑음
$numbers = Array();
while(1) {
if (count($numbers) == $input)
break;
$numbers[] = rand(1, $input);
}
//print_r($numbers);
//echo PHP_EOL;
$start_time = microtime_float();
$result_low = $result_high = Array();
while(1){
$min = 999999999;
$x = 999999999;
$max = 0;
$y = 999999999;
foreach($numbers as $k => $v){
if ($v < $min) {
$min = $v;
$x = $k;
}
if ($v > $max) {
$max = $v;
$y = $k;
}
}
if ($min != 999999999 && $min > 0) {
$result_low[] = $min;
unset($numbers[$x]);
}
if ($max != 0 && $max > 0 && $x != $y) {
$result_high[] = $max;
unset($numbers[$y]);
}
if (count($numbers) == 0)
break;
}
$result = $result_low;
$high_cnt = count($result_high);
for ($i = $high_cnt - 1; $i >= 0; $i--) {
$result[] = $result_high[$i];
}
//print_r($result);
//echo PHP_EOL;
$cnt = count($result);
if ($cnt % 2 == 0) {//짝수
echo $result[$cnt / 2 - 1];
}
else {//홀수
echo $result[floor($cnt / 2)];
}
echo PHP_EOL;
get_excute_time("진행 시간", $start_time);
?>
set_time_limit(0);
//ini_set('memory_limit','1G');
header('Content-Type: text/html; charset=utf-8');
function microtime_float() {
list($usec, $sec) = explode(" ", microtime());
return (((float)substr((string)$usec, 0, 4) + (float)$sec)) * 1000;
}
function get_excute_time($msg, $start_time){
$end_time = microtime_float();
$time = ($end_time - $start_time) / 1000;
echo "$msg : $time seconds" . PHP_EOL ;
}
$input = 1000;
//임의의 $input 이하의 숫자 $input개 뽑음
$numbers = Array();
while(1) {
if (count($numbers) == $input)
break;
$numbers[] = rand(1, $input);
}
//print_r($numbers);
//echo PHP_EOL;
$start_time = microtime_float();
$result_low = $result_high = Array();
while(1){
$min = 999999999;
$x = 999999999;
$max = 0;
$y = 999999999;
foreach($numbers as $k => $v){
if ($v < $min) {
$min = $v;
$x = $k;
}
if ($v > $max) {
$max = $v;
$y = $k;
}
}
if ($min != 999999999 && $min > 0) {
$result_low[] = $min;
unset($numbers[$x]);
}
if ($max != 0 && $max > 0 && $x != $y) {
$result_high[] = $max;
unset($numbers[$y]);
}
if (count($numbers) == 0)
break;
}
$result = $result_low;
$high_cnt = count($result_high);
for ($i = $high_cnt - 1; $i >= 0; $i--) {
$result[] = $result_high[$i];
}
//print_r($result);
//echo PHP_EOL;
$cnt = count($result);
if ($cnt % 2 == 0) {//짝수
echo $result[$cnt / 2 - 1];
}
else {//홀수
echo $result[floor($cnt / 2)];
}
echo PHP_EOL;
get_excute_time("진행 시간", $start_time);
?>
-
채택 0

491
진행 시간 : 0.05 seconds
진행 시간 : 0.05 seconds
-
채택 0
// 계수 정렬(Counting Sort) 알고리즘 적용
function get_middle($arrNum){
$count = array();
$max = - 1;
$cnt = 0;
foreach ($arrNum as $k => $v) {
if ($max < $v) $max = $v;
$count[$v]++;
$cnt++;
}
for ($i = 1; $i <= $max; $i++)
$count[$i] += $count[$i - 1];
$result = array();
for ($i = $cnt -1; $i >= 0; $i--)
$result[--$count[$arrNum[$i]]] = $arrNum[$i];
return $result[ceil($cnt / 2 - 1)];
}
function get_middle($arrNum){
$count = array();
$max = - 1;
$cnt = 0;
foreach ($arrNum as $k => $v) {
if ($max < $v) $max = $v;
$count[$v]++;
$cnt++;
}
for ($i = 1; $i <= $max; $i++)
$count[$i] += $count[$i - 1];
$result = array();
for ($i = $cnt -1; $i >= 0; $i--)
$result[--$count[$arrNum[$i]]] = $arrNum[$i];
return $result[ceil($cnt / 2 - 1)];
}
-
채택 0

제 것 보다 훨씬 좋네요. ^^
수고하셨습니다.
수고하셨습니다.
-
채택 0

굳이 세번째 루프 까지 갈필요는 없어 보입니다.
// 계수 정렬(Counting Sort) 알고리즘 적용
function get_middle($numbers){
$result = $count = array();
$max = - 1;
$min = null;
foreach ($numbers as $k => $v) {
if ($max < $v)
$max = $v;
if (is_null($min) || $min > $v)
$min = $v;
$count[$v] = (isset($count[$v])) ? $count[$v] + 1 : 1;
}
for ($i = $min; $i <= $max; $i++) {
if (isset($count[$i]) && $count[$i] > 0) {
for ($j = 0; $j < $count[$i]; $j++) {
$result[] = $i;
}
}
}
return $result[ceil($cnt / 2 - 1)];
}
잘 배웠습니다.
// 계수 정렬(Counting Sort) 알고리즘 적용
function get_middle($numbers){
$result = $count = array();
$max = - 1;
$min = null;
foreach ($numbers as $k => $v) {
if ($max < $v)
$max = $v;
if (is_null($min) || $min > $v)
$min = $v;
$count[$v] = (isset($count[$v])) ? $count[$v] + 1 : 1;
}
for ($i = $min; $i <= $max; $i++) {
if (isset($count[$i]) && $count[$i] > 0) {
for ($j = 0; $j < $count[$i]; $j++) {
$result[] = $i;
}
}
}
return $result[ceil($cnt / 2 - 1)];
}
잘 배웠습니다.
-
채택 0
// 제 소스보다 훨씬 빠르군요. 대단하십니다.
// 유창화님 소스에서 중간값이 나오면 루프를 더 돌지 않고 값을 return 하도록 수정해 보았습니댜.
function get_middle($numbers){
$result = $count = array();
$max = - 1;
$min = null;
$cnt = 0;
foreach ($numbers as $k => $v) {
$cnt++;
if ($max < $v)
$max = $v;
if (is_null($min) || $min > $v)
$min = $v;
$count[$v] = (isset($count[$v])) ? $count[$v] + 1 : 1;
}
$mid = ceil($cnt / 2 - 1);
for ($i = $min; $i <= $max; $i++) {
if (isset($count[$i]) && $count[$i] > 0) {
for ($j = 0; $j < $count[$i]; $j++) {
$result[] = $i;
if (isset($result[$mid])) return $result[$mid];
}
}
}
}
// 유창화님 소스에서 중간값이 나오면 루프를 더 돌지 않고 값을 return 하도록 수정해 보았습니댜.
function get_middle($numbers){
$result = $count = array();
$max = - 1;
$min = null;
$cnt = 0;
foreach ($numbers as $k => $v) {
$cnt++;
if ($max < $v)
$max = $v;
if (is_null($min) || $min > $v)
$min = $v;
$count[$v] = (isset($count[$v])) ? $count[$v] + 1 : 1;
}
$mid = ceil($cnt / 2 - 1);
for ($i = $min; $i <= $max; $i++) {
if (isset($count[$i]) && $count[$i] > 0) {
for ($j = 0; $j < $count[$i]; $j++) {
$result[] = $i;
if (isset($result[$mid])) return $result[$mid];
}
}
}
}
-
채택 0

네 ㅎㅎ
이게 정답이네요.
수고하셧습니다. ^^
이게 정답이네요.
수고하셧습니다. ^^
-
채택 0
감사합니다.
유창화님 차려놓은 밥상에 숱가락만 언졌습니댜. ^^
유창화님 차려놓은 밥상에 숱가락만 언졌습니댜. ^^
-
채택 0

너무나도 좋은 답변들 너무 감사합니다!!
두분의 깔끔한 정리 ~ 너무 좋습니다!
두분의 깔끔한 정리 ~ 너무 좋습니다!
-
채택 0