Find the smallest amongst 3 numbers in C++ [duplic

2020-02-08 07:30发布

问题:

Is there any way to make this function more elegant? I'm new to C++, I don't know if there is a more standardized way to do this. Can this be turned into a loop so the number of variables isn't restricted as with my code?

float smallest(int x, int y, int z) {

  int smallest = 99999;

  if (x < smallest)
    smallest=x;
  if (y < smallest)
    smallest=y;
  if(z < smallest)
    smallest=z;

  return smallest;
}

回答1:

There's a number of improvements that can be made.

You could use standard functions to make it clearer:

// Notice I made the return type an int instead of a float, 
// since you're passing in ints
int smallest(int x, int y, int z){
    return std::min(std::min(x, y), z);
}

Or better still, as pointed out in the comments:

int smallest(int x, int y, int z){
    return std::min({x, y, z});
}

If you want it to operate on any number of ints, you could do something like this:

int smallest(const std::vector<int>& intvec){
    int smallest = std::numeric_limits<int>::max(); // Largest possible integer
    // there are a number of ways to structure this loop, this is just one
    for (int i = 0; i < intvec.size(); ++i) 
    {
        smallest = std::min(smallest, intvec[i]);
    }
    return smallest;
}

You could also make it generic so that it'll operate on any type, instead of just ints

template <typename T>
T smallest(const std::vector<T>& vec){
    T smallest = std::numeric_limits<T>::max(); // Largest possible integer
    // there are a number of ways to structure this loop, this is just one
    for (int i = 0; i < vec.size(); ++i) 
    {
        smallest = std::min(smallest, vec[i]);
    }
    return smallest;
}


回答2:

If possible, I recommend using C++11 or newer which allows you to compute the desired result w/out implementing your own function (std::min). As already pointed out in one of the comments, you can do

T minimum(std::min({x, y, z}));

or

T minimum = std::min({x, y, z});

which stores the minimum of the variables x, y and z in the variable minimum of type T (note that x, y and z must have the same type or have to be implicitly convertible to it). Correspondingly, the same can be done to obtain a maximum: std::max({x, y, z}).



回答3:

apart min, that let you write return min(x, min(y, z)) there is ternary operator:

float smallest(int x, int y, int z){
  return x < y ? (x < z ? x : z) : (y < z ? y : z);
}


回答4:

smallest=(x<((y<z)?y:z)t)?x:((y<z)?y:z);

Suppose,

x is one;
y is two;
z is three;

smallest = (one < ((two < three) ? two:three)) ? one:((two < three) ? two:three)


回答5:

A small modification

 int smallest(int x, int y, int z){
    int smallest = min(x,y);
    return min(smallest,z);
    }


回答6:

There is a proposal to include this into the C++ library under N2485. The proposal is simple, so I've included the meaningful code below. Obviously this assumes variadic templates.

template < typename T >
const T & min ( const T & a )
{ return a ; }

template < typename T , typename ... Args >
const T & min ( const T & a , const T & b , const Args &... args )
{ return std :: min ( b < a ? b : a , args ...); }


回答7:

1) Simple Solution:

int smallest(int x, int y, int z)
{
    return std::min(std::min(x, y), z);
}

2) Better Solution (in terms of optimization):

float smallest(int x, int y, int z)
{
  return x < y ? (x < z ? x : z) : (y < z ? y : z);
}

3) your solution Modified(Simple but not efficient):

int smallest(int x, int y, int z)
{

  int smallest = x;

  if (y < smallest)
     smallest=y;
  if(z < smallest)
     smallest=z;
  return smallest;
}

4) Any number of Numbers:

For n numbers, store it in an array (array[n]), Sort the array and take the array[0] to get smallest.

    //sort the elements in ascending order
    for(int i=0;i<n;i++)
    {
      if(array[i]>array[i+1])
      {
        int temp = array[i];
        array[i] = array[i+1];
        array[i+1] = temp;
      }
    }

    //display smallesst and largest
    cout<<"Smallest: "<<array[0];
    cout<<"Largest: "<<array[n-1];   //not needed in your case
    }


回答8:

In your version, you're finding the smallest value only if it's smaller than 99999.

You should compare all three values together. Also, you're getting int but returning float. Either, you should decide which kind of values you want to process, or you could create a generalized version that works with any kind that can be compared:

#include <algorithm>

template<class T>
T smallest(T x, T y, T z)
{
  return std::min(x, std::min(y, z));
}

EDIT:

Two ways to improve the code into something that operates on a vector:

#include <cstdio>
#include <algorithm>
#include <vector>

// Use a built-in function to retrieve the smallest value automatically
template<class T>
T smallest1(const std::vector<T> &values)
{
  return *std::min_element(values.begin(), values.end());
}

// Go through the vector manually
template<class T>
T smallest2(const std::vector<T> &values)
{
  // Get the first value, to make sure we're comparing with an actual value
  T best_so_far = values.front();
  // For all the other values in the vector ...
  for(unsigned i = 1; i < values.size(); ++i) {
    // ... replace if the new one is better
    if(values[i] < best_so_far)
      best_so_far = values[i];
  }
  return best_so_far;
}

int main()
{
  // Try out the code with a small vector
  std::vector<int> test;
  test.push_back(6);
  test.push_back(5);
  test.push_back(7);

  printf("%d\n", smallest1(test));
  printf("%d\n", smallest2(test));

  return 0;
}


回答9:

Or you can just use define, to create a macro function.

#define min(x,y,z) (x < y ? (x < z ? x : z) : (y < z ? y : z))


回答10:

You can store them in a vector and use std::min_element on that.

For example:

vector<int> values;
values.push_back(10);values.push_back(1);values.push_back(12);

int min = *std::min_element(values.begin(),values.end());