这是一个简单的程序,用于查找最常出现在数组中的元素:
#include <cstdlib>
#include <iostream>
#include <vector>
using namespace std;
int main(int argc, char *argv[]) {
int a[] = {1,2,3,4,4,4,5};
int n = sizeof(a) / sizeof(int);
int max = 0;
int result = 0;
int *b = new int[n];
for (int i = 0; i < n; i++) {
b[a[i]] = (b[a[i]] || 0) + 1;
if (b[a[i]] > max) {
max = b[a[i]];
result = a[i];
}
}
cout << result << endl;
system("PAUSE");
return EXIT_SUCCESS;
}
但它不起作用;它打印1
。为什么呢?
答案 0 :(得分:11)
由于您要包含矢量,为什么不将int *b=new int [n];
替换为std::vector<int> b(n)
?这也需要释放内存,你忘了delete[] b
。
但正如其他人所提到的,如果数组包含大于n的元素,则解决方案将会中断。更好的方法可能是使用映射到int来计算元素。这样,您还可以计算不能用作数组索引的元素,例如字符串。
也没有理由将自己局限于数组。这是一个通用解决方案,适用于任何低于可比元素类型的容器:
#include <algorithm>
#include <iterator>
#include <map>
struct by_second
{
template <typename Pair>
bool operator()(const Pair& a, const Pair& b)
{
return a.second < b.second;
}
};
template <typename Fwd>
typename std::map<typename std::iterator_traits<Fwd>::value_type, int>::value_type
most_frequent_element(Fwd begin, Fwd end)
{
std::map<typename std::iterator_traits<Fwd>::value_type, int> count;
for (Fwd it = begin; it != end; ++it)
++count[*it];
return *std::max_element(count.begin(), count.end(), by_second());
}
#include <iostream>
#include <vector>
int main()
{
std::vector<int> test {1, 2, 3, 4, 4, 4, 5};
std::pair<int, int> x = most_frequent_element(test.begin(), test.end());
std::cout << x.first << " occured " << x.second << " times";
}
答案 1 :(得分:6)
您尚未初始化数组b
。你可以这样做:
int *b=new int [n]();
^^
完成后,您可以将频率数组递增为:
b[a[i]]++;
取代
b[a[i]]=(b[a[i]]||0)+1;
您执行(b[a[i]]||0)+1
的方式适用于Javascript,Perl等语言,其中未初始化的数组元素将具有名为undef
或null
的特殊值。 C ++没有这样的东西,未初始化的数组将有垃圾。
答案 2 :(得分:1)
您需要将数组b初始化为零。
b[a[i]]||0
不起作用,你不知道b中最初是什么。
更短的代码:
int main(int argc, char *argv[])
{
int a[]={1,2,3,4,4,4,5};
int n = sizeof(a)/sizeof(int );
int *b=new int [n];
fill_n(b,n,0); // Put n times 0 in b
int val=0; // Value that is the most frequent
for (int i=0;i<n;i++)
if( ++b[a[i]] >= b[val])
val = a[i];
cout<<val<<endl;
delete[] b;
return 0;
}
注意: 如果最大值低于数组a中的值数,那么你的代码(我的代码)也只能工作。
如果不是这种情况并且最大值远远大于元素数量,则可能需要对数组进行排序,然后在线性时间(和常量空间)中搜索最大值。
答案 3 :(得分:0)
这里,O(n)及时,O(1)在空间通用解决方案中工作于有序范围。
#include <iostream>
template <class ForwardIterator>
ForwardIterator
most_common(ForwardIterator first, ForwardIterator last) {
/** Find the most common element in the [first, last) range.
O(n) in time; O(1) in space.
[first, last) must be valid sorted range.
Elements must be equality comparable.
*/
ForwardIterator it(first), max_it(first);
size_t count = 0, max_count = 0;
for ( ; first != last; ++first) {
if (*it == *first)
count++;
else {
it = first;
count = 1;
}
if (count > max_count) {
max_count = count;
max_it = it;
}
}
return max_it;
}
int main() {
int a[] = {1, 2, 3, 4, 4, 4, 5};
const size_t len = sizeof(a) / sizeof(*a);
std::cout << *most_common(a, a + len) << std::endl;
}
答案 4 :(得分:0)
利用事实地图的实现已经过排序。
#include <iostream>
#include <vector>
#include <map>
using namespace std;
template<class T> pair<T, int> getSecondMostOccurance(vector<T> & v) {
map<T, int> m;
for ( int i = 0; i < v.size(); ++i ) {
m[ v[i] ]++;
}
return *m.end();
}
int main() {
int arr[] = {1, 4, 5, 4, 5, 4};
pair<int, int> p = getSecondMostOccurance(vector<int>(arr, arr+7));
cout << "element: " << p.first << " count: " << p.second << endl;
return 0;
}