• Como resolver esta secuencia geometrica?C++

 #492812  por Destr0yer
 03 Oct 2017, 04:18
Buenas necesito de vuestra ayuda para resolver este ejercicio:

esto es lo que he avanzado, sin embargo , no se en que parte podría colocar la variable 'y' ; gracias
 #492874  por Slek
 11 Oct 2017, 00:06
Buenas,
con este ejemplo creo que se pueden ilustrar bastante bien algunos conceptos iteresantes de programación.

Una primera implementación podría ser:
#include <iostream>
#include <string>

#define N_MAX 30
#define EPSILON 0.00001

int main ()
{
    std::string s;
    int n;
    double a, x, y;

    do
    {
        std::cout << "Ingrese el número de términos (N): ";
        std::getline(std::cin, s);

        n = std::stoi(s);
    } while ((n <= 0) || (n > N_MAX));

    do
    {
        std::cout << "Ingrese el valor de a: ";
        std::getline(std::cin, s);

        a = std::stod(s);
    } while (std::abs(a) < EPSILON);

    std::cout << "Ingrese el valor de x: ";
    std::getline(std::cin, s);

    x = std::stod(s);

    std::cout << "Ingrese el valor de y: ";
    std::getline(std::cin, s);

    y = std::stod(s);

    double termino, suma = 0., signo = -1., cociente = 3., denominador = 1.;
    for (int k = 1; k <= n; k++)
    {
        termino = ((k & 1) ? x:y)*signo*cociente/denominador;
        suma += termino;
        denominador *= 2*a;
        signo *= -1.;
        cociente += 3.;
    }

    std::cout << std::endl << "La sumatoria es: " << suma << std::endl;

    return 0;
}
utilizando el [ Debe registrarse para ver este enlace ]

Sería sintácticamente equivalente a:
        if (k & 1)[code][/code]
            termino = x;
        else
            termino = y;
        termino *= signo*cociente/denominador;
//        termino = ((k & 1) ? x:y)*signo*cociente/denominador;

Para comprobar si un número es par o impar, basta con evaluar el último bit (eso es precisamente lo que hace k & 1).

En estas ocasiones podría ser interesante aplicar técnicas de [ Debe registrarse para ver este enlace ]. Por ejemplo, evaluando los términos de dos en dos:
#include <cmath>

    double suma = 0.;
    for (int k = 1; k <= n/2; k++)
    {
        suma -= 3*x*(2*k - 1)/std::pow(2*a, 2*(k-1));
        suma += 3*y*2*k/std::pow(2*a, 2*k-1);
    }

    if (n & 1)
        suma -= (3*x*n)/std::pow(2*a, n-1);

Además podemos sacar la condición fuera del bucle (solo se evalua una vez). De esta forma reducimos aún más el número de [ Debe registrarse para ver este enlace ].

Por último, si la eficiencia es un problema, podemos eliminar los bucles for por completo, evaluando es su lugar las funciones de [ Debe registrarse para ver este enlace ] asociadas:
double suma = -3*x*evalSumX(4*a*a, n/2 + (n & 1)) + 3*y*evalSumY(2*a, n/2);
donde:
#include <cassert>
#include <cmath>

double evalSumX(double a, int n)
{
    assert(n > 0);

    if (std::abs(a - 1.) >= EPSILON)
    {
        double an = std::pow(a, n);
        return a*(an*a+an-a*(2*n+1)+2*n-1)/(an*(a-1)*(a-1));
    }
    else
        return n*n;
}

double evalSumY(double a, int n)
{
    assert(n > 0);

    double a2 = a*a;
    if (std::abs(a2 - 1.) >= EPSILON)
    {
        double a2n = std::pow(a2, n);
        return 2*a*(a2*a2n-a2*(n+1)+n)/(a2n*(a2-1)*(a2-1));
    }
    else
        return n*(n+1);
}
con [ Debe registrarse para ver este enlace ] constante [ Debe registrarse para ver este enlace ], en lugar de lineal respecto al número de términos ([ Debe registrarse para ver este enlace ])

Cualquier duda, preguntad.

Un saludo!