테스트 사이트 - 개발 중인 베타 버전입니다

중간값 구하기

아래의 문제의 답을 도출하는 과정을 프로그래밍 언어로 구현하시오.(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개

이문제는 소트프로그램을 만들라는 거군요
<?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);

?>
491
진행 시간 : 0.05 seconds
// 계수 정렬(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)];
}
제 것 보다 훨씬 좋네요. ^^

수고하셨습니다.
굳이 세번째 루프 까지 갈필요는 없어 보입니다.

// 계수 정렬(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)];
}

잘 배웠습니다.
// 제 소스보다 훨씬 빠르군요. 대단하십니다.
// 유창화님 소스에서 중간값이 나오면 루프를 더 돌지 않고 값을 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];

}
}

}
}
네 ㅎㅎ
이게 정답이네요.
수고하셧습니다. ^^
감사합니다.
유창화님 차려놓은 밥상에 숱가락만 언졌습니댜. ^^
너무나도 좋은 답변들 너무 감사합니다!!

두분의 깔끔한 정리 ~ 너무 좋습니다!

게시글 목록

번호 제목
5340
5327
5323
5308
5303
5302
5299
5296
5284
5267
5248
5231
5193
5179
5164
5130
5120
5102
5055
4999
4998
4990
4947
4926
4898
4884
4864
4863
4850
4824