• No se han encontrado resultados

LENGUAJES DE PROGRAMACIÓN. Solución al Trabajo Práctico - Junio de 2014

N/A
N/A
Protected

Academic year: 2021

Share "LENGUAJES DE PROGRAMACIÓN. Solución al Trabajo Práctico - Junio de 2014"

Copied!
10
0
0

Texto completo

(1)

EJERCICIO 1

El método de Newton es un algoritmo muy eficiente para resolver f(x) = 0. Partien-do de un valor inicial x0, el método de Newton obtiene x1, x2, . . . , recursivamente

mediante la fórmula:

xk+1 = xk−

f(xk)

f′(x k)

Escriba un programa en C++ que aplique el método de Newton para resolver: f(x) = x2

− 2 = 0 Puesto que f′(x) = 2x, obtenemos:

xk+1 = xk− f(xk) f′(xk) = xk− x2 k− 2 2xk

El programa debe solicitar que el usuario introduzca por consola el valor inicial (x0) y el número de iteraciones del algoritmo (N).

El programa debe comprobar que el número de iteraciones sea un valor entero mayor que cero. Si no se satisface esta condición, el programa debe terminar. El programa debe escribir en la consola, para k = 0, . . . , N, los valores xk

obteni-dos de aplicar el método de Newton y los correspondientes valores f(xk). Ambos

valores deben mostrarse en formato científico, con 10 dígitos de precisión. A continuación el programa debe terminar.

(2)

// Fichero: metodoNewton.cpp #include <iostream> #include <iomanip> #include <cmath> int main() {

// Entrada por consola del valor inicial

std::cout << "Valor inicial: ";

double x_k;

std::cin >> x_k;

// Entrada por consola del número de iteraciones

std::cout << "Numero de iteraciones: ";

int N;

std::cin >> N;

// Comprobar que N es mayor que cero if (N<=0) return 0;

// Método de Newton for (int k=0; k<=N; k++) {

// f(x_k)

double f_k = std::pow(x_k,2) - 2; // Salida por consola

std::cout << k << "\t"<<

std::scientific << std::setprecision(10) << x_k << "\t"<< f_k << "\t"<< std::endl;

// f’(x_k)

double derf_k = 2*x_k; // Iteración del método

x_k = x_k - f_k/derf_k;

}

return 0; }

(3)

Consideremos el sistema lineal de ecuaciones Ax= b

donde A es una matriz cuadrada invertible. Supongamos además que la matriz Aes triangular inferior. Esto es:

ai,j = 0 si i < j

En este caso, el sistema lineal Ax = b puede ser resuelto fácilmente. Puede calcularse x1 de la primera ecuación

a1,1x1 = b1

A continuación, puede calcularse x2 de la segunda ecuación

a2,1x1+ a2,2x2 = b2

Y así sucesivamente. En general, una vez se han calculado x1, . . . , xk−1, es posible

emplear la k-ésima ecuación

ak,1x1+ ak,2x2 + · · · + ak,kxk = bk

para calcular xk. Es decir:

xk =

1 ak,k

(bk− ak,1x1− ak,2x2− · · · − ak,k−1xk−1)

Escriba un programa en C++ que dada la matriz A y el vector b, calcule y muestre en la consola el vector de incógnitas x.

El programa tendrá una constante entera N tal que la matriz A sea N × N, y los vectores b y x tengan N componentes. La matriz A y el vector b deben ser constantes del programa. El programa debe realizarse de manera que funcione correctamente para cualquier tamaño de la matriz y los vectores.

(4)

// Fichero: sistemaTriangular.cpp #include <iostream>

const int N = 4;

const double b[N] = {1, -2, 0, 4};

const double A[N][N] = { {3, 0, 0, 0},

{1, 1, 0, 0},

{-1, 1, 10, 0},

{1, 1, -1, 4} };

int main() {

std::cout << "Vector de incognitas: "<< std::endl;

double x[N];

for (int i=0; i<N; i++) {

x[i] = b[i];

for (int j=0; j<i; j++)

x[i] = x[i] - A[i][j]*x[j]; x[i] = x[i]/A[i][i];

std::cout << x[i] << std::endl;

}

return 0; }

(5)

Se ha realizado una réplica de un experimento factorial completo con 3 facto-res experimentales y dos niveles por factor, que se repfacto-resentan “+” y “−”. Los resultados obtenidos se han almacenado en un fichero de texto. Cada línea del fichero corresponde a un punto experimental. Las tres primeras columnas del fichero indican el punto experimental: la primera columna el nivel del primer factor, la segunda columna el nivel del segundo factor y la tercera columna el nivel del tercer factor. En la cuarta columna se encuentra el correspondiente valor numérico de la respuesta. La estructura del contenido del fichero es la siguiente:

− − − R1 + − − R2 − + − R3 + + − R4 − − + R5 + − + R6 − + + R7 + + + R8

donde R1, . . . , R8 representan los valores numéricos de la respuesta, que son

números reales.

El objetivo del ejercicio es escribir en C++ un programa que lea el contenido del fichero, y calcule y muestre por consola los efectos principales de los tres factores. El efecto principal del factor j se representa ej y es la diferencia entre la respuesta

media cuando el factor j vale “+” y la respuesta media cuando el factor j vale “−”. Es decir: e1 = −R1+ R2− R3+ R4− R5+ R6− R7+ R8 4 e2 = −R1− R2+ R3+ R4− R5− R6+ R7+ R8 4 e3 = −R1− R2− R3 − R4+ R5+ R6+ R7+ R8 4

El programa debe realizar las acciones siguientes:

(6)

abrirlo, mostrar un mensaje de error y terminar.

2. Ir leyendo el fichero de texto, comprobando que los puntos experimentales están en el orden correcto. Si el orden no es correcto, mostrar un mensaje de error y terminar.

3. Cerrar el fichero.

4. Calcular los tres efectos principales y mostrarlos en la consola. 5. Terminar.

Así, por ejemplo, si el contenido del fichero datos.txt es − − − 2.5 + − − 1.3 − + − 2.1 + + − 1.5 − − + −2 + − + 1.5 − + + −1.5 + + + 1.3

El programa debería mostrar en la consola: e1 : 1.125

e2 : 0.025 e3 : -2.025

(7)

// Fichero: experimento.cpp #include<iostream> #include<fstream> #include<string>

// Nombre del fichero que contiene los datos

const std::string nombreFich = "datos.txt"; int main()

{

std::ifstream fich_in(nombreFich.c_str(), std::ios::in);

if (!fich_in) {

std::cout << "ERROR: No es posible abrir el fichero "<< nombreFich << std::endl;

return 1; }

// Array que almacena las respuestas double R[8];

// Lectura del fichero for (int i=0; i<8; i++) {

char nivel_factor1, nivel_factor2, nivel_factor3; // Lee las tres primeras columnas

fich_in >> nivel_factor1; fich_in >> nivel_factor2; fich_in >> nivel_factor3;

// Comprueba que los puntos experimentales están en el orden correcto int num = 0;

if (nivel_factor1 == ’+’) num += 1; if (nivel_factor2 == ’+’) num += 2; if (nivel_factor3 == ’+’) num += 4; if (num != i) {

std::cout << "Error en linea "<< i+1 <<

": punto experimental en orden incorrecto"<< std::endl;

return 0; }

// Lee la cuarta columna

fich_in >> R[i];

}

// Cierre del fichero

fich_in.close();

// Mostrar los efectos principales

std::cout << "e1 : "<<(-R[0]+R[1]-R[2]+R[3]-R[4]+R[5]-R[6]+R[7])/4 << "\n"<< "e2 : "<<(-R[0]-R[1]+R[2]+R[3]-R[4]-R[5]+R[6]+R[7])/4 << "\n"<< "e3 : "<<(-R[0]-R[1]-R[2]-R[3]+R[4]+R[5]+R[6]+R[7])/4 << std::endl; return 0; }

Código 1.3: Solución al Ejercicio 3.

(8)

Escriba en C++ un programa que realice y muestre en la consola la suma de dos números enteros positivos arbitrariamente grandes introducidos por el usuario a través de la consola. El programa debe realizar las acciones siguientes:

1. Solicitar al usuario que introduzca por consola la expresión a evaluar. 2. Almacenar la expresión introducida por el usuario en una variable de tipo

std::string.

3. Comprobar que la expresión introducida por el usuario tiene el formato correcto. Si no lo tiene, mostrar un mensaje de error y terminar. El formato correcto de la expresión es el siguiente:

– Primeramente, uno o más dígitos enteros (0, 1, ..., 9). – A continuación, el símbolo ’+’.

– Finalmente, uno o más dígitos enteros (0, 1, ..., 9).

La expresión no debe contener espacios en blanco. Por ejemplo, la siguiente es una expresión válida:

283746357262816181643862826+362528016129919283473635627262 4. Calcular la suma de los dos números enteros, almacenando el resultado en

una variable de tipo std::string.

Obsérvese que en general los sumandos y el resultado pueden ser mayo-res que el máximo valor repmayo-resentable por los tipos de datos enteros de C++. Por ese motivo, debe programarse un algoritmo que calcule la suma. El algoritmo puede ser cualquiera, siempre que proporcione el resultado correcto. Una posibilidad es emplear el algoritmo que comúnmente se usa al realizar una suma con “papel y lápiz”.

5. Mostrar el resultado de la suma en la consola. 6. Terminar.

(9)

// Fichero: sumaEnterosLargos.cpp #include <iostream>

#include <string> int main()

{

// Entrada por consola de la expresión

std::cout << "Introduzca la expresion: "<< std::endl; std::string expresion;

std::cin >> expresion;

// Índice del string en que se encuentra el símbolo + int indMas = expresion.find("+");

if (indMas==-1) {

std::cout << "Error: Falta el simbolo + en la expresion" <<std::endl;

return 0; }

if (indMas==0) {

std::cout << "Error: Falta el primer sumando" <<std::endl;

return 0; }

if (indMas==expresion.length()-1) {

std::cout << "Error: Falta el segundo sumando" <<std::endl;

return 0; }

// Extraer los sumandos

std::string sumando1, sumando2; sumando1.assign(expresion,0,indMas);

sumando2.assign(expresion,indMas+1,expresion.length()-indMas-1);

// Comprobar el formato del primer sumando for (int i=0; i<sumando1.length(); i++) {

if (sumando1[i]<’0’||sumando1[i]>’9’) {

std::cout <<

"Error: El primer sumando no es entero" <<std::endl;

return 0; }

}

// Comprobar el formato del segundo sumando for (int i=0; i<sumando2.length(); i++) {

if (sumando2[i]<’0’||sumando2[i]>’9’) {

std::cout <<

"Error: El segundo sumando no es entero" <<std::endl;

return 0; }

}

Código 1.4: Solución al Ejercicio 4 (primera parte).

(10)

// Rellenar con ceros para que ambos sumandos tengan la misma longitud if (sumando1.length() < sumando2.length()) { std::string ceros(sumando2.length()-sumando1.length(),’0’); sumando1.insert(0,ceros); } if (sumando1.length() > sumando2.length()) { std::string ceros(sumando1.length()-sumando2.length(),’0’); sumando2.insert(0,ceros); } // Realiza la suma int acarreo = 0; std::string resultado(sumando1.length(),’0’);

for (int i=sumando1.length()-1; i>=0; i--) { int digito1 = sumando1[i] - ’0’; int digito2 = sumando2[i] - ’0’;

int suma = digito1 + digito2 + acarreo;

resultado[i] = ’0’+ suma %10; acarreo = (int)(suma/10); } if (acarreo>0) { char c = ’0’+ acarreo; std::string cs(1,c); resultado.insert(0,cs); }

// Muestra los sumandos y el resultado en la consola

std::cout << "= "<< resultado << std::endl;

return 0; }

Referencias

Documento similar

In addition to the requirements set out in Chapter VII MDR, also other MDR requirements should apply to ‘legacy devices’, provided that those requirements

The notified body that issued the AIMDD or MDD certificate may confirm in writing (after having reviewed manufacturer’s description of the (proposed) change) that the

Cedulario se inicia a mediados del siglo XVIL, por sus propias cédulas puede advertirse que no estaba totalmente conquistada la Nueva Gali- cia, ya que a fines del siglo xvn y en

Para ello, trabajaremos con una colección de cartas redactadas desde allí, impresa en Évora en 1598 y otros documentos jesuitas: el Sumario de las cosas de Japón (1583),

En junio de 1980, el Departamento de Literatura Española de la Universi- dad de Sevilla, tras consultar con diversos estudiosos del poeta, decidió propo- ner al Claustro de la

E Clamades andaua sienpre sobre el caua- 11o de madera, y en poco tienpo fue tan lexos, que el no sabia en donde estaña; pero el tomo muy gran esfuergo en si, y pensó yendo assi

Dada la endogeneidad de la respuesta de la política monetaria a la evolución prevista para la economía, esta evolución de las cotizaciones bancarias ante sorpresas monetarias puede

[r]