2011-03-25 25 views
7

因此,我正在嘗試製作一個基本程序來學習C++的基礎知識,我從0到100生成100個隨機數並將它們存儲在一個向量中,然後顯示矢量的總和,平均值,中值,模式,高和低。除了模式是我卡住的地方之外,我還完成了其他一切。這是我迄今爲止的代碼。在C++中查找Ints向量的模式

int modeFunction() 
    { 
     numMode = 0; 
     count = 0; 
     for (int n = 0; n < 100; n++) 
     { 
      for (int y = 0; y < 100; y++) 
      { 
       if (numVector.at(y) == numVector.at(n)) 
       { 
        numMode = numVector.at(y); 
        count++; 
       } 
      } 

     } 
     return numMode; 
    } 

之後,我陷入了困境,因爲在我的腦海裏,應該工作,但事實並非如此。它只是把最後一個數字,通常是100.任何幫助將不勝感激。

+1

東西,如果'myVector'是一個'的std ::矢量'(好像它ATLEAST),你可以索引它像一個數組:'myVector [Y]'和'myVector [n]的'將產量與'myVector.at'版本相同,但看起來更好。 :) – Xeo 2011-03-25 22:35:10

+2

@Xeo:不同之處在於,當at指數超出範圍時,已定義了行爲。可以說'operator []'是一個微型優化,儘管如你所說這也是一種風格差異。 – 2011-03-25 22:50:09

+0

@Steve:啊,謝謝你那個珍聞。:)在'at'處沒有打擾,但是一個普通的數組在超出範圍的訪問中也有未定義的行爲,儘管當你需要它時定義行爲是非常好的。 :) – Xeo 2011-03-25 22:57:02

回答

7

因爲所有的值是0和100之間,可以有效地直方圖找到模式:

std::vector<int> histogram(101,0); 
for(int i=0; i<100; ++i) 
    ++histogram[ numVector[i] ]; 
return std::max_element(histogram.begin(), histogram.end()) - histogram.begin(); 
5

由於模式是最頻繁發生的數字,所以除非新數字的計數大於numMode的計數,否則不應更改numMode

編輯:爲了澄清,你需要保持一個單獨的計數爲當前元素和當前的數字,你認爲是模式。理想情況下,將newMode設置爲第一個元素是一種好方法。

另外,模式不必是唯一的(即「1 1 2 2」)。如果你關心這一點,你可能想牢記這一點。

newMode = element[0] 
modeCount = # of occurrence of newMode 

for (i-th element from [1 to end]) { 
    tmpCount = # of occurrence of element[i] 
    if tmpCount > modeCount { 
    newMode = element[i] 
    modeCount = tmpCount 
    } 
} 
0

您的算法是錯誤的 - 它輸出數組中的最後一個數字,因爲這是它所能做到的。每當指數爲y的數字與指數n上的數字相匹配時,您將覆蓋先前的n的結果。由於您使用相同的循環條件,yn總是同在嵌套循環至少一個點,每個可能n價值 - 你將永遠與numModenumVector.at(99)結束。

你需要改變你的算法來保存計數沿途各n指數(或至少其中n指數結束了最大的count),這樣就可以知道在n環的一端進入發生次數最多。

1

替代解決方案。注意:未經測試。

int mode1(const std::vector<int>& values) 
{ 
    int old_mode = 0; 
    int old_count = 0; 
    for(size_t n=0; n < values.size(); ++n) 
    { 
     int mode = values[n]; 
     int count = std::count(values.begin()+n+1, values.end(), mode); 

     if(count > old_count) 
     { 
      old_mode = mode; 
      old_count = count; 
     } 
    } 
    return old_mode; 
} 

int mode2(const std::vector<int>& values) 
{ 
    return std::max_element(values.begin(), values.end(), [](int value) 
    { 
     return std::count(values.begin(), values.end(), value); 
    }); 
} 
0

模式表示頻率最高的數字。邏輯應該是 -

//Start of function 

int mode = 0, globalCount = 0 ; 
// Start of outer for loop 
for i = 0 to length - 1  
    int localCount = 0 

    // Start of inner for loop 
    for j = 0 to length - 1  
    if vec[i] == vec[j]  
    ++localCount  
// End of Inner for loop 

if (localCount > globalCount) 
    globalCount = localCount 
    mode = vec[i] 
// End of outer for loop 

if globalCount > 1 // This should be checked whether vec has repetitions at all 
    return mode 
else 
    return 0 

// End of function 
+0

@Cistoran - 邏輯可以更好地提高效率,但這是什麼該算法應該根據您的思維過程。 – Mahesh 2011-03-25 22:57:10

0

bmcnett的做法的偉大工程,如果要素的數量足夠小。如果你有大量的元素,但所有的元素值都在一個小範圍內使用map/hashmap效果很好。像

typedef std::pair<int, int> mode_pair; 

struct mode_predicate 
{ 
    bool operator()(mode_pair const& lhs, mode_pair const& rhs) 
    { 
    return lhs.second < rhs.second; 
    } 
}; 

int modeFunction() 
{ 
    std::map<int, int> mode_map; 
    for (int n = 0; n < 100; n++) 
    mode_map[numVector[n]]++; 
    mode_predicate mp; 
    return std::max_element(mode_map.begin(), mode_map.end(), mp)->first; 
}