可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
So I'm trying to make a basic program to learn the basics of C++, I'm generating 100 random numbers from 0 to 100 and storing them in a vector, I am then displaying the sum, mean, median, mode, high and low of the vector. I have everything else done except the mode which is where I get stuck. Here is the code I have so far.
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;
}
After that I get stuck because in my mind that should work but it doesn't. It just out puts the last number, usually 100. Any help would be much appreciated.
回答1:
since all the values are between 0 and 100, you can find the mode efficiently with a histogram:
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();
回答2:
Since mode is the number that occurs most frequent you shouldn't change numMode
unless the new number's count is greater than numMode
's count.
EDIT: To clarify, you need to keep a separate count for the current element and the current number that you think is the mode. Ideally, setting newMode
to the first element is a good approach.
In addition, mode isn't necessary unique (i.e. "1 1 2 2"). You may want to keep that in mind if you care about that.
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
}
}
回答3:
Your algorithm is wrong - it outputs the last number in the array because that's all it can ever do. Every time the number at index y
matches the number at index n
you overwrite the results for the previous n
. Since you're using the same loop conditions, y
and n
are always the same at at least one point in the nested loop for each possible n
value - and you'll always end up with numMode
being numVector.at(99)
.
You need to change your algorithm to save the count for each n
index along the way (or at least which n
index ended up with the greatest count
), so that you can know at the end of the n
loop which entry occured the most times.
回答4:
Alternative solutions. Note: untested.
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);
});
}
回答5:
bmcnett's approach works great if number of elements are small enough. If you have large number of elements but the all element value are with in a small range using map/hashmap works well. Something like
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;
}
回答6:
Mode means a number with highest frequency. The logic should be -
//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
回答7:
int number = array_list[0];
int mode = number;
int count = 1;
int countMode = 1;
for (int i=1; i<size_of_list; i++)
{
if (array_list[i] == number)
{ // count occurrences of the current number
count++;
if (count > countMode)
{
countMode = count; // mode is the biggest ocurrences
mode = number;
}
}
else
{ // now this is a different number
if (count > countMode)
{
countMode = count; // mode is the biggest ocurrences
mode = number;
}
count = 1; // reset count for the new number
number = array_list[i];
}
}