Menú

Mostrar Mensajes

Esta sección te permite ver todos los mensajes escritos por este usuario. Ten en cuenta que sólo puedes ver los mensajes escritos en zonas a las que tienes acceso en este momento.

Mostrar Mensajes Menú

Mensajes - amchacon

#191
Todo eso está definido en las Windows API. De hecho cualquier función que veas relevante del sistema estará definida en las windows API.

El tema de crear procesos en cuestión, buscando en google "createprocess windows api" encontré la página de referencia:
http://msdn.microsoft.com/en-us/library/windows/desktop/ms682425%28v=vs.85%29.aspx

¿Esperabas una función tan sencilla como la de fork? Amigo mío, Microsoft es un artista en el arte de complicarse la vida, todo lo que veas desarrollado por él suele estar complicado hasta el exceso.

Eso sí, aunque se complica mucho sus herramientas siempre son las mejores en Windows. No vas a encontrar ninguna que haga más que las suyas.

Por cierto, si te da igual usar hilos o procesos. Quizás te interesa C++11, es el estándar del 2011 de C++ y una de sus novedades son las librerías de hilos:
http://en.cppreference.com/w/cpp/thread

De lo mejor que vas a encontrar en programación concurrente y te funcionará tanto en linux como en windows (ya que forma parte de la librería estándar).
#192
¡Hey! ¡Que recuerdos!

Yo también hize una calculadora de esas en mis tiempos, la mía además hacía funciones matematicas (sin,cos,tan,log,sqrt... todas recreadas con la libreria estandar y a correr xD). También tenía algunas macros como el número pi o el numero de euler. Lo que más me costo son los anidamientos así:
Citarsin(sin(2))

Aunque yo no usaba pila, sino un enfoque más simplista: "Divide y venceras". Si tenía la siguiente expresión:

Citar2 + 3 * 2

La transformaba:
Citar2 + 6

Y la volvía a reinterpretar.

El código es de hace 1 año casi, mucho ha llovido desde entonces. Hay muchísimas cosas que haría de otra forma (como la función convertirnumero, que tiene bastantes aberraciones ;D).

Código (cpp) [Seleccionar]
#include <iostream>
#include <cmath>
#include <list>
#include <sstream>
#include <map>

/** Fecha: 05/07/2013

Analiza una expressión en formato texto y resuelve las operaciones pertinentes

*/

const int MAX =5;

using namespace std;

inline void ResolverParentesis(string &Entrada,short &i);
double Ejecucion(string &Entrada);
double ConvertirNumero(string &Entrada,int &Index);
double RealizarOperacion(string &Entrada);
int ObtenerOperadorAnterior(string &Entrada,int Index);
double RealizarOperacion(string &Entrada);

double ConvertirAngulo(double Entrada)
{
    return Entrada *3.141592/180;
}

inline void ResolverFunciones(string& Entrada);

const char Operaciones[MAX] = {'^','/','*','+','-'};

typedef double (*Puntero_A_Funcion)(double);

map<string,Puntero_A_Funcion> Punteros;
map<string,double> Macros;

int main()
{
    Punteros["sin"] = sin;
    Punteros["cos"] = cos;
    Punteros["tan"] = tan;

    Punteros["sinh"] = sinh;
    Punteros["cosh"] = cosh;
    Punteros["tanh"] = tanh;

    Punteros["asin"] = asin;
    Punteros["acos"] = acos;
    Punteros["atan"] = atan;

    Punteros["asinh"] = asinh;
    Punteros["acosh"] = acosh;
    Punteros["atanh"] = atanh;

    Punteros["cbrt"] = cbrt;
    Punteros["sqrt"] = sqrt;

    Punteros["log"] = log;
    Punteros["log10"] = log10;

    Punteros["abs"] = abs;

    Punteros["rad"] = ConvertirAngulo;

    Macros["pi"] = 3.141592654;
    Macros["euler"] = 2.7182818;
    Macros["aureo"] = 1.61803398;
    Macros["ans"] = 0;

    string Expresion;
    cout<<"Calculadora parser por amchacon"<<endl<<endl;

    cout<<"Soporte para las siguientes funciones matematicas: "<<endl<<endl;

    short Contador = 0;

    for (auto it = Punteros.begin(); it != Punteros.end(); it++)
    {
        cout<<it->first<<"\t";
        Contador++;
        if (Contador == 3)
        {
            Contador = 0;
            cout<<endl;
        }
    }

    cout<<endl<<endl<<"Constantes definidas: "<<endl;

    Contador = 0;
    for (auto it = Macros.begin(); it != Macros.end(); it++)
    {
        cout<<it->first<<"\t";
        Contador++;
        if (Contador == 3)
        {
            Contador = 0;
            cout<<endl;
        }
    }

    cout<<endl<<endl;

    while(1)
    {

        cout << "Introduce tu expresion: " << endl;
        getline(cin,Expresion);

        try
        {
            cout<<endl<<"El resultado es: "<<RealizarOperacion(Expresion);
        }
        catch(const char* c)
        {
            cout<<endl<<c;
        }

        cout<<endl<<endl<<endl;

    }
    return 0;
}

double RealizarOperacion(string &Entrada)
{
    int Index;

    if (Entrada.empty())
        throw "Error, expresion vacia";

    // Macros

    for (auto it = Macros.begin();it != Macros.end();it++)
    {
        Index = Entrada.find(it->first);

        if (Index != -1)
        {
            Entrada.erase(Index,it->first.size());
            stringstream Cosita;
            Cosita<<it->second;
            Entrada.insert(Index,Cosita.str());
        }
    }

    // Funciones matemáticas

    ResolverFunciones(Entrada);
    Macros["ans"] =  Ejecucion(Entrada);

    return Macros["ans"];
}

/** Función principal que resuelve la operación **/

double Ejecucion(string &Entrada)
{
    // Comprobando paréntesis

    for (short i = 0; i < Entrada.size(); i++)
    {
        if (Entrada[i] == '(') // Si hay un parentesis
        {
            ResolverParentesis(Entrada,i);
        }
    }

    /** Empezamos a resolver las operaciones **/

    for (short j = 0; j < MAX; j++) // Recorremos las 4 operaciones
        for (short i = 0; i < Entrada.size(); i++)
        {
            if (Entrada[i] == Operaciones[j]) // Si encontramos nuestra operación
            {
                int Inicio = ObtenerOperadorAnterior(Entrada,i); // Buscamos el operador que le precede (o el 0)

                if (Inicio == -1)
                    continue;

                int Index = Inicio; // El index es nuestra posicion actual
                int Tam = Index; // El tamanyo de la expresion que contiene nuestra operacion
                double Operacion = ConvertirNumero(Entrada,Index); // Obtenemos el primer numero

                // Eliminando espacios en blanco...

                while(Entrada[Index] == ' ')
                {
                    Index++;
                }

                Index++; // Eliminamos el operador

                double Numerito = ConvertirNumero(Entrada,Index); // Obtenemos el segundo numero de la operacion

                switch (j) // Dependiendo de la operacion que estabamos buscando hacemos una cosa o otra
                {
                case 0:
                    Operacion = pow(Operacion,Numerito);
                    break;
                case 1:
                    if (!Numerito)
                        throw "Error, division por cero";
                    Operacion /= Numerito;
                    break;
                case 2:
                    Operacion *= Numerito;
                    break;
                case 3:
                    Operacion += Numerito;
                    break;
                case 4:
                    Operacion -= Numerito;
                }

                // El tamanyo de nuestra expresión es final (Index) menos inicio

                Tam = Index-Inicio;

                // Actualizamos nuestra expression

                Entrada.erase(Inicio,Tam); // Borramos la antigua

                // Obtenemos la expression númerica de la nueva

                stringstream Buffer;
                Buffer<<Operacion;

                // Y la insertamos

                Entrada.insert(Inicio,Buffer.str());

                // Volvemos al principio

                i = 0;
            }
        }

    /** Ahora unicamente nos queda una expresión númerica, la pasamos a número y la devolvemos **/

    int Index = 0;
    return ConvertirNumero(Entrada,Index);
}

inline void ResolverFunciones(string& Entrada)
{
    int Index;
    for (auto it = Punteros.begin(); it != Punteros.end(); it++)
    {
        Index = Entrada.find(it->first);
        if (Index != -1)
        {
            int Inicio = Index;
            Index = Inicio+it->first.size();
            while(Entrada[Index] == ' ')
            {
                Index++;
            }
            short aux = Index;
            if (Entrada[Index] == '(')
            {
                 ResolverParentesis(Entrada,aux);
            }


            if ((Entrada[Index] >= '0' && Entrada[Index] <= '9') || (Entrada[Index] == '-') || Entrada[Index] == '+')
            {
                stringstream Cosita;
                Cosita<<it->second(ConvertirNumero(Entrada,Index));
                Entrada.erase(Inicio,Index-Inicio);
                Entrada.insert(Inicio,Cosita.str());
            }
        }
    }
}

inline void ResolverParentesis(string &Entrada,short &i)
{
    short Toque = 1; // Buscamos el siguiente parentesis
    string Buffer; // Aquí guardaremos la expresión inscrita en el paréntesis
    bool Correcto = false; // Variable que comprueba si se llego al final del parentesis

//    for (auto it = Punteros.begin(); it != Punteros.end(); it++)
//    {
//        if (Entrada)
//    }

    for (short j = (i+1); j < Entrada.size(); j++)
    {
        Buffer+= Entrada[j]; // Vamos guardando la expresion...

        /** Si encontramos un paréntesis anidado, tendremos que encontrar el siguiente cierre de paréntesis **/

        if (Entrada[j] == '(')
            Toque++;
        if (Entrada[j] == ')') // Cierre de parentesis, un parentesis menos que buscar
            Toque--;

        if (Toque == 0) // Si ya hemos terminado
        {
            Buffer.erase(Buffer.size()-1,1); // Borramos el ')'

            ResolverFunciones(Buffer);

            /** Aplicamos recursividad, resolvemos la operación inscrita en el paréntesis **/

            Ejecucion(Buffer);

            /** Borramos nuestro paréntesis y lo sustituimos por nuestro nuevo valor **/

            Entrada.erase(i,j-i+1);
            Entrada.insert(i,Buffer);
            i = 0;
            Correcto = true; // Finalizo correctamente
            break;
        }
    }

    if (!Correcto) // Si no se encontró el final del paréntesis
    {
        throw "No se encontro el fin del parentesis \n";
    }
}

// Dada la posición de un operador, devuelve la posición contigua del operador anterior (o 0)

int ObtenerOperadorAnterior(string &Entrada,int Index)
{
    Index--; // nos saltamos nuestro operador
    if (Index < 0)
        return -1;

    // Vamos recorriendo nuestra entrada hasta que lo encontramos

    while (Entrada[Index] != '+' && Entrada[Index] != '-' && Entrada[Index] != '*' && Entrada[Index] != '/' && Index != 0)
    {
        Index--;
    }

    if (Index != 0)
        return Index+1; // Devolvemos la posición contigua
    else
        return 0;
}

/** El santo grial de todo, convierte una expressión de texto en un número **/

double ConvertirNumero(string &Entrada,int &Index)
{
    list<double> Enteros;
    list<double> Decimales;
    short aux;
    short signo = 1;

    // Nos saltamos los espacios en blanco

    while(Entrada[Index] == ' ')
    {
        Index++;
    }

    if (Entrada[Index] == '-')
    {
        signo = -1;
        Index++;
    }

    /** Ahora debería haber números, de lo contrario tenemos un error **/

    if (Entrada[Index] < '0' || Entrada[Index] > '9')
    {
        stringstream buffer;
        buffer<<"Error de sintaxis, desconocido elemento: '"<<Entrada[Index]<<"' en la posicion: "<<Index+1;
        throw buffer.str().c_str();
    }

    /** Añadimos los enteros **/

    while (Entrada[Index] >= '0' && Entrada[Index] <= '9' && Index < Entrada.size())
    {
        Enteros.push_back(Entrada[Index]-48);
        //cout<<Cosa[i]<<endl;
        Index++;
    }

    /** Si a continuación encontramos un punto o una coma, esque hay numeros a continuacion **/

    if (Entrada[Index] == '.' || Entrada[Index] == ',')
    {
        bool Activado = false;
        Index++;
        while (Entrada[Index] >= '0' && Entrada[Index] <= '9' && Index < Entrada.size())
        {
            Decimales.push_back(Entrada[Index]-48);
            Index++;
            Activado = true;
        }
        if (!Activado)
        {
            throw "Error de sintaxis, se insertó un punto pero no se añadió ningun decimal";
        }
    }
    double Numero = 0; // El valor que devolveremos
    aux = 0;

    /** Recorremos los enteros y lo pasamos a número. Como tenemos las cifras simplemente es sumarlas **/

    for (auto it = Enteros.begin(); it != Enteros.end(); it++)
    {
        Numero += *it*pow(10,Enteros.size()-aux-1);
        aux++;
    }
    aux = 0;

    /** Idem, pero para los decimales **/

    if (!Decimales.empty())
        for (auto it = Decimales.begin(); it != Decimales.end(); it++)
        {
            Numero += *it/(pow(10,(aux))*10);
            aux++;
        }

    Numero *= signo;
    return Numero;
}


El código en cuestión usa el estándar C++11. Tendrás que activar ese estandar en el compilador.

Creo que tu sistema es mejor, pero podrías utilizar de este código el objeto map que uso para hacer las funciones matemáticas (sin,cos,tan...).

¿Críticas a tú código? Que es muy poco modular.
#193
Los enteros de 64 bits existen incluso compilando en 32 bits.

Su nombre suele ser long long, aunque si usas C++ es más correcto usar int_64t.

Los long long son compatibles con las funciones matematicas (siempre que no te pases y te salgas del rango xD).
#194
Yo me hize un empaquetador de esos, los creaba en formato AMC (patente por registrar ;D).

Hacer un empaquetador sin compresión no es muy dificil. Para empaquetar:

- Te pones una carpeta donde estarán los archivos a empaquetar, los vas listando uno a uno. Para cada archivo:
       - Coges tu tamaño y lo escribes en el paquete.
       - Escribes el tamaño del nombre, apto seguido escribes el nombre.
       - Copias el contenido del archivo al paquete.
       - Mientras queden archivos por listar vuelve al paso 1.

Y para desempaquetar algo parecido:

- Te coges una carpeta de destino, abres el paquete y procedes a la inversa:

        - Lees el tamaño (llamemoslo TAM_S) , lees el tamaño del nombre (llamemoslo TAM_M).
        - Los siguientes TAM_M bytes serán del nombre, los lees y creas un archivo con ese nombre.
        - Los siguientes TAM_S bytes serán del archivo, vuelcalos al nuevo archivo que has creado.
        - Repetir hasta que hayas recorrido el paquete entero.
#195
No recomiendo para nada usar pow aquí, es muy mala práctica ya que pow es una función relativamente costosa y aquí no la necesitas.

La solución que propone yoel_alejrando soluciona el problema. Aunque yo opto por esta otra, más corta, más concisa, sin comparaciones y sin copypastear líneas:

Código (cpp) [Seleccionar]
int signo[2] = {1,-1};
for(i=1; i<=n; i++)
  pi = pi - signo[i%2]/(2*i+1);
#196
No existe el operador ^ en C.

Para las potencias hay que usar la función pow (base,exponente)

Aunque en este caso no la necesitas, va a dar 1 si i es par y -1 si es impar.
#197
Estoy en el movil, así que voy a prescindir de los quotes y ser muy breve:

@Alejandro: La solución no es correcta porque no funciona para n > 20.

Hay una simplificación del numero combinatorio en algunos casos, eso te debería permitir un correcto funcionamiento hasta n = 40.

@Leosan: Cuando en una sucesión expreso un término respecto al anterior, se le llama recurrencia. La recurrencia no es mas que una aplicación matemática de la recursividad.

Cualquier algoritmo recursivo que se postre se puede representar con una recurrencia (y viceversa).
#198
Cita de: yoel_alejandro en 20 Marzo 2014, 15:43 PM
ivance, te saliste del reto!!! No puedes usar recursividad:

push_back(v[i-1][j]+v[i-1][j-1]);

:rolleyes:
Exactamente. Esta generando el triángulo recursivamente.

Y cabe en un long long a secas.

PD: No hace falta pasar un puntero. Se puede asumir que el array tiene el tamaño adecuado (y n tiene un valor correcto).

Aunque bueno, tampoco pasa nada si lo compruebas.
#199
A ver si lo adivino... ¿Estas en un modulo no? Lo digo porque los profesores de allí tienen una fama...

Es imposible que resolvaís ese problema si ni siquieras podeís pasar de reducir una imagen. La solución no está en resolver un problema técnico por encima de vuestras posibilidades, sino protestar y reclamar a la junta directiva. Si es necesario solicitad la guia docente de la asignatura para aseguraos que el profesor sigue el temario.

Lo que no puede ser esque un profesor diga "esto está en la wikipedia" y se quede tan pancho. Hay que protestar (con educación por supuesto), quien no llora no mama.
#200
Cita de: Superplay en 20 Marzo 2014, 13:21 PM
El problema no es que me las den, si no que tengo que programarlas todas desde el principio y no tengo ni idea. Es decir, se hacer resize con CImg pero no con las cosas específicas que pide ahí ni nada.
Me refiero que te dan las directrices hechas.

Por ejemplo, en la función de reducir la imagen. Si te doy una matriz:

Citar1 1 2 2 1 1
1 1 2 2 1 1
1 1 2 2 1 1
1 1 2 2 1 1

Que podría corresponder a una determinada imagen.

Reducirla a la mitad sería:
Citar1 2 1
1 2 1

Cabe decir que la he reducido en el eje X y en el eje Y. Podría reducirlo en un solo eje:

Eje X:
Citar1 2 1
1 2 1
1 2 1
1 2 1

Eje Y:
Citar1 1 2 2 1 1
1 1 2 2 1 1

¿Supongo que esto si lo sabras hacer no? Porque si te lo piden será porque te han dado algunas directrices antes.

Lo mismo con ampliar la imagen.