2017-06-07 30 views
0

我有一個非常簡單的代碼,它可以計算您在數組中需要多少值。數組中的計數器C++

for (int i = 0; i < dm; i++) 
    { 
     if (arr[i] == c) 
     { 
      counter++; 
     } 
    }; 

但我需要使它有點棘手。我需要計算相同的值的數量。想象一下,我有一個數組{4,4,4,3,3,2,2,1,1,0,0,0},我需要找到那裏有多少「雙胞胎」。所以3,2,1是雙胞胎,因爲他們只有1個確切的朋友。 我嘗試了2 fors和2個計數器,但仍有麻煩。謝謝。希望你明白我的意思是「雙胞胎」。 x和x是雙胞胎和y,y,y不是(以防萬一)

+0

你的數組是否總是排序? – Slava

+2

製作一個「地圖」對象並存儲它的計數 –

+0

@slava是從較高到較低,如果這就是你的意思 – AlexMIEL

回答

0

,而無需使用附加的陣列解決方案:

int twins_counter = 0; 
for (int i = 0; i < dm; i++) 
{ 
    int counter = 0; // counter for elements 
    for (int j = 0; j < dm; j++) 
    { 
     if (arr[i] == arr[j]) 
     { 
      if(j < i) 
      { 
       break; // we have searched twin for this element already 
      } 
      counter++; 
      if(counter > 2) 
      { 
       break; // we meet element third time, it isn't twin 
      } 
     } 
    } 

    if(counter == 2) 
    { 
      twins_counter++; 
    } 
}; 

對於排序的(向上或向下)陣列一個週期是不夠的:

int twins_counter = 0; 
int counter = 1; 

for (int i = 1; i < dm; i++) 
{ 
    if(arr[i] == arr[i-1]) 
    { 
     counter++; 
    } 
    else 
    { 
      if(counter == 2) 
      { 
       twins_counter++; 
       counter = 1; 
      } 
    } 
} 

// check last value 
if(counter == 2) 
{ 
    twins_counter++; 
} 
+0

對於排序的數組,你可以簡化這個解決方案更多 –

+0

謝謝,但你可以給我一個提示,我需要如何修改它,如果我需要找到例如只存在4次數組中的元素,而不是2倍像雙胞胎? – AlexMIEL

+0

@AlexMIEL只要在條件下更改2到4即可。 –

2

我會製作一個映射 - 針對數組中的每個單獨數字 - 它們的出現次數。該代碼可能看起來如下:

#include <iostream> 
#include <map> 

int main() 
{ 
    const int numberOfElements = 12; 

    int array[numberOfElements] = { 4,4,4,3,3,2,2,1,1,0,0,0 }; 
    std::map<int,int> counts; 
    for (int i=0; i < numberOfElements; i++) { 
     counts[array[i]]++; 
    } 
    for (auto x : counts) { 
     if (x.second == 2) { 
      cout << "pair: " << x.first << endl; 
     } 
    } 
    return 0; 
} 

如果 - 因某種原因 - 元素的範圍是有限的,你也可以使用「普通」數組計數的出現。如果,例如,該元素是在0..4的範圍內,可以使用下面的代碼片段:

const int numberOfElements = 12; 
const int elementMax = 4; 

int array[numberOfElements] = { 4,4,4,3,3,2,2,1,1,0,0,0 }; 
int counts[elementMax+1] = {}; 
for (int i=0; i<numberOfElements; i++) { 
    counts[array[i]]++; 
} 
for (int i=0; i <= elementMax; i++) { 
    if (counts[i] == 2) { 
     cout << "pair: " << i << endl; 
    } 
} 

如果你的數組進行排序,比沒有計數器陣列可以看作是一個解決辦法如下:

const int numberOfElements = 12; 

int array[numberOfElements] = { 4,4,4,3,3,2,2,1,1,0,0,0 }; 
int prev = -1; 
int count = 0; 
for (int i=0; i<numberOfElements; i++) { 
    if (array[i] == prev) { 
     count++; 
    } 
    else { 
     if (count == 2) { 
      cout << "pair: " << prev << endl; 
     } 
     count=1; 
     prev = array[i]; 
    } 
} 
if (prev >= 0 && count==2) { 
    cout << "pair: " << prev << endl; 
} 
+0

請避免使用幻數 – Slava

+0

對OP的評論說數組總是排序,所以這些都是太多的工作,內存使用等等。 –

+0

@丹尼爾H:第一個是更通用的解決方案,我發現值得說明的;也爲排序的數組附加了一個解決方案。 –

1

你可以做,在道次和使用效率的二進制搜索:

int arr[] = { 4,4,4,3,3,2,2,1,1,0,0,0 }; 
int twins = 0; 
for(auto i = std::begin(arr); i != std::end(arr);) { 
    auto next = std::upper_bound(i, std::end(arr), *i, std::greater<int>()); 
    if(std::distance(i, next) == 2) ++twins; 
    i = next; 
}  

Live example

的情況下有沒有太多的重複陣列std::upper_bound中可能是無效的,可以很容易被替換:

auto next = std::find_if(std::next(i), std::end(arr), [i](int n) { return *i != n; }); 
+0

O(n)因爲您的解決方案是n * log n因爲二進制搜索循環的每一步。二進制搜索不需要 - 請參閱我的解決方案。 –

+0

@AlexanderUshakov您試圖說完全掃描數組比二進制搜索更有效嗎?你需要重新考慮你的O(n)估計。如果我將「i」增加1並對每個值進行二分搜索,那麼這將是n * log n。 – Slava

+0

如果數組中的所有值都不相同,則您的解決方案將與我們在每個元素上進行二分搜索時的方法相同。所以它的O(n)是n * log n。 –