Foros del Web » Programación para mayores de 30 ;) » C/C++ »

Como se utiliza Función Objeto? :( Ayuda porfavor !!!!

Estas en el tema de Como se utiliza Función Objeto? :( Ayuda porfavor !!!! en el foro de C/C++ en Foros del Web. Hola, necesito hacer una práctica para aprobar una asignatura de la carrera en la que me piden usar una función objeto. Yo tengo el código ...
  #1 (permalink)  
Antiguo 23/06/2010, 05:32
 
Fecha de Ingreso: julio-2009
Mensajes: 16
Antigüedad: 15 años, 3 meses
Puntos: 0
Como se utiliza Función Objeto? :( Ayuda porfavor !!!!

Hola, necesito hacer una práctica para aprobar una asignatura de la carrera en la que me piden usar una función objeto. Yo tengo el código siguiente:
Código C++:
Ver original
  1. #include <iostream>
  2. #include <vector>
  3. #include <iterator>
  4. #include <algorithm>
  5. #include <map>
  6.  
  7. using namespace std;
  8.  
  9. map<string,int> d;
  10.  
  11. void mifuncion (pair<string, string> t)
  12. {
  13.   map<string, int>::iterator i;
  14.   i = d.find(t.first);
  15.   if (i != d.end()) // Existe clave
  16.     d[t.first] += 1;
  17.   else
  18.       d.insert(i, pair<string,int>(t.first,1));
  19. }
  20.  
  21.  
  22. int main ()
  23. {
  24.         multimap<string, string> multi;
  25.  
  26.         cout << "Vaya insertando las claves en la forma K1, K2" << endl;
  27.         cout << "Presione ctrl+z para finalizar" << endl;
  28.  
  29.         string k1, k2;
  30.  
  31.         while (cin >> k1)
  32.         {
  33.             cin >> k2;
  34.             multi.insert(pair<string, string>(k1, k2));
  35.         }
  36.  
  37.         cout << endl << "Elementos del multidiccionario: " << endl;
  38.         for (multimap<string, string>::iterator it = multi.begin(); it != multi.end(); ++it)
  39.            {
  40.                cout << "  [" << (*it).first << ", " << (*it).second << "]" << endl;
  41.            }
  42.  
  43.         for_each (multi.begin(), multi.end(), mifuncion);
  44.  
  45.         cout << endl << "Elementos del diccionario: " << endl;
  46.         for (map<string, int>::iterator it = d.begin(); it != d.end(); ++it)
  47.            {
  48.                cout << "  [" << (*it).first << ", " << (*it).second << "]" << endl;
  49.            }
  50.  
  51.         return 0;
  52. }

Cómo es entonces haciéndolo con una función objeto sin necesidad de declarar el diccionario global?

Muchas gracias !!
  #2 (permalink)  
Antiguo 23/06/2010, 12:09
 
Fecha de Ingreso: febrero-2003
Ubicación: D.F.
Mensajes: 163
Antigüedad: 21 años, 9 meses
Puntos: 22
Respuesta: Como se utiliza Función Objeto? :( Ayuda porfavor !!!!

Un poco de info en español, aunque en estos temas es más completa la información si la buscas en ingles.

Una pósible solución:
Código:
#include <iostream>
#include <vector>
#include <iterator>
#include <algorithm>
#include <map>
#include <string>

using namespace std;

class MiFuncion{
	map<string, int>& d;
public:
	MiFuncion(map<string, int>& rd):d(rd){}
	void operator()(pair<string, string> t){
		map<string, int>::iterator i;
		i = d.find(t.first);
		if (i != d.end()) // Existe clave
			d[t.first] += 1;
		else
			d.insert(i, pair<string,int>(t.first,1));
	}
};

int main ()
{
	multimap<string, string> multi;
	map<string,int> d;

	cout << "Vaya insertando las claves en la forma K1, K2" << endl;
	cout << "Presione ctrl+z para finalizar" << endl;

	string k1, k2;

	while (cin >> k1)
	{
		cin >> k2;
		multi.insert(pair<string, string>(k1, k2));
	}

	cout << endl << "Elementos del multidiccionario: " << endl;
	for (multimap<string, string>::iterator it = multi.begin(); it != multi.end(); ++it)
	{
		cout << "  [" << (*it).first << ", " << (*it).second << "]" << endl;
	}

	for_each (multi.begin(), multi.end(), MiFuncion(d));

	cout << endl << "Elementos del diccionario: " << endl;
	for (map<string, int>::iterator it = d.begin(); it != d.end(); ++it)
	{
		cout << "  [" << (*it).first << ", " << (*it).second << "]" << endl;
	}

	return 0;
}
La parte del código en la que debes poner atención está resaltada en rojo.

Saludos.
  #3 (permalink)  
Antiguo 23/06/2010, 12:39
 
Fecha de Ingreso: julio-2009
Mensajes: 16
Antigüedad: 15 años, 3 meses
Puntos: 0
Respuesta: Como se utiliza Función Objeto? :( Ayuda porfavor !!!!

Muchisimas gracias !! :)
  #4 (permalink)  
Antiguo 23/06/2010, 13:10
 
Fecha de Ingreso: julio-2009
Mensajes: 16
Antigüedad: 15 años, 3 meses
Puntos: 0
Respuesta: Como se utiliza Función Objeto? :( Ayuda porfavor !!!!

Perdonar que vuelva a dar la lata, la solución que me disteis es correcta, pero ahora necesito meter los elementos del diccionario con un istream_iterator, y por mas que lo intento, no me sale....

Lo que tengo puesto es esto, pero no se por que al compilar me da muchos errores...
Código C++:
Ver original
  1. [......]
  2.  
  3. int main ()
  4. {
  5.     multimap<string, string> multi;
  6.     map<string,int> d;
  7.  
  8.     cout << endl << endl << "Vaya insertando las claves en la forma K1 (intro), K2 (intro)" << endl;
  9.     cout << "Presione <Ctrl+D> para finalizar" << endl << endl;
  10.  
  11.     /*string k1, k2;
  12.  
  13.     while (cin >> k1)
  14.     {
  15.         cin >> k2;
  16.         multi.insert(pair<string, string>(k1, k2));
  17.     }
  18.        */
  19.    
  20.     istream_iterator<pair<string, string>> in (cin);
  21.  
  22.  
  23.     copy (in, istream_iterator<pair<string, string>>(), multi.begin());
  24.  
  25. [..........]


Espero me podáis volver a ayudar, muchas gracais !!!
  #5 (permalink)  
Antiguo 23/06/2010, 16:22
 
Fecha de Ingreso: febrero-2003
Ubicación: D.F.
Mensajes: 163
Antigüedad: 21 años, 9 meses
Puntos: 22
Respuesta: Como se utiliza Función Objeto? :( Ayuda porfavor !!!!

En terminos generales se puede decir que va bien lo que estás haciendo pero ojo con lo siguiente:

istream_iterator<pair<string, string>> in (cin);

La clase pair no tiene sobrecargado el operador de inserción ">>", esto es necesario para trabajar con istream_iterator.

Para resolver esto de forma simple, puedes crearte una nueva clase digamos StrPair que herede de pair y que solo maneje pares de strings para que puedas sobrecargar el operador de inserción.

Ejemplo:

Código:
class StrPair : public pair<string, string>{
public:
	StrPair(const string& s1 = "", const string& s2 = ""):pair(s1, s2){}
	friend istream& operator>>(istream& is, StrPair& sp){
		return is >> sp.first >> sp.second;
	}
};
También puedes utilizar inserter en la función copy.

Ejemplo:
Código C++:
Ver original
  1. #include <iostream>
  2. #include <vector>
  3. #include <iterator>
  4. #include <algorithm>
  5. #include <map>
  6. #include <string>
  7. #include <iterator>
  8.  
  9. using namespace std;
  10.  
  11. class MiFuncion{
  12.     map<string, int>& d;
  13. public:
  14.     MiFuncion(map<string, int>& rd):d(rd){}
  15.     void operator()(pair<string, string> t){
  16.         map<string, int>::iterator i;
  17.         i = d.find(t.first);
  18.         if (i != d.end()) // Existe clave
  19.             d[t.first] += 1;
  20.         else
  21.             d.insert(i, pair<string,int>(t.first,1));
  22.     }
  23. };
  24.  
  25. class StrPair : public pair<string, string>{
  26. public:
  27.     StrPair(const string& s1 = "", const string& s2 = ""):pair(s1, s2){}
  28.     friend istream& operator>>(istream& is, StrPair& sp){
  29.         return is >> sp.first >> sp.second;
  30.     }
  31. };
  32.  
  33. int main ()
  34. {
  35.  
  36.     multimap<string, string> multi;
  37.     map<string,int> d;
  38.  
  39.     cout << "Vaya insertando las claves en la forma K1, K2" << endl;
  40.     cout << "Presione ctrl+z para finalizar" << endl;
  41.  
  42.     copy(istream_iterator<StrPair>(cin), istream_iterator<StrPair>(), inserter(multi, multi.begin()));
  43.  
  44.     cout << endl << "Elementos del multidiccionario: " << endl;
  45.     for (multimap<string, string>::iterator it = multi.begin(); it != multi.end(); ++it)
  46.     {
  47.         cout << "  [" << (*it).first << ", " << (*it).second << "]" << endl;
  48.     }
  49.  
  50.     for_each (multi.begin(), multi.end(), MiFuncion(d));
  51.  
  52.     cout << endl << "Elementos del diccionario: " << endl;
  53.     for (map<string, int>::iterator it = d.begin(); it != d.end(); ++it)
  54.     {
  55.         cout << "  [" << (*it).first << ", " << (*it).second << "]" << endl;
  56.     }
  57.  
  58.     return 0;
  59. }
  #6 (permalink)  
Antiguo 23/06/2010, 21:22
 
Fecha de Ingreso: julio-2009
Mensajes: 16
Antigüedad: 15 años, 3 meses
Puntos: 0
Respuesta: Como se utiliza Función Objeto? :( Ayuda porfavor !!!!

Buff, muchisimas gracias!!!..... una ultima pregunta, supongo, sería lógico vamos... si quisiera mostrar los elementos con un ostream_iterator es analogo a lo que me has puesto tu para el istream no? Es decir, algo así... ???

Código C++:
Ver original
  1. [.....]
  2.  
  3. class StrPair2 : public pair<string, string>{
  4. public:
  5.     StrPair2(const string& s1 = "", const string& s2 = ""): pair<string, string>::pair(s1, s2){}
  6.     friend ostream& operator<<(ostream& os, StrPair& sp){
  7.         return os << "[" << sp.first << ", " << sp.second << "]";
  8.     }
  9. };
  10.  
  11. int main ()
  12. {
  13.     multimap<string, string> multi;
  14.     map<string,int> d;
  15.  
  16.     cout << endl << endl << "Vaya insertando las claves en la forma K1 (intro), K2 (intro)" << endl;
  17.     cout << "Presione <Ctrl+D> para finalizar" << endl << endl;
  18.  
  19.         copy(istream_iterator<StrPair>(cin), istream_iterator<StrPair>(), inserter(multi, multi.begin()));
  20.  
  21.     cout << endl << endl << "Elementos del multidiccionario: " << endl;
  22.        
  23.         ostream_iterator<StrPair2> out (cout, "\n");
  24.  
  25.     copy (multi.begin(), multi.end(), out);
  26.  
  27. [..........]


Creo que debo estar cerca de la solución, aunque sé que así no debe ser por los errores de compilación jejeje Graciassss

Última edición por Phass; 24/06/2010 a las 04:23
  #7 (permalink)  
Antiguo 24/06/2010, 17:37
 
Fecha de Ingreso: febrero-2003
Ubicación: D.F.
Mensajes: 163
Antigüedad: 21 años, 9 meses
Puntos: 22
Respuesta: Como se utiliza Función Objeto? :( Ayuda porfavor !!!!

Para los datos de entrada sabemos que con utilizar un pair<string, string> es suficiente, por eso una solución era crear el StrPair, para el ostream_iterator esto cambia un poco, ya que los datos provienen de dos tipos diferentes de datos, esto es, un pair<string, string> y un pair<string, int> del multimap y map respectivamente, por esto último, lo que conviene ahora es reescribir la clase que hereda de pair de manera genérica y sobrecargando ambos operadores "extracción" e "inserción" para la misma.

Ejemplo:
Código C++:
Ver original
  1. #include <iostream>
  2. #include <vector>
  3. #include <iterator>
  4. #include <algorithm>
  5. #include <map>
  6. #include <string>
  7. #include <iterator>
  8.  
  9. using namespace std;
  10.  
  11. class MiFuncion{
  12.     map<string, int>& d;
  13. public:
  14.     MiFuncion(map<string, int>& rd):d(rd){}
  15.     void operator()(pair<string, string> t){
  16.         map<string, int>::iterator i;
  17.         i = d.find(t.first);
  18.         if (i != d.end()) // Existe clave
  19.             d[t.first] += 1;
  20.         else
  21.             d.insert(i, pair<string,int>(t.first,1));
  22.     }
  23. };
  24.  
  25. template<class T1, class T2>
  26. class MyPair : public pair<T1, T2>{
  27. public:
  28.     MyPair():pair<T1, T2>(){}
  29.     MyPair(T1 t1, T2 t2):pair<T1, T2>(t1, t2){}
  30.     template <class U, class V>
  31.     MyPair(const pair<U,V> &rp):pair<T1, T2>(rp){ }
  32.     friend istream& operator>>(istream& is, MyPair& pa){
  33.         return is >> pa.first >> pa.second;
  34.     }
  35.  
  36.     friend ostream& operator<<(ostream& os, const MyPair& pa){
  37.         return os << "[" << pa.first << ", " << pa.second << "]";
  38.     }
  39. };
  40.  
  41.  
  42.  
  43. int main ()
  44. {
  45.  
  46.     multimap<string, string> multi;
  47.     map<string,int> d;
  48.  
  49.     cout << "Vaya insertando las claves en la forma K1, K2" << endl;
  50.     cout << "Presione ctrl+z para finalizar" << endl;
  51.  
  52.     copy(istream_iterator<MyPair<string, string> >(cin), istream_iterator<MyPair<string, string> >(), inserter(multi, multi.begin()));
  53.     cout << endl << "Elementos del multidiccionario: " << endl;
  54.     copy (multi.begin(), multi.end(), ostream_iterator<MyPair<string, string> >(cout, "\n"));
  55.  
  56.  
  57.     for_each (multi.begin(), multi.end(), MiFuncion(d));
  58.     cout << endl << "Elementos del diccionario: " << endl;
  59.     copy (d.begin(), d.end(), ostream_iterator<MyPair<string, int> >(cout, "\n"));
  60.  
  61.     return 0;
  62. }

Fíjate que en la clase MyPair el constructor copia es un template, es importante hacerlo de esta forma ya que en la clase pair así está definido, esto lo que te permite es crear un nuevo pair a partir de otro que tenga el mismo tipo de datos o diferente pero cuya conversión de los mismos resulte válida.

Saludos.

Última edición por fightmx; 25/06/2010 a las 07:06
  #8 (permalink)  
Antiguo 25/06/2010, 03:20
 
Fecha de Ingreso: julio-2009
Mensajes: 16
Antigüedad: 15 años, 3 meses
Puntos: 0
Respuesta: Como se utiliza Función Objeto? :( Ayuda porfavor !!!!

Muchas gracias !! Pero algo debe estar mal en el copy porque no me compila me da errores asi algo extraños de candidaturas :S :( Ademas, el profesor me dijo que no podia utilizar una clase pair heredada, sino la de stl y ahora si que me da errores cuando lo intento cambiar...... pFF :(

Código C++:
Ver original
  1. [.....................]
  2.  
  3. /*template<class T1, class T2>
  4. class MyPair : public pair<T1, T2>{
  5. public:
  6.     MyPair():pair<T2, T2>::pair(){}
  7.     MyPair(T1 t1, T2 t2):pair<T1, T2>::pair(t1, t2){}
  8.     MyPair(const MyPair<T1, T2> &rp):pair<T1, T2>::pair(rp){ }
  9.     friend istream& operator>>(istream& is, MyPair& pa){
  10.         return is >> pa.first >> pa.second;
  11.     }
  12.  
  13.     friend ostream& operator<<(ostream& os, const MyPair& pa){
  14.         return os << "[" << pa.first << ", " << pa.second << "]";
  15.     }
  16. };
  17. */
  18. template <class K, class V>
  19. istream & operator>> (istream & is, pair<K, V>& pa)
  20. {
  21.     return is >> pa.first >> pa.second;
  22. }
  23.  
  24. template<class K, class V>
  25. ostream & operator<< (ostream & os, const pair<K, V> & pa)
  26. {
  27.     return os << "[" << pa.first << ", " << pa.second << "]";
  28. }
  29.  
  30. [............]

Es logico que me salgan muchisimos mas errores de compilacion que antes? :S

EDIT: ya está solucionado, era encapsular los operadores en el namespace

MUCHISIMAS GRACIAS POR TODO FIGHTMX !!!

Última edición por Phass; 25/06/2010 a las 05:05
  #9 (permalink)  
Antiguo 25/06/2010, 07:31
 
Fecha de Ingreso: febrero-2003
Ubicación: D.F.
Mensajes: 163
Antigüedad: 21 años, 9 meses
Puntos: 22
Respuesta: Como se utiliza Función Objeto? :( Ayuda porfavor !!!!

Así es, omití el detalle del espacio al momento de invocar templates anidados:

ostream_iterator<MyPair<string, string>>(); // mal
ostream_iterator<MyPair<string, string> >(); // bien

y salia sobrando un typename. (edité el código anterior con la corrección).

Lo último que mencionas funciona:
Código C++:
Ver original
  1. namespace std{
  2.     template<class T1, class T2>
  3.     istream& operator>>(istream& is, pair<T1, T2>& p){
  4.         return is >> p.first >> p.second;
  5.     }
  6.     template<class T1, class T2>
  7.     ostream& operator<<(ostream& os, const pair<T1, T2>& p){
  8.         return os << "[" << p.first << ", " << p.second << "]";
  9.     }
  10. }
Solo que tendrás que definir el operador dentro del namespace std, algo que no es recomendable y que no siempre funciona, es para que lo tomes en cuenta.

Saludos.

Etiquetas: objeto
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta

SíEste tema le ha gustado a 1 personas




La zona horaria es GMT -6. Ahora son las 09:46.