22
\$\begingroup\$

When I need to get maximum value of A, B, and C, then I would write like:

val = A;
val = max(val, B);
val = max(val, C);

But, in this case, I need to write two "val" in the one line. And, it is cumbersome if the "val" is more complex like "val[0][1][2].element"... If it is adding value, I can write like "val += B" without writing "val" twice in the line.

I can make macro like:

#define MAXEQ(A,B) (A) = max((A), (B))

But, it looks not very intuitive.

Is there any smarter way to write these things ?

\$\endgroup\$
4
  • 1
    \$\begingroup\$ Would you like a version that allows for( x : list ) val <= highest(x);? But this is a better question for StackOverflow not CodeReview. \$\endgroup\$ Commented May 13, 2013 at 14:55
  • 1
    \$\begingroup\$ What about just doing val = max(A, max(B, C))? \$\endgroup\$ Commented May 15, 2013 at 11:35
  • \$\begingroup\$ @LokiAstari : effectiveness of chosen algorithm, is a form of code review. Though this might be a personal opinion =( \$\endgroup\$ Commented May 15, 2013 at 17:54
  • \$\begingroup\$ Seems largely on topic to me, though I'd have been happier with a complete code snippet...which he almost provided. He has working code and wants to make it cleaner; this seems a perfect CR question. I'd rather see this question on CR than on SO. \$\endgroup\$ Commented Jan 5, 2014 at 17:46

3 Answers 3

36
\$\begingroup\$

If you have access to C++11, I'd suggest using std::max with an initializer_list<T>. A complete minimal example:

#include <algorithm>
#include <initializer_list>
#include <iostream>

int main()
{
    int a = 1;
    int b = 2;
    int c = 3;

    int m = std::max({a, b, c});

    std::cout << m << "\n";
}
\$\endgroup\$
3
  • \$\begingroup\$ How would you make this work if the data is generated in a loop, or the number of data changes at runtime? \$\endgroup\$ Commented May 13, 2013 at 14:52
  • 3
    \$\begingroup\$ @BenVoigt If the data changes at runtime, store it in a container and use max_element. That, to me, didn't seem the intent of the question; rather, "I have a number of (already defined) variables - how do I find the max of them concisely". \$\endgroup\$ Commented May 14, 2013 at 1:01
  • \$\begingroup\$ @Yuushi I don't follow - why does it matter if the data changes at runtime? \$\endgroup\$ Commented Nov 15, 2019 at 22:11
1
\$\begingroup\$

Assuming you have an unknown set of data, you can always place it in an array / vector / list and run...

int res = *max_element( intList.begin(),  intList.end() ); //where intList is the list

Which is as commented by @Yuushi : but expended on, since it can get quirky

#include <algorithm>
#include <iostream>
#include <list>
#include <stdlib.h> 
#include <algorithm>    // std::max

using namespace std;

int main() {
   list<int> intList;
   int a, b;
   int maxItems = rand() % 40 + 10; //10 to 50 items

   cout << "=== Testing a maximum of " << maxItems << " values ===\n"; 
   cout << "generating random value set: {";

   for( a = 0; a < maxItems; ++a ) {
      b = rand() % 100;
      cout << b << ", ";
      intList.push_back(b);
   }
   cout << "}\n";

   //Note max element inputs iterators, and outputs the max value iterator! 
   //-> which is the pointer to the actual value (hence * to get value)
   a = *max_element( intList.begin(),  intList.end() );
   cout << "max value generated = " << a << "\n";

   return 0;
}

Which can give a sample result as below

=== Testing a maximum of 33 values ===
generating random value set: {86, 77, 15, 93, 35, 86, 92, 49, 21, 62, 27, 90, 59, 63, 26, 40, 26, 72, 36, 11, 68, 67, 29, 82, 30, 62, 23, 67, 35, 29, 2, 22, 58, }
max value generated = 93
\$\endgroup\$
3
  • \$\begingroup\$ Why do you need to do this? Why does it matter if the data is "unknown"? How will it fail, and why? \$\endgroup\$ Commented Nov 15, 2019 at 22:24
  • 1
    \$\begingroup\$ std::vector<int> will in almost every case be more efficient than std::list<int>. \$\endgroup\$ Commented Nov 15, 2019 at 22:46
  • \$\begingroup\$ @TylerShellberg He is not saying it will fail if the data is known. However, it is somewhat bizarre to write code to find the maximum of data known before compilation. You could just pick the maximum and avoid the unnecessary code/confusion. \$\endgroup\$ Commented Jan 26, 2021 at 23:10
1
\$\begingroup\$

A simpler way would be to use this overloaded function std::max that accepts an object of the type std::initializer_list<int>

#include<iostream>
#include<algorithm>
using namespace std;
int main()
{
    int a = 2;
    int b = 3;
    int c = 4;
    cout << max({a,b,c}) << '\n';

    cout << max({7,7,8}) << '\n';

return 0;
}
\$\endgroup\$
1
  • \$\begingroup\$ What does this add that's missing from Yuushi's answer? Apart from polluting the global namespace with the whole of std, I mean. Please just vote for the existing answer instead of duplicating it. \$\endgroup\$ Commented Jan 9, 2021 at 15:55

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.