2013-05-17 64 views
2

給定一個層次結構(如輪廓),其中每個層次都由一個整數表示(例如,第一個層次爲0,第二個層次爲1,並且任何時候您都可以在較早的層次上開始一個新點),則I想要重新分配整數,以便數字不會被跳過,但同時要尊重原始關係。我已經表示的輸入作爲數組:如何用遞歸重新賦值?

$stuff = array(0,1,2,2,4,1,9,9,10,3,8,4);

和(當被表示爲陣列)所期望的輸出是:

$stuff = array(0,1,2,2,3,1,2,2,3,2,3,3);

規則是:

  • 如果給定值與最接近的先前值相同,則輸出值應該與最接近的之前的輸出值相同
  • 如果給定值比最近的先前值更高(即更深),那麼輸出值應該大於最接近的前一個輸出值的值
  • 如果給定值比最近的值更低(即更淺)之前的值,然後找到最接近的先前值小於給定值,並且輸出值應該比那個值大1。

我認爲這樣做的唯一方法是通過遞歸。除了上述輸入數組中的最後一種情況外,我可以爲它工作。如果我將輸入數組中的最後一個案例更改爲「5」而不是「4」,那麼它將起作用。

這裏就是我想:

<?php 

$input = array(0,1,2,2,4,1,9,9,10,3,8,4); 
$debug = false; 
for ($i =0; $i < count($input); $i++) { 
    if ($debug) { 
     echo '<hr />Old level: '.$input[$i]; 
     $newLevel = newLevel($input,$i,$input[$i],$debug); 
     echo '<br />New level: '.$newLevel.'<br /><br /><br /><hr />'; 
    } 
    else { 
     echo 'Old level: '.$input[$i].'; New level: '.newLevel($input,$i,$input[$i],$debug).'<br />'; 
    } 
} 

function newLevel($input, $index,$origValue,$debug) { 
    if ($index == 0) return 0; 
    else { 
     if ($input[$index] > $input[$index-1]) { 
      if ($debug) echo '<br />Orig value: '.$origValue.' in else/if'; 
      return newLevel($input,$index-1,$origValue,$debug)+1; 
     } 
     elseif ($input[$index] == $input[$index-1]) { 
      if ($debug) echo '<br />Orig value: '.$origValue.' in else/elseif1'; 
      return newLevel($input,$index-1,$origValue,$debug); 
     } 
     elseif ($input[$index] < $input[$index-1]) { 
      for ($i = $index-2; $i >= 0; $i--) { 
       if ($input[$index] == $input[$i]) { 
        if ($debug) echo '<br />Orig value: '.$origValue.' in else/elseif2/for/if'; 
        return newLevel($input,$i,$origValue,$debug); 
       } 
       elseif ($input[$index] == ($input[$i] + 1)) { 
        if ($debug) echo '<br />Orig value: '.$origValue.' in else/elseif2/for/elseif'; 
        return newLevel($input,$i,$origValue,$debug); 
       } 
      } 
       die ("Error with going to outer level -- should never hit this."); 
     } 
    } 
} 

?> 

這是我想要的輸出:

Old level: 0; New level: 0 
Old level: 1; New level: 1 
Old level: 2; New level: 2 
Old level: 2; New level: 2 
Old level: 4; New level: 3 
Old level: 1; New level: 1 
Old level: 9; New level: 2 
Old level: 9; New level: 2 
Old level: 10; New level: 3 
Old level: 3; New level: 2 
Old level: 8; New level: 3 
Old level: 4; New level: 3 

但我得到的輸出有一個「2」最後的新水平線。任何幫助非常感謝它。

+0

我相當肯定最後一種情況下可以分解爲'分鐘(prior_new_level,current_old_level)' –

回答

3

其實,你根本不需要遞歸。你在不使用遞歸的情況下很好地解釋了你的算法,所以你的代碼也不需要它。

這是我的算法版本,沒有遞歸。

$original = array(0,1,2,2,4,1,9,9,10,3,8,4); 
$revised = array(); 

foreach($original as $index=>$value) { 
    $output = 0; 
    $previous = false; 

    if ($index > 0) 
     $previous = $original[$index-1]; 

    if ($previous === false) 
     $output = 0; 
    else if ($value == $previous) 
     $output = $revised[$index-1]; 
    else if ($value > $previous) 
     $output = $revised[$index-1] + 1; 
    else { 
     $output = 1; // worst case scenario 
     for($rindex = $index-1; $rindex >= 0; $rindex--) { 
      if ($value > $original[$rindex]) { 
       $output = $revised[$rindex]+1; 
       break; 
      } 
     } 
    } 

    $revised[] = $output; 
} 

echo "\n"; 
print_r($original); 
print_r($revised); 
+0

這看起來正確的第一眼。 +1來回答另一個遞歸問題(儘管這不是真正的遞歸)。 –

+0

對於有效的答案+1。但是我想找到一個遞歸解決方案的原因是我需要能夠以一種不允許在實例化之後重新分配變量的語言來執行此操作(因爲語言不允許副作用)。我的計劃是用PHP解決這個問題,因爲這是我更強大的語言,然後將它移植到其他語言。最好的計劃......如果你能幫忙找出遞歸解決方案,我將不勝感激。 – user2379780

+0

使用遞歸不能解決您的不變性問題。您一次只能計算出答案中的一個元素,並且必須將現有數組擴展一個,或者將該值分配給以前分配的元素。在Java中,你可能用'int [] revised = new int [original.length];'初始化你的輸出數組,然後用'revised [index] = output;'賦值新的值。我向你保證,每種語言都會有某種構造支持你在這裏需要做的事情。 – slashingweapon