I do assignments for the book by Bjarne Straustrup Programming: Principles and Practice Using C ++, 2nd Edition. At the head of 4, the task 16 it is necessary to find the mode of the number series. There were no problems with one mode, but what to do when there are several modes in a number series? For example, if in the row 4, 8, 8, 4, 9; fashion is the same and 4 and 8.

vector<double> numbers; for (double n; cin >> n;) numbers.push_back(n); sort(numbers); int counter = 0; for (int i = 0; i < numbers.size(); ++i) { for (int j = 0; j < numbers.size(); ++j) { if (numbers[i] == numbers[j]) ++counter; } //сколько ΠΊΠ°ΠΆΠ΄ΠΎΠ΅ число повторяСтся Ρ€Π°Π· arr.push_back(counter); counter = 0; } int n = 0; double max = 0; for (int i = 0; i < arr.size(); ++i) { if (arr[i] == 1) ++counter; if (arr[i] > max) { max = arr[i]; n = i; } } if (counter == arr.size()) cout << "We dont have mode\n"; else cout << "Mode: " << numbers[n] << '\n'; keep_window_open("~"); return 0; 
  • one
    What is fashion? - Vlad from Moscow
  • The number that is repeated in the sequence the most times - Bogdan
  • There are several approaches. Either record the modes also in a vector, or make two passes through the sequence: first look for the maximum repetition, and then output all values ​​with the maximum repetition. - Vlad from Moscow

4 answers 4

You have these cycles

 int counter = 0; for (int i = 0; i < numbers.size(); ++i) { for (int j = 0; j < numbers.size(); ++j) { if (numbers[i] == numbers[j]) ++counter; } //сколько ΠΊΠ°ΠΆΠ΄ΠΎΠ΅ число повторяСтся Ρ€Π°Π· arr.push_back(counter); counter = 0; } 

not effective. Since the vector has already been sorted, it does not make sense to start the inner loop from the position equal to 0.

As for your question, there are several approaches. For example, you could write modes also in a vector. The second approach consists of two passes on a sorted vector. First, you find the maximum value of the repeated neighboring elements, and in the second pass, output those elements that are repeated the number of times found.

Below is a program that demonstrates the first approach using vector storage mod.

 #include <iostream> #include <vector> #include <algorithm> int main() { std::vector<int> v = { 4, 8, 8, 4, 9 }; std::vector<int> mods; std::sort( v.begin(), v.end() ); using size_type = std::vector<int>::size_type; size_type max = 0; for ( size_type i = 0, j; i < v.size(); i = j ) { j = i + 1; while ( v[j] == v[i] ) ++j; if ( max <= j - i ) { if ( max != 1 ) { if ( max < j - i ) { max = j - i; mods.assign( 1, v[i] ); } else { mods.push_back( v[i] ); } } } } if ( max == 1 ) { std::cout << "We dont have mode\n"; } else { std::cout << "Mode" << ( mods.size() == 1 ? ":" : "s:" ); for ( int x : mods ) std::cout << ' ' << x; std::cout << '\n'; } return 0; } 

Her console output is as follows.

 Modes: 4 8 
  • I apologize, maybe I did not understand something, but if we take, for example, std :: vector <int> v = {3, 3, 8, 8, 4,4,4,4, 9}; , then the output of your algorithm will be 3.4, and it should be only 4. and I still haven’t really understood what is the meaning of the if (max <j - i) condition, if it is checked only if max was assigned to ji, you probably wanted to compare with the previous fashion value? - bronstein87
  • @ bronstein87 Thanks for the comment. Assignment max = j - I; should be after the condition if (max <j - i) I corrected the code. - Vlad from Moscow

Output any :) - it will be a fashion. But let me give advice on how to proceed. You are now going through all the other numbers for each number encountered in the vector. Why, if the vector is already sorted ?

I would introduce two variables - the mode value and the number of its repetitions (initially - 0).

Further, going from the first value of the vector, I would simply count how many times the next value of the vector occurs (in your case - 4 4 8 8 9, then the first is 4, the second is 4, the third is not; stop. Current counter 0. It less received? yes. We are recording a new counter - 2, a new mode - 4. Continuing from the third element 8, fourth 8, fifth ... stop. Counter - 2. The recorded counter is less? No? ignore. (Or, if you check with using> = - then yes, overwrite counter 2, mode - 8). Continue from the fifth element. 9, the vector is over. Repetition is one, less is the account Ica, ignore.

So you will go through the vector only once. Otherwise, why did you sort it? :)

    Here's another option, I will not say that it is optimal, but simple and visual:

     #include <unordered_map> #include <algorithm> #include <iostream> #include <vector> int main() { // -- Π²Π΅ΠΊΡ‚ΠΎΡ€ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠΉ std::vector<int> Array = {7,5,3,2,2,4,5,7,9,0,1,1,4}; // -- ΠΊΠ°Ρ€Ρ‚Π° частот std::unordered_map<int,int> Freq; for(auto &i:Array) Freq[i]++; // -- сортировка ΠΏΠΎ частотам std::vector<std::pair<int, int>> Vec(Freq.begin(),Freq.end()); std::sort(Vec.begin(),Vec.end(),[](std::pair<int,int> a, std::pair<int,int> b) { return (a.second == b.second) ? a.first > b.first : a.second > b.second; }); // -- Π²Ρ‹Π²ΠΎΠ΄ ΠΏΠ°Ρ€ ΠΏΠΎ ΡƒΠ±Ρ‹Π²Π°Π½ΠΈΡŽ частот ΠΈ ΠΏΠΎ ΡƒΠ±Ρ‹Π²Π°Π½ΠΈΡŽ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠΉ for(auto &i:Vec) std::cout << i.first << ":" << i.second << std::endl; // -- Ссли Π½ΡƒΠΆΠ΅Π½ ΠΎΠ΄ΠΈΠ½ элСмСнт - Π²ΠΎΠ·ΠΌΠ΅ΠΌ ΠΏΠ΅Ρ€Π²Ρ‹ΠΉ } 

    The output will be:

     7:2 5:2 4:2 2:2 1:2 9:1 3:1 0:1 

      I got another option.

       vector<int> repeats; vector<int> numbers = { 4, 8, 8, 4, 9 }; sort(numbers); int counter = 0; for (int i = 0; i < numbers.size(); ++i) { for (int j = 0; j < numbers.size(); ++j) { if (numbers[i] == numbers[j]) ++counter; } //сколько ΠΊΠ°ΠΆΠ΄ΠΎΠ΅ число повторяСтся Ρ€Π°Π· repeats.push_back(counter); counter = 0; } vector<int> num; vector<int> rep; for (int i = 0; i < repeats.size(); ++i) { //Ссли счСтчик Ρ€Π°Π²Π΅Π½ ΠΊΠΎΠ»-Π²Ρƒ //Π·Π½Π°Ρ‡Π΅Π½ΠΈΠΉ Π² Π²Π΅ΠΊΡ‚ΠΎΡ€Π΅ - Π·Π½Π°Ρ‡ΠΈΡ‚ всС числа //ΠΏΠΎΠ²Ρ‚ΠΎΡ€ΡΡŽΡ‚ΡΡ 1 Ρ€Π°Π· ΠΈ ΠΌΠΎΠ΄Ρ‹ Π½Π΅Ρ‚ if (repeats[i] == 1) ++counter; //Π£Π΄Π°Π»Π΅Π½ΠΈΠ΅ ΠΏΠΎΠ²Ρ‚ΠΎΡ€ΡΡŽΡ‰ΠΈΡ…ΡΡ чисСл ΠΈ ΠΈΡ… ΠΏΠΎΠ²Ρ‚ΠΎΡ€ΠΎΠ² if (i == 0 || numbers[i - 1] != numbers[i]) { num.push_back(numbers[i]); rep.push_back(repeats[i]); } } int n = 0; int max = 0; for (int i = 0; i < num.size(); ++i) { if (rep[i] > max) { max = rep[i]; n = i; //индСкс макимального ΠΊΠΎΠ»-Π²Π° повторСния } } cout << "\n"; if (counter == repeats.size()) cout << "We dont have mode\n"; else for (int i = 0; i < num.size(); ++i) //Ссли максимальноС ΠΏΠΎΠ²Ρ‚ΠΎΡ€Π΅Π½ΠΈΠ΅ Ρ‚Π°ΠΊΠΎΠ΅ ΠΆΠ΅ Π²Ρ‹Π²ΠΎΠ΄ΠΈΠΌ Π΅Ρ‰Ρ‘ ΠΌΠΎΠ΄Ρ‹ if (rep[i] == rep[n]) cout << "Mode: " << num[i] << '\n'; 

      Output to console:

       Mode: 4 Mode: 8