Auswahl aus Array mit Bedingung



  • Also ich würde auf jeden Fall std::vector nehmen. Der ist dynamisch und bietet Zugriffsmöglichkeiten wie ein Array.

    Zum Suchen bietet sich eigentlich std::find_if() an. In deinem Beispiel sieht es aber so aus, als benötigtest du den Index für den Vergleichswert. Da wird find_if() wohl nicht funktionieren.



  • Danke, das sind schonmal zwei gute Stichworte.
    Schau mich mal bei den Algorithmen der STL um, ob da was passt.
    Weitere Vorschläge sind natürlcih willkommen 🙂



  • Hallo nochmal

    Also so ganz kapier ich das nicht.
    find_if liefert einfach das erste zurück, aber nicht das mit dem kleinsten Wert. min_element sieht gut aus, es gibt aber kein min_element_if oder?
    min_element benutzt ein Predicate oder den operator<. Ich müsste wohl ein eigenes Predicate machen und da die if Abfrage einbauen. Aber, ich hab die Vergleichswerte und Bedingungen ja nicht im Objekt, also extern. Wie kann ich darauf zugreifen?

    Kann man solche Algorithmen selber auch machen? Gibs dafür Anleitungen?

    Sorry, steh grad bisserl aufm Schlauch..



  • Hier ne kleinigkeit zum spielen:

    #include "stdafx.h"
    #include <iostream>
    #include <vector>
    #include <functional>
    #include <algorithm>
    #include <time.h>
    
    using namespace std;
    
    // Prüft auf kleiner Wert und > 0
    template<class Type>
       struct lessgreaterzero : public binary_function <Type, Type, bool> 
       {
          bool operator()(
             const Type& i, 
             const Type& a
          ) const
    	  {
    		return i < a && i > 0;
    	  }
       };
    
    int main(int argc, char* argv[])
    {
    	std::vector<int> var ;
    
    	//-------------------------------------------------------------------------------------
    	// Vector befüllen mit Zuallswerten und am Anfang eine 0 um zu prüfen ob die Funktion oben geht
    	srand(static_cast<int>(time(NULL)));
    	var.push_back(0);	// Testen ob das > 0 klappt
    	for(int i = 0; i < 100;++i)
    		var.push_back(rand());
    	//-------------------------------------------------------------------------------------
    
    	// Element suchen das passt
    	int index = -1;					// Index auf -1 um zu zeigen, das nichts gefunden wurde
    	vector<int>::iterator pos;		// Das Ergebnis von find_if speichern
    	pos = find_if(var.begin(),var.end(),bind2nd(lessgreaterzero<int>(),4000));	// Werte prüfen auf < 40000
    
    	if(pos != var.end())				// Wenn das Ende vom Vector erreicht, wurde nichts gefunden
    	 index = distance(var.begin(),pos);	// Ansonsten die Distanz von anfang bis gefundenen iterator errechnen
    
    	//-------------------------------------------------------------------------------------
    	// Alle Positionen die passen speichern und ausgeben
    	vector<int> positionen;			
    
    	pos = var.begin();				
    	do
    	{
    		pos = find_if(pos,var.end(),bind2nd(lessgreaterzero<int>(),4000));
    		if(pos == var.end())
    			break;
    		positionen.push_back(distance(var.begin(),pos));		
    
    	}while(pos++ != var.end());
    
    	// Alle index ausgeben die passen
    	cout<<"vector:\n"<<endl;
    	copy(var.begin(),var.end(),ostream_iterator<int>(cout,"\t"));
    	cout<<"\npositionen:\n"<<endl;
    	copy(positionen.begin(),positionen.end(),ostream_iterator<int>(cout,"\t"));
    
    	return 0;
    }
    


  • Danke, ja das sieht gut aus.
    Ich bräucht wohl etwas im Stil von:

    template <class ForwardIterator, class BinaryPredicate, class Predicate>
    ForwardIterator min_element_if (ForwardIterator first,
                                    ForwardIterator last,
                                    BinaryPredicate comp,
                                    Predicate       pred)
    {
        ForwardIterator result = last;
        for (ForwardIterator = it ; it != last; it++)
        {
            if (pred(it))
                if (comp(it, result))
                    result = it;
        }
        return result;
    }
    

    und dann noch zwei so structs

    template <class T>
    struct less_greater_zero : public binary_function <T, T, bool>
    {
        bool operator() (const T& arg1, const T& arg2) const
        {
            return i > 0 && arg1 < arg2;
        }
    };
    
    template <class T>
    struct has_item : public unary_function <T, bool>
    {
        bool operator() (const T& arg) const
        {
            // so und hier brauch ich Zugriff auf Bedingung[arg's Index] ausm ersten Post???
        }
    };
    

    Wie kann ich dem struct has_item Zugriff auf das bool-Array geben?
    Und wie komm ich an den Index von arg dran?

    Wenn das so ginge wär super, macht Spass 🙂



  • uups, sorry

    return i > 0 && arg1 < arg2;

    sollte

    return arg1 > 0 && arg1 < arg2;

    heissen



  • Wenn es wirklich noch von einem zweiten Array abhängt, könnte das hier zum spielen verleiten:

    #include <iostream>
    #include <vector>
    #include <functional>
    #include <algorithm>
    #include <time.h>
    
    using namespace std;
    
    // Prüft auf kleiner Wert und > 0
    template<class Type>
       struct lessgreaterzero : public binary_function <Type, Type, bool> 
       {
          bool operator()(
             const Type& i, 
             const Type& a
          ) const
    	  {
    		return i < a && i > 0;
    	  }
       };
    
    int main(int argc, char* argv[])
    {
    	std::vector<int> var ;
    	std::vector<bool> bed;
    	std::vector<int>  posi;
    
    	srand(static_cast<int>(time(NULL)));
    
    	for(int i = 0;i < 100;++i)
    	{
    		int rnd = rand();
    		var.push_back(rnd);
    		bed.push_back(rnd < rand());
    
    	}
    
    	for(vector<bool>::iterator pos = bed.begin();pos != bed.end();++pos)
    	{
    		// Man könnte sich noch das ständige erzeugen der struktur ersparen
    		if(*pos && lessgreaterzero<int>()(var[distance(bed.begin(),pos)],4000))
    			posi.push_back(distance(bed.begin(),pos));
    	}
    
    	// Alle index ausgeben die passen
    	cout<<"bed:\n"<<endl;
    	copy(bed.begin(),bed.end(),ostream_iterator<int>(cout,"\t"));
    	cout<<"vector:\n"<<endl;
    	copy(var.begin(),var.end(),ostream_iterator<int>(cout,"\t"));
    	cout<<"\npositionen:\n"<<endl;
    	copy(posi.begin(),posi.end(),ostream_iterator<int>(cout,"\t"));
    }
    


  • Danke, Knuddelbaer, das du meinen Spieltrieb förderst 🙂

    distance() wieder was gelernt :life:

    Grübel...💡
    Ich übergeb einfach nen Iterator auf den Bediungunsvector:

    template <class ForwardIterator, class BinaryPredicate, class PredicateIterator>
    ForwardIterator min_element_if (ForwardIterator first,
                                    ForwardIterator last,
                                    BinaryPredicate comp,
                                    PredicateIterator pred)
    {
        ForwardIterator result = last;
        for (ForwardIterator it = first; it != last; it++, pred++ )
        {
            if (*pred)
                if (comp(*it, *result))
                    result = it;
        }
        return result;
    }
    //Aufruf
    position = min_element_if( Vergleichswert.begin(), Vergleichswert.end(), less_greater_zero, Bedingung.begin()
    

    Heureka?

    ps: ich kompiliere grad im kopf :p



  • Da du eine direkte Zuordnung zwischen den beiden Werten (Zahl und Gültigkeit) hast, würde ich sie nicht in getrennten Arrays rumschleppen, sondern gemeinsam - also statt zweier Vectoren 'var' und 'bed' nur einen "vector<pair<int,bool> > var;" (da hast du auch die Gültigkeitsbedingung im Vergleich drin:

    template<class Type>
    struct lessbed : public binary_function <pair<Type,bool>, pair<Type,bool>, bool> 
    {
      bool operator()( const pair<Type,bool>& i, const pair<Type,bool>& a) const
      {
        return i.first < a.first && i.first*i.second > 0;
      }
    };
    


  • Die beiden Arrays sind aber unabhängig und werden unterschiedlich oft zu verschiedenen Zeiten und Quellen geändert. Von daher will ich die nicht zusammenfassen.
    Aber trotzdem eine gute Idee, danke nochmal.


Anmelden zum Antworten