2012-02-24 8 views
14

¿Hay alguna manera de hacer que esta función sea más elegante? Soy nuevo en C++, no sé si hay una forma más estandarizada de hacerlo. ¿Se puede convertir esto en un ciclo así que el número de variables no está restringido como con mi código?Encuentra el más pequeño entre 3 números en C++

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; 
} 
+4

jaja ¿y si ninguno de los valores son menores que 99999? decir ah. – L7ColWinters

+4

@jogojapan o mejor que comenzar con 'INT_MAX' (or'std :: numeric_limits :: max()' solo comience con el primer número ... –

+0

No estoy seguro de que sea una buena idea cerrar esto debido a el contexto de C++. Me gustaría ver la discusión genérica en el duplicado citado, y también me gustaría ver la discusión de C++ con plantillas y programación de metadatos, y la discusión de C++ 11 con 'constexpr'. una mejor dup, a pesar de que es 'max' en lugar de' min': [La forma más eficiente de encontrar la mayor de tres ints] (http://stackoverflow.com/q/2233166/608639). Se ve mejor porque es C++ específico. Pero carece de un buen tratamiento de plantillas, metaprogramación y 'constexpr'. – jww

Respuesta

1

una pequeña modificación

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

Hay una serie de mejoras que se pueden hacer.

Usted podría utilizar las funciones estándar para hacerlo más claro:

// 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); 
} 

O mejor aún, como se ha señalado en los comentarios:

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

Si desea que le permite operar en cualquier número de enteros , podría hacer algo como esto:

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; 
} 

También podría hacerlo genérico para que funcione e en cualquier tipo, en lugar de sólo 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; 
} 
+23

Con C++ 11,' std :: min ({x, y, z}); '. –

+0

El tercer ejemplo podría escribirse utilizando iteradores por lo que también funcionaría en otros contenedores, como listas o conjuntos. – Correa

+0

@Correa: lo consideré, pero no quería ir demasiado lejos con características buenas ya que creo que podría servir para confundirlo. – Alex

8

aparte min, que le permiten escribir min retorno (x, min (y, z)) hay operador ternario:

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

Bien, me ganaste :( –

1

En su versión , está buscando el valor más pequeño solo si es más pequeño que 99999.

Debe comparar los tres valores juntos. Además, obtiene int pero devuelve float. O bien, usted debe decidir qué tipo de valores que desee procesar, o usted podría crear una versión generalizada que funciona con cualquier tipo que puede ser comparada:

#include <algorithm> 

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

EDIT:

Dos maneras de mejorar el código en algo que funciona en un 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; 
} 
2

hay una propuesta para incluir esto en la biblioteca de C++ en N2485. La propuesta es simple, así que he incluido el código significativo a continuación. Obviamente, esto supone plantillas variadas.

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 ...); } 
5
smallest=(x<((y<z)?y:z)t)?x:((y<z)?y:z); 

Supongamos,

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

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

De alguna manera en tu primera línea se deslizó una 't' en la segunda parántesis de cierre. – xoryouyou

1

1) Solución simple:

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

2) solución mejor (en términos de optimización):

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

3) su solución modificada (Simple pero no eficiente):

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

    int smallest = x; 

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

4) Cualquier número de Números:

Para n números, almacenarlo en una matriz (array [n]), Sort la matriz y toman la matriz [0] para obtener la más pequeña.

//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 
    } 
0

O puede simplemente usar definir, para crear una función de macro.

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

Evita las macros en C++ cuando puedes: http://stackoverflow.com/questions/4715831/why- is-define-bad-and-what-is-the-proper-substitute – jogojapan

18

Si es posible, recomiendo el uso de C++ 11 o más nuevo que le permite calcular el resultado deseado w/a la implementación de su propia función (std::min). Como ya se ha señalado en uno de los comentarios, puede hacerlo

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

o

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

que almacena el mínimo de las variables x, y y z en la variable minimum de tipo T (nota que x, y y z deben tener el mismo tipo o deben ser implícitamente convertibles a él). En consecuencia, lo mismo se puede hacer para obtener un máximo: std::max({x, y, z}).

+2

Esta debería ser la respuesta aceptada. Este es un ejemplo de cómo C++ 11 facilita tanto las cosas y la gente debería usarlas a menos que tengan una razón muy buena. Miren cuánto más complejas e innecesarias son todas las otras respuestas, a pesar de haber sido escritas en 2012 cuando ya existía esta sintaxis superior. –

+0

Intenté 'int x = 1; int y = 2; int z = 3; std :: cout << std :: max ({x, y, z}); 'pero da un error de compilación. ¿Cuál es la forma correcta de hacerlo? – xslittlegrass

+0

Puede probar el indicador -std = C++ 11 en su compilador. – ae0709

1

Puede almacenarlos en un vector y usar std::min_element en eso.

Por ejemplo:

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

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