2012-02-24 16 views
14

Czy istnieje sposób na uczynienie tej funkcji bardziej elegancką? Jestem nowy w C++, nie wiem, czy istnieje bardziej standaryzowany sposób na zrobienie tego. Czy można to przekształcić w pętlę, więc liczba zmiennych nie jest ograniczona, tak jak w przypadku mojego kodu?Znajdź najmniejszą spośród 3 liczb w 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 ​​co, jeśli żadna z wartości są mniejsze niż 99999? ha. – L7ColWinters

+4

@jogojapan lub lepiej niż zaczynające się od 'INT_MAX' (or'std :: numeric_limits :: max()' po prostu zacząć od pierwszego numeru ... –

+0

nie jestem pewien, że to dobry pomysł, aby zamknąć to spowodowane kontekst C++ Chciałbym zobaczyć ogólną dyskusję w cytowanym dupku, a także chciałbym zobaczyć dyskusję w C++ za pomocą szablonów i meta-programowania oraz dyskusję w C++ 11 z 'constexpr'. lepszy dup, nawet jeśli jego 'max' zamiast' min': [Najbardziej efektywny sposób na znalezienie największego z trzech intów] (http://stackoverflow.com/q/2233166/608639). Wygląda lepiej, ponieważ jego C++ . specyficzne, ale brakuje mu dobrego traktowania szablonów, programowanie meta i 'constexpr' – jww

Odpowiedz

1

Niewielka modyfikacja

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

Istnieje szereg ulepszeń, które mogą być wykonane.

Można użyć standardowych funkcji, aby uczynić go bardziej zrozumiałym:

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

Albo jeszcze lepiej, jak wskazano w uwagach:

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

Jeśli chcesz, aby działać na dowolnej liczbie wskazówki , można zrobić coś takiego:

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

można również zrobić to generic tak że będzie ona operat e na wszelkiego rodzaju, a nie tylko wskazówki

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

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

+0

Trzeci przykład można zapisać za pomocą iteratorów. więc działałoby również na inne pojemniki, takie jak listy lub zestawy. – Correa

+0

@Correa: Zastanawiałem się nad tym, ale nie chciałem zbyt daleko schodzić z głębokimi szczegółami, ponieważ uważam, że może to go zmylić. – Alex

8

siebie min, które pozwalają pisać powrót min (x, min (y, z)) jest trójargumentowy operator:

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

OK, pokonałeś mnie :( –

1

W swojej wersji , znajdujesz najmniejszą wartość tylko wtedy, gdy jest mniejsza niż 99999.

Powinieneś porównać wszystkie trzy wartości łącznie. Ponadto uzyskujesz int, ale zwracasz float. Albo, należy zdecydować, jaki rodzaj wartości, które mają zostać przetworzone, lub można utworzyć uogólnioną wersję, która współpracuje z wszelkiego rodzaju, które można porównać:

#include <algorithm> 

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

EDIT:

dwa sposoby, aby poprawić kod w coś, co działa na 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

jest to propozycja włączenia do biblioteki C++ pod N2485. Propozycja jest prosta, więc dodałem znaczący kod poniżej. Oczywiście zakłada to szablony variadic.

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

Załóżmy,

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

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

Jakoś w pierwszej linii poślizgnął się na "t" przy drugim paragrafie zamykającym – xoryouyou

1

1) Proste rozwiązanie:

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

2) Lepsze rozwiązanie (pod względem optymalizacji):

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

3) rozwiązanie zmodyfikowany (prosty ale skuteczny)

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

    int smallest = x; 

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

4) dowolną liczbę numerów:

dla N cyfr, należy przechowywać je w tablicy (tablica [n]), sortowanie tablica i pobierają tablicę [0], aby uzyskać najmniejszy.

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

Albo można po prostu użyć zdefiniować, aby utworzyć funkcję makro.

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

Unikaj makr w C++, kiedy możesz: http://stackoverflow.com/questions/4715831/why- is-define-bad-and-what-is-the-proper-substitute – jogojapan

18

Jeśli to możliwe, zalecamy stosowanie C++ 11 lub nowszy, który pozwala obliczyć pożądanego wyniku w/out realizacji własną funkcję (std::min). Jak już wspomniano w jednym z komentarzy, możesz zrobić

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

lub

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

który przechowuje minimum zmiennych x, y i z w zmiennej minimum typu T (zauważmy, że x, y i z muszą mieć ten sam typ lub muszą być do tego niejawnie wymienialne). Odpowiednio, to samo można zrobić, aby uzyskać maksimum: std::max({x, y, z}).

+2

To powinna być akceptowana odpowiedź, jest to przykład tego, że C++ 11 sprawia, że ​​tak wiele rzeczy jest o wiele łatwiejsze, a ludzie powinni go używać, chyba że mają niezmiernie dobry powód: spójrz, jak wiele bardziej złożonych i niepotrzebnych jest wszystkich innych odpowiedzi, pomimo tego, że napisano je w 2012 roku, kiedy ta doskonała składnia już istniała –

+0

Próbowałem 'int x = 1; int y = 2; int z = 3; std :: cout << std :: max ({x, y, z}); 'ale daje błąd kompilacji .. Jaki jest prawidłowy sposób na to? – xslittlegrass

+0

Możesz wypróbować flagę -std = C++ 11 na swoim kompilator. – ae0709

1

Można przechowywać je w wektorze i używać std::min_element na ten temat.

Na przykład:

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

int min = *std::min_element(values.begin(),values.end()); 
Powiązane problemy