Zahlenausgeber



  • #include <iostream>
    #include <algorithm>
    #include <array>
    
    int main()
    {
        const int number_of_numbers = 10;
        std::array<int, number_of_numbers> numbers;
    
        for(int i = 0; i < number_of_numbers; ++i)
        {
            int n;
            std::cin >> n;
            numbers[i] = n;
        }
    
         auto minmax = std::minmax_element(numbers.begin(), numbers.end());
         std::cout << "min: " << *minmax.first  << '\n'
                   << "max: " << *minmax.second << '\n';
    }
    


  • int min, max, zahl;
    cin>>zahl;
    min = max = zahl;
    for (int i=2; i<=10; ++i){
       cin >> zahl;
       min = std::min(min, zahl);
       max = std::max(max, zahl);
    }
    cout<<"max="<<max<<'\n';
    cout<<"min="<<min<<'\n';
    

    BTW:

    314159265358979 schrieb:

    <blödsinn>

    Gehts auch mit noch mehr Speicherverbrauch?



  • Gerne, ersetz array durch deque. Und mach aus int long long.
    Aber ich kann dich beruhigen, ich war gerade auf der Suche nach einer Lösung mit std::istream_iterator.


  • Mod

    314159265358979 schrieb:

    Aber ich kann dich beruhigen, ich war gerade auf der Suche nach einer Lösung mit std::istream_iterator.

    Das dumme an denen ist, das es trivial ist, mit einer beliebigen Menge von Eingaben zurecht zu kommen, wohingegen die Anforderung genau 10 Werte zu nehmen recht umständlich zu bauen ist. Schade, dass die Lehrer immer so konkrete Zahlen vorgeben 😞 . Das erschwert allgemeine Lösungen und verführt dazu, mit statischen Arrays zu arbeiten. Vermutlich denken, sie, sie machten die Aufgabe dadurch leichter.



  • Genau darüber habe ich gerade nachgedacht, aber ich bastle an einer Lösung 😉



  • Das dumme an denen ist, das es trivial ist, mit einer beliebigen Menge von Eingaben zurecht zu kommen, wohingegen die Anforderung genau 10 Werte zu nehmen recht umständlich zu bauen ist.[/quote]Das zeigt, wie unflexibel die Standardlib ist.



  • blödsinn schrieb:

    Das dumme an denen ist, das es trivial ist, mit einer beliebigen Menge von Eingaben zurecht zu kommen, wohingegen die Anforderung genau 10 Werte zu nehmen recht umständlich zu bauen ist.

    Das zeigt, wie unflexibel die Standardlib ist.[/quote]



  • #include <iostream>
    #include <iterator>
    #include <algorithm>
    #include <utility>
    
    template <typename Iterator>
    class take_n_iterator : public std::iterator<typename Iterator::value_type, typename Iterator::iterator_category>
    {
            unsigned n;
            Iterator iter;
    
    public:
            template <typename... Args>
            explicit take_n_iterator(unsigned n, Args&&... args)
                    : n(n)
                    , iter(std::forward<Args>(args)...)
            {}
    
            take_n_iterator()
                    : n(static_cast<unsigned>(-1))
            {}
    
            take_n_iterator& operator ++ ()
            {
                    --n;
                    ++iter;
    
                    return *this;
            }
    
            take_n_iterator operator ++ (int)
            {
                    take_n_iterator tmp(*this);
    
                    --n;
                    ++iter;
    
                    return tmp;
            }
    
            typename Iterator::reference operator * ()
            {
                    return *iter;
            }
    
            friend bool operator == (const take_n_iterator<Iterator>& lhs, const take_n_iterator<Iterator>& rhs)
            {
                    return (!lhs.n && rhs.n == static_cast<unsigned>(-1)) || lhs.n == rhs.n;
            }
    
            friend bool operator != (const take_n_iterator<Iterator>& lhs, const take_n_iterator<Iterator>& rhs)
            {
                    return !(lhs == rhs);
            }
    };
    
    int main()
    {
            auto minmax = std::minmax_element(take_n_iterator<std::istream_iterator<int>>(10, std::cin), take_n_iterator<std::istream_iterator<int>>());
    
            std::cout << "min: " << *minmax.first  << '\n'
                      << "max: " << *minmax.second << '\n';
    }
    

    Yay.


  • Mod

    Ach jetzt warst du schneller. Aber ich hatte auch Lust bekommen:

    #include <iterator>
    
    template <typename it_type> class counting_istream_iterator: 
      public std::iterator<std::input_iterator_tag, 
                           typename it_type::value_type, 
                           typename it_type::difference_type, 
                           typename it_type::pointer, 
                           typename it_type::reference>
    {
      typedef counting_istream_iterator<it_type> self_type;
      typedef std::iterator<std::input_iterator_tag, 
                           typename it_type::value_type, 
                           typename it_type::difference_type, 
                           typename it_type::pointer, 
                           typename it_type::reference>       base_type;
      it_type original;
      it_type current;
      typename base_type::difference_type counter;
    public:
      typedef typename it_type::char_type char_type;
      typedef typename it_type::traits_type traits_type;
      typedef typename it_type::istream_type istream_type;
    
      counting_istream_iterator(it_type const &it, typename base_type::difference_type const &init):
        original(it),
        current(it),
        counter(init)
      {}
    
      friend bool operator==(self_type const& lhs, self_type const&rhs)
      { return (lhs.original == rhs.original) and (lhs.counter == rhs.counter); }
      friend bool operator!=(self_type const& lhs, self_type const&rhs)
      { return !(lhs == rhs); }
    
      self_type& operator++() 
      {
        ++current;
        ++counter;
        return *this;
      }
      self_type& operator++(int)
      {
        self_type tmp = *this;
        ++*this;
        return tmp;
      }
    
      const typename base_type::reference operator*() const {return *current;}
      const typename base_type::pointer operator->() const {return &*current;}
    };
    
    #include <iostream>
    #include <algorithm>
    using namespace std;
    
    void foo (int i) 
    {
      cout << " " << i;
    }
    
    int main()
    {
      typedef istream_iterator<int> it_type;
      typedef counting_istream_iterator<it_type> c_it_type;
    
      it_type cin_it(cin);
      for_each(c_it_type(cin_it, 0), c_it_type(cin_it, 10), foo);
    }
    

    War doch ganz einfach 😃 .



  • .. und das ganze noch mal mit boost:

    #include <boost/iterator/iterator_adaptor.hpp>
    #include <iterator> // std::istream_iterator
    #include <iostream>
    #include <utility> // std::pair
    
    template< typename T >
    class CountingIstream : public boost::iterator_adaptor< CountingIstream< T >, std::istream_iterator< T > >
    {
    public:
        explicit CountingIstream( std::istream& in )
            : iterator_adaptor_( in )
            , m_count( 0 )
        {}
        explicit CountingIstream( int count = -1 )
            : iterator_adaptor_()
            , m_count( count )
        {}
        void increment()
        {
            ++base_reference();
            ++m_count;
        }
        bool equal( const CountingIstream& b ) const
        {
            return m_count == b.m_count || base() == b.base();
        }
    private:
        int m_count;
    };
    
    // -- für alle, die noch nicht über den neuen Standard verfügen
    template< typename I >
    std::pair< I, I > minmax_element( I first, I last )
    {
        I foundMin = first;
        I foundMax = first;
        if( first != last )
        {
            while( ++first != last )
            {
                if( *first < *foundMin )
                    foundMin = first;
                if( *foundMax < *first )
                    foundMax = first;
            }
        }
        return std::make_pair( foundMin, foundMax );
    }
    
    int main()
    {
        using namespace std;
        const int N = 10;
        cout << "Geben Sie " << N << " Zahlen und ein 'x' ein" << endl;
        const pair< CountingIstream< int >, CountingIstream< int > > res
            = minmax_element( CountingIstream< int >( cin ), CountingIstream< int >( N ) );
        if( res.first != CountingIstream< int >() )
            cout << "Die kleinste Zahl war: " << *res.first << " und die groesste " << *res.second << endl;
        return 0;
    }
    

    und dem kleinen Schönheitsfehler, dass am Ende noch mal eine nicht leere Zeile eingegeben werden muss, deren Inhalt aber keine Rolle spielt. Daher das "und ein 'x'". Das folgt aus der Eigenheit des std::istream_iterators.

    SeppJ schrieb:

    Das dumme an denen ist, das es trivial ist, mit einer beliebigen Menge von Eingaben zurecht zu kommen, wohingegen die Anforderung genau 10 Werte zu nehmen recht umständlich zu bauen ist. Schade, dass die Lehrer immer so konkrete Zahlen vorgeben 😞 . Das erschwert allgemeine Lösungen und verführt dazu, mit statischen Arrays zu arbeiten. Vermutlich denken, sie, sie machten die Aufgabe dadurch leichter.

    so isses!

    Gruß
    Werner



  • Das dumme an denen ist, das es trivial ist, mit einer beliebigen Menge von Eingaben zurecht zu kommen, wohingegen die Anforderung genau 10 Werte zu nehmen recht umständlich zu bauen ist. Schade, dass die Lehrer immer so konkrete Zahlen vorgeben 😞 . Das erschwert allgemeine Lösungen und verführt dazu, mit statischen Arrays zu arbeiten. Vermutlich denken, sie, sie machten die Aufgabe dadurch leichter.

    Naja, angenommen eine 0 signalisiert das Ende der Eingabe, würde doch auch nichts einfacher machen, oder?


  • Mod

    Ethon schrieb:

    Naja, angenommen eine 0 signalisiert das Ende der Eingabe, würde doch auch nichts einfacher machen, oder?

    Nein, warum sollte es? Null ist nix besonderes. Aber wenn man sagen würde, dass man Zahlen bis zum Ende des Streams lesen soll, dann wäre es (wie viele Anfängerprobleme) ein typischer STL-Algorithms Zweizeiler.


Anmelden zum Antworten