2015-09-04 67 views
-1

我的程序假設計算我陣列中的數據從增加到減少的次數,反之亦然。例如:{1,2,3,4,3,4} 會隨着前四個元素增加而改變兩次,然後減少o 3(導致一次改變),然後再增加到四次,導致第二次改變。 在我的代碼中的想法是,每次大或小變爲false時,它會在發生時計數,但我無法使其工作。 任何幫助非常感謝,因爲我真的很困難!C++計算陣列中的數據更改方向的次數?

unsigned count = 0; 
bool greater = true; 
bool decrease = true; 
for (unsigned i = 0; i < elements; i++){ 
    if (a[i + 1] > a[i]){ 
     greater = true; 
    } 
    else 
     greater = false; 
    count++; 
} 
for (unsigned i = 0; i < elements; i++){ 
    if (a[i + 1] < a[i]){ 
     decrease = true; 
    } 
    else 
     decrease = false; 
    count++; 
} 
     return count; 
+0

試着將一個複雜的問題分解成更小的更容易的問題。例如你可以構造一個新的'bool'數組,它的條目告訴你原始數組是增加還是減少?如果你有這樣一個陣列,你能解決問題嗎? – Hurkyl

回答

1

你必須改變你的循環。首先,你應該停止大小爲1的循環。因爲你在比較下一個元素,如果你的for運行直到元素而不是元素-1,你可以跳出界限。

此外,你有一個邏輯問題。如果您使用布爾變量作爲標誌,則在增加計數器之前應檢查它是否爲真。如果你增加你的櫃檯,你必須重置該標誌。類似於下循環的東西應該可以工作。也許有一些小錯誤,因爲我現在沒有什麼可以測試的。但它應該與此類似。

for (unsigned i = 0; i < elements-1; i++){ 
    if (a[i + 1] > a[i]){ 
     greater = true; 
    } 
    else{ 
     greater = false; 
    } 
    if(greater){ 
     count++; 
     greater = false; 
    } 
} 
+1

不幸的是,當輸入數組{1,2,3,4,5}時,程序輸出它已經改變了4次,但是我們希望它在從增加變爲遞減時反之亦然,反之亦然價值觀的權利。 – Beezy

+0

在這種情況下,你應該改變if條件。但至少更改for頭,因爲你可能會崩潰你的應用程序;) – acostela

2

你的邏輯是錯誤的

你可以做這樣的事情

enum class EDirection { none, decreasing, increasing}; 

std::size_t count_direction_changes(const std::vector<int>& v) 
{ 
    std::size_t res = 0; 
    EDirection direction = EDirection::none; 

    for (std::size_t i = 1; i != v.size(); ++i) { 
     const int diff = v[i] - v[i - 1]; 
     switch (direction) 
     { 
      case EDirection::none: { 
       if (diff == 0) { 
        break; 
       } 
       direction = (diff > 0) ? EDirection::increasing : EDirection::decreasing; 
       break; 
      } 
      case EDirection::increasing: { 
       if (diff < 0) { 
        ++res; 
        direction = EDirection::decreasing; 
       } 
       break; 
      } 
      case EDirection::decreasing: { 
       if (diff > 0) { 
        ++res; 
        direction = EDirection::increasing; 
       } 
       break; 
      } 
     } 
    } 
    return res; 
} 

Demo

+0

只能用類來完成這項工作,或者你可以把它寫成普通函數嗎? – Beezy

+0

不知道你的意思是...它已經是一個免費的功能。你可以將'std :: vector'更改爲其他*範圍*。 – Jarod42

0

這是很多像Jarod42的,但看到我已經編碼會拋出它在那裏。順便說一句,我使用稍微尷尬的v[n] < v[n - 1],所以只需要實現operator<將算法應用到用戶定義類型(即不是operator>)。

#include <iostream> 
#include <vector> 

template <typename T> 
size_t changes(const std::vector<T>& v) 
{ 
    if (v.size() <= 2) return 0; 
    size_t count = 0; 
    enum { Increasing, Decreasing, Flat } last; 
    last = v[0] < v[1] ? Increasing : v[1] < v[0] ? Decreasing : Flat; 
    for (size_t i = 2; i < v.size(); ++i) 
     if (v[i - 1] < v[i]) 
     { 
      if (last == Decreasing) ++count; 
      last = Increasing; 
     } 
     else if (v[i] < v[i - 1]) 
     { 
      if (last == Increasing) ++count; 
      last = Decreasing; 
     } 
    return count; 
} 

int main() 
{ 
    std::cout << changes<int>({ 1, 3, 5, 4, 6 }) << '\n'; 
    std::cout << changes<int>({ 3, 3, 5, 4, 6 }) << '\n'; 
    std::cout << changes<int>({ 4, 3, 5, 4, 2, 2, 1 }) << '\n'; 
} 

看到它跑here

0

這裏是另一種方法,類似於託尼和賈羅德的:

#include <vector> 
#include <cassert> 
#include <iostream> 

size_t countTrendChanges(const std::vector<int>& a) { 
    if (a.size() < 3) 
    return 0; 

    int trend = 0; 
    size_t count = 0; 
    for (size_t i = 1; i != a.size(); ++i) { 
    int new_trend = (a[i-1] < a[i]) - (a[i] < a[i-1]); 
    if (new_trend == 0) 
     continue; 
    if (trend != 0 && new_trend != trend) 
     count++; 
    trend = new_trend; 
    } 
    return count; 
} 

int main() { 
assert(countTrendChanges({}) == 0); 
assert(countTrendChanges({1}) == 0); 
assert(countTrendChanges({3,2,1}) == 0); 
assert(countTrendChanges({1,2,3}) == 0); 
assert(countTrendChanges({1,2,2,3}) == 0); 
assert(countTrendChanges({3,2,1,2,3}) == 1); 
assert(countTrendChanges({1,2,3,2}) == 1); 
assert(countTrendChanges({2,1,1,2}) == 1); 
assert(countTrendChanges({1,2,2,1}) == 1); 
assert(countTrendChanges({1,2,3,4,3,4}) == 2); 
}