2013-02-15 9 views
2

Мне нужно преобразовать массив чисел и итогов в простой оператор.Как я могу упростить процент (например, 25%) до простого утверждения (например, 1 из 4)?

Например, как можно преобразовать следующее, программно с помощью PHP, простых утверждений, как, 1 out of 10, 1 out of 100, и даже округление некоторые (например, 2 out of 100 для 9000,400000).

Создать образец массива:

$arr = array(); 
for ($i=0; $i < 100; $i++) { 
    $n = mt_rand(1,1000); 
    $t = mt_rand(10,100000); 
    if ($n > $t) continue; // skip! 
    $arr[] = array($n,$t); 
} 
/* 
// Generates pairs like: 
// Array 
// (
//  [0] => Array ([0] => 55 [1] => 8774 ) 
//  [1] => Array ([0] => 814 [1] => 11174) 
//  [2] => Array ([0] => 255 [1] => 32168) 
//  ... 
//  [99] => Array ([0] => 851 [1] => 24231) 
//) 
*/ 

Запуск через функции и печати упрощенных результатов:

foreach ($arr as $a) { 
    echo $a[0] . '/' . $a[1] . ' ==> ' . simplifyRatio($a[0],$a[1]) . "\r\n"; 
} 

Можете ли вы мне точку в правильном направлении, о том, как это сделать?

Вот начало функции, над которой я работаю, но решение ускользает от меня.

function simplifyRatio($n,$t) { 
    $p = $n/$t; 
    if ($p > 0.09) return round($n) . ' out of ' . round($t); 
    if ($p > 0.009) return round($n) . ' out of ' . round($t); 
} 

В идеале знаменатель должен быть: 1,2,3...10,20,30...100,200,300...1000,2000,3000...10000,20000,30000...100000 (max)

+0

Вам необходимо выполнить условия, в которых у вас будет более 100%? – Jrod

ответ

0

я осела на ближайшем матче по образцу 1 out of ___, например, так:

function simplifyRatio($n,$t) { 
    $r = $t/$n; 
    return '1 out of ' . round($r); 
} 

// Examples: 
$arr = array(); 
for ($i=0; $i < 100; $i++) { 
    $n = mt_rand(1,1000); 
    $t = mt_rand(10,100000); 
    if ($n > $t) continue; // skip! 
    $arr[] = array($n,$t); 
} 
foreach ($arr as $a) { 
    echo $a[0] . '/' . $a[1] . ' ==> ' . simplifyRatio($a[0],$a[1]) . "\r\n"; 
} 

Пример Результат:

1000/24819 ==> 1 out of 25 
309/50305 ==> 1 out of 163 
488/99123 ==> 1 out of 203 
322/47610 ==> 1 out of 148 
183/54287 ==> 1 out of 297 
752/67646 ==> 1 out of 90 
240/68854 ==> 1 out of 287 
301/81345 ==> 1 out of 270 
611/16404 ==> 1 out of 27 
522/62992 ==> 1 out of 121 

CodePad: http://codepad.org/wu6iOdDq

Вначале я надеялся, что в итоге появятся округлые знаменатели (10,20 ... 100,200 ... 1000,2000 и т. Д.), Но я не знаю, как это сделать. Я с радостью пожалую ответ, который очистит знаменателей выше.

1

Предполагая, что всегда процент. Вы также можете sprintf$outof перед отображением

function convertPercent($iPercent) 
{ 
    // Assume validation on $iPercent 
    $outof = round(100/$iPercent); 
    return "1 out of $outof"; 
} 
1

Для простоты я предположим, что вы можете получить свой процент во фракции (т.е. 25% - 25/100, 0,7% = 7/1000 и т. Д.).

Вы можете использовать алгоритм Евклида, чтобы найти НОД числитель и знаменатель: http://en.wikipedia.org/wiki/Euclidean_algorithm

В РНР было бы выглядеть примерно так:

function gcd ($int1, $int2) { 
    $tmp = 0; 
    while ($int1 > 0) { 
     $tmp = $int1; 
     $int1 = $int2 % $int1; 
     $int2 = $tmp; 
    } 
    return $int2; 
} 

Это будет работать до тех пор, как $ int1 и $ int2 являются целыми числами, превышающими 0 (вы можете захотеть добавить некоторую логику для обеспечения этого). Если вам нужны отрицательные числа, просто возьмите абсолютное значение.

Зная НОД, это легко понять, остальное:

function reduce($numerator, $denominator) { 
    $gcd = gcd($numerator, $denominator); 
    echo ($numerator/$gcd) . " out of " . ($denominator/$gcd); 
} 
echo reduce(4, 8).'<br>'; // 1 out of 2 
echo reduce(38, 897).'<br>'; // 38 out of 897 
echo reduce(39, 26).'<br>'; // 3 out of 2 

Надеется, что это помогает!