2012-02-24 14 views
14

Esiste un modo per rendere questa funzione più elegante? Sono nuovo di C++, non so se c'è un modo più standard per farlo. Può essere trasformato in un loop in modo che il numero di variabili non sia limitato come con il mio codice?Trova il più piccolo tra 3 numeri in 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

haha ​​cosa succede se nessuno dei valori sono più piccole di 99999? ha. – L7ColWinters

+4

@jogojapan o meglio che iniziare con 'INT_MAX' (o'std :: numeric_limits :: max()' solo iniziare con il primo numero ... –

+0

Non sono sicuro che fosse una buona idea chiudere questo a causa di il contesto C++ Mi piacerebbe vedere la discussione generica nel duplicato citato, e mi piacerebbe anche vedere la discussione in C++ con i modelli e la meta-programmazione, e la discussione in C++ 11 con 'constexpr'. un duplicato migliore, anche se il suo 'max' invece di' min': [Il modo più efficace per trovare il massimo di tre inte] (http://stackoverflow.com/q/2233166/608639). Sembra migliore perché il suo C++ specifico, ma manca un buon trattamento di modelli, meta programmazione e 'constexpr'. – jww

risposta

1

Una piccola modifica

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

C'è una serie di miglioramenti che possono essere fatte.

È possibile utilizzare le funzioni standard per renderlo più chiaro:

// 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 meglio ancora, come sottolineato nei commenti:

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

Se si vuole operare su qualsiasi numero di int , si potrebbe fare qualcosa di simile:

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

si potrebbe anche rendere più generico in modo che sarà operat e su qualsiasi tipo, invece di INT

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

Terzo esempio potrebbe essere scritto usando gli iteratori quindi funzionerebbe anche su altri contenitori, come elenchi o set. – Correa

+0

@Correa: l'ho preso in considerazione, ma non volevo andare troppo lontano dalla parte profonda con caratteristiche nitide poiché penso che potrebbe servire solo a confonderlo. – Alex

8

parte min, che consentono di scrivere min ritorno (x, min (y, z)) c'è operatore ternario:

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

OK, mi hai battuto :( –

1

Nella vostra versione , stai rilevando il valore minimo solo se è inferiore a 99999.

È necessario confrontare tutti e tre i valori insieme. Inoltre, stai ricevendoma restituendo float. Entrambi i casi, si dovrebbe decidere quale tipo di valori che si desidera elaborare, oppure si potrebbe creare una versione generalizzata che funziona con qualsiasi tipo che può essere paragonato:

#include <algorithm> 

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

EDIT:

Due modi per migliorare il codice in qualcosa che opera su 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

c'è una proposta per includere questo nella libreria C++ sotto N2485. La proposta è semplice, quindi ho incluso il codice significativo qui sotto. Ovviamente ciò presuppone modelli variadici.

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

Supponiamo,

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

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

In qualche modo nella tua prima riga ci è scivolata una "t" alla seconda parata di chiusura – xoryouyou

1

1) soluzione semplice:

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

2) soluzione migliore (in termini di ottimizzazione):

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

3) la soluzione Modificato (Semplice ma non efficiente):

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

    int smallest = x; 

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

4) Qualsiasi numero di numeri:

per n numeri, conservarla in un array (array [n]), Sort la matrice e prendono la matrice [0] per ottenere il più piccolo.

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

Oppure si può semplicemente utilizzare definire, per creare una funzione macro.

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

Evita i macro in C++ quando puoi: http://stackoverflow.com/questions/4715831/why- è-define-bad-and-what-is-the-proper-sostituto – jogojapan

18

Se possibile, mi consiglia di utilizzare C++ 11 o più recente, che consente di calcolare il risultato desiderato w/implementare la vostra propria funzione (std::min). Come già evidenziato in uno dei commenti, si può fare

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

o

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

che memorizza il minimo delle variabili x, y e z nella variabile minimum di tipo T (notare che x, e z devono avere lo stesso tipo o devono essere implicitamente convertibili in esso). Corrispondentemente, lo stesso può essere fatto per ottenere un massimo: std::max({x, y, z}).

+2

Questa dovrebbe essere la risposta accettata Questo è un esempio di come C++ 11 rende così tante cose molto più facili e le persone dovrebbero usarlo a meno che non abbiano una ragione estremamente buona. Guarda quanto sono più complesse e inutili tutte le altre risposte, nonostante siano state scritte nel 2012 quando esisteva già questa sintassi superiore. –

+0

Ho provato 'int x = 1; int y = 2; int z = 3; std :: cout << std :: max ({x, y, z}); 'ma fornisce un errore di compilazione Qual è il modo corretto per farlo? – xslittlegrass

+0

Puoi provare flag -std = C++ 11 sul tuo compilatore. – ae0709

1

È possibile memorizzarli in un vettore e utilizzare std::min_element su quello.

Ad esempio:

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

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