2011-12-16 33 views
2

我想標記一些趨勢,所以我有1作爲最低值,5作爲最大值。如何根據某些值定義趨勢?

因此,例如,

我可能有以下情況:

5,4,5,5 (UP) 
3,4,  (UP) 
4,3,3  (DOWN) 
4,4,4,4, (FLAT - this is OK for all same numbers) 

我打算訂購的值作爲輸入,無限數量的爲輸出我將只顯示一個(UP ),(DOWN)或(FLAT)圖像。

關於我如何實現這一點的任何想法?

對不起,如果我不夠描述。

謝謝大家。

+0

好像你到底要循環,直到你找到一個更大(DOWN)或更小(UP)的數字。如果到達字符串的開頭而沒有結果,則顯示FLAT。 – kapa 2011-12-16 08:54:29

回答

0

我不知道如果我完全理解你的問題,但我會把值在數組中,並使用這樣的代碼(寫在僞代碼):

int i = 0; 
    String trend = "FLAT": 
    while(i<length(array)) { 
     if(array(i)<array(i+1)) { 
      trend = "UP"; 
     } 
     else if(array(i)>array(i+1) { 
      trend = "DOWN"; 
     } 
     i++; 
    } 

編輯:這顯然只顯示最新的變化趨勢 一會也可能遞減計數次數的趨勢是向上或並確定整體趨勢由值

+0

此代碼將總是基於數組的最後兩項決定。 – kapa 2011-12-16 08:59:30

0

對於你的例子:

  • 計算最長遞增子,A
  • Calulate最長遞減子序列,B

由你的邏輯去,如果A的長度大於B,其一個較大的UP,DOWN別的。 您還需要使用一個布爾變量來跟蹤所有等於標記FLAT趨勢。

查詢: 會是什麼趨勢:

3,4,5,4,3 ? 
3,4,4,4,3 ? 
1,2,3,4,4,3,2,2,1 ? 

那麼邏輯可能需要一些改變,這取決於你的需求是什麼。

2

一點點硬根據您提供的有限信息來回答,但假設:

  • 如果有一個在所有的趨勢沒有運動是平的,
  • 否則,趨勢是最後的方向運動,

那麼這段代碼應該工作:

$input = array(); 

$previousValue = false; 
$trend = 'FLAT'; 

foreach($input as $currentValue) { 
    if($previousValue !== false) { 
     if($currentValue > $previousValue) { 
      $trend = 'UP'; 
     } elseif($currentValue < $previousValue) { 
      $trend = 'DOWN'; 
     } 
    } 
    $previousValue = $currentValue; 
} 
+0

該解決方案可以正常工作,但爲了獲得更準確的結果,我添加了一個額外的檢查,以確定之前的值沒有變化。 – paj 2014-05-28 13:42:50

0
echo foo(array(5,4,5,5)); // UP 
echo foo(array(3,4)); // UP 
echo foo(array(4,3,3)); // DOWN 
echo foo(array(4,4,4,4)); // FLAT 

function foo($seq) 
{ 
    if (count(array_unique($seq)) === 1) 
     return 'FLAT'; 

    $trend = NULL; 
    $count = count($seq); 
    $prev = $seq[0]; 
    for ($i = 1; $i < $count; $i++) 
    { 
     if ($prev < $seq[$i]) 
     { 
      $trend = 'UP'; 
     } 
     if ($prev > $seq[$i]) 
     { 
      $trend = 'DOWN'; 
     } 
     $prev = $seq[$i]; 
    } 

    return $trend; 
} 
3

使用最小二乘法擬合來計算值的「斜率」。

function leastSquareFit(array $values) { 
    $x_sum = array_sum(array_keys($values)); 
    $y_sum = array_sum($values); 
    $meanX = $x_sum/count($values); 
    $meanY = $y_sum/count($values); 
    // calculate sums 
    $mBase = $mDivisor = 0.0; 
    foreach($values as $i => $value) { 
     $mBase += ($i - $meanX) * ($value - $meanY); 
     $mDivisor += ($i - $meanX) * ($i - $meanX); 
    } 

    // calculate slope 
    $slope = $mBase/$mDivisor; 
    return $slope; 
} // function leastSquareFit() 

$trend = leastSquareFit(array(5,4,5,5)); 

(未測試)

如果斜率是正的,趨勢是向上;如果是負面的,則向下。根據您自己的判斷來決定哪些保證金(正面或負面)被視爲持平。

0

我使用@liquorvicar的代碼,以確定谷歌搜索頁面排名的趨勢,但增加了一些額外的趨勢值,使之更準確:

NOCHANGE - 沒有變化

較好(較高的谷歌位置較低=數)

惡化(下谷歌位置=高數)

我還添加了額外的檢查時,最後一個值沒有變化,但考慮帳戶以前的變化,即

worsenochange(無變化,previouse更糟 - 較小的數字)

betternochange(無變化,previouse較好 - 較小的數字)

我用這些值顯示的範圍的趨勢圖標:

$_trendIndicator="<img title="trend" width="16" src="/include/main/images/trend-'. $this->getTrend($_positions). '-icon.png">"; 

example of trend icons

private function getTrend($_positions) 
{ 
    // calculate trend based on last value 
    // 
    $_previousValue = false; 
    $_trend = 'nochange'; 

    foreach($_positions as $_currentValue) { 

     if($_previousValue !== false) { 

      if($_currentValue > $_previousValue) { 
       $_trend = 'better'; 
      } elseif($_currentValue < $_previousValue) { 
       $_trend = 'worse'; 
      } 

      if ($_trend==='worse' && ($_previousValue == $_currentValue)) {$_trend = 'worsenochange';} 

      if ($_trend==='better' && ($_previousValue == $_currentValue)) {$_trend = 'betternochange';} 
     } 

     $_previousValue = $_currentValue; 
    } 

    return $_trend; 
}