miércoles, 25 de junio de 2014

Ejercicios C++: Registros y Arrays (III)

Hace ya tiempo que no escribía una entrada de ejercicios de C++, así que aquí os dejo la tercera que vemos sobre registros y arrays, pues es lo más complicado que hemos visto hasta ahora de este lenguaje. En las (dos) próximas entradas de C++ trabajaremos con strings.


Se dispone de un array de 80 números enteros en el que al menos hay dos números que son iguales y dos que son distintos. Obtenga una función que tomando como parámetro dicho array, devuelva un elemento del array que sea mayor que el mínimo de éste.
int minimo (const TArray& array){
 int min = array[0];
 for(unsigned i = 1; i < TAMANO; i++){
  if(array[i] < min){
   min = array[i];
  }
 }
 return min;
}

int ejercicio (const TArray& array){
 int res;
 bool encontrado = false;
 unsigned i= 0;
 minimo = minimo(array);
 while(i < TAMANO && !encontrado){
  if(array[i] > minimo){
   encontrado = true;
   res = array[i];
  }
  i++;
 }

 return res;
}

Diseña un algoritmo que permita invertir el contenido de un array.
#include <iostream>
using namespace std;

const unsigned TAMANO = 10;

typedef int TArray[TAMANO];


void leerArray(TArray& array){
 for(unsigned i=0; i < TAMANO; i++){
  //cout << "v["<<i<<"]->";
  cin >> array[i];
 }
}

void invertir(const TArray& array, TArray& inv){
 unsigned j = TAMANO -1;
 for(unsigned i = 0; i < TAMANO; i++){
  inv[i] = array[j];
  j--;
 }
}



void mostrarArray(const TArray& unarray){
 for(unsigned i =0; i < TAMANO; i++){
  cout << "["<<unarray[i]<<"]";
 }
}
int main() {
 TArray array, inv;
 leerArray(array);
 invertir(array, inv);
 mostrarArray(inv);
 return 0;
}


Escriba un programa que efectúe la conversión de un número natural en base 10 a otra determinada base, sabiendo que el resultado no sobrepasará los 50 dígitos. El usuario introducirá primero el número en base 10 y después la base a la que convertirlo (el programa debe asegurarse de que la base no sea ni menor de 2 ni mayor de 9).
#include <iostream>
using namespace std;

const unsigned MAXIMO = 50;

typedef unsigned TArray[MAXIMO];

void leerDatos(unsigned &num, unsigned& base){
 cout << "Introduce el número a convertir: ";
 cin >> num;
 do{
  cout << "Introduce la base: ";
  cin >> base;
 }while(base < 2 || base > 9);
}

void convertir(unsigned num, unsigned base, TArray array, unsigned&  i){
 i=0;
 while(num != 0){
  array[i] = num%base;
  num = unsigned(num/base);
  i++;
 }
}
void invertir(const TArray& array, TArray& inv, unsigned contador){
 unsigned j = contador -1;
 for(unsigned i = 0; i < contador; i++){
  inv[i] = array[j];
  j--;
 }
}

void mostrarSolucion(const TArray& array, unsigned contador){
 cout << "El número ya convertido es ";
 for(unsigned i=0; i < contador  ; i++){
  cout << array[i];
 }
}

int main() {
 unsigned num, base, i;
 TArray primero, solucion;
 leerDatos(num, base);
 convertir(num, base, primero, i);
 invertir(primero, solucion, i);
 mostrarSolucion(solucion, i);
 return 0;
}

Dados los siguientes tipos (para una constante MAX cualquiera):

typedef char Componentes[MAX];

struct Vector {

Componentes datos; // array de caracteres

unsigned tam; // numero de celdas ocupadas

};


a) La moda de un array de caracteres es el carácter del array que se repite más frecuentemente. Si varios caracteres se repiten con la misma frecuencia máxima, entonces no hay moda. Escribe un procedimiento con tres parámetros. El primero es de entrada para recibir un registro de tipo Vector que contiene el array datos con tam caracteres. El segundo parámetro es de salida e indicará si se ha encontrado la moda en el array o no. El tercer parámetro es de salida y será el carácter que representa la moda (si es que existe).

#include <iostream>
using namespace std;

const unsigned MAX =50;

typedef char Componentes[MAX];
struct Vector {
 Componentes datos; // array de caracteres
 unsigned tam; // numero de celdas ocupadas
};

void apartadoA(const Vector& vector, bool& existeModa, char& moda){
 int apariciones;
 int mayor=0;
 char m;
 existeModa = false;
 for(unsigned i=0; i < vector.tam; i++){
  apariciones = 1;
  for(unsigned j=i+1; j< vector.tam;j++){
   if(vector.datos[i] == vector.datos[j]){
    apariciones++;
   }
  }
  if(apariciones != mayor){
   if(mayor < apariciones){
    mayor = apariciones;
       m = vector.datos[i];
       existeModa = true;
   }
  }else{
   existeModa = false;
  }
 }
 if(existeModa){
  moda = m;
 }
}

void leerVector(Vector& vector){
 vector.tam = 0;
 char a;
 cin >> a;
 while(a != '.'){
  vector.datos[vector.tam]= a;
  vector.tam++;
  cin >> a;
 }
}

int main() {
 Vector vector;
 bool existeModa;
 char moda;
 leerVector(vector);
 apartadoA(vector, existeModa, moda);
 if(existeModa){
  cout << "La moda es '"<< moda<<"'";
 }else{
  cout << "No existe la moda.";
 }
 return 0;
}

b) Diseña una función booleana que dados dos registros de tipo Vector como parámetros, devuelva TRUE si son iguales y FALSE en otro caso. Dos vectores son iguales si contienen los mismos elementos y en el mismo orden relativo, suponiendo que el primer elemento sigue al último.
#include <iostream>
using namespace std;

const unsigned MAX=50;
typedef char Componentes[MAX];
struct Vector {
 Componentes datos; // array de caracteres
 unsigned tam; // numero de celdas ocupadas
};

bool vectoresIguales(Vector& vector1, Vector& vector2){
 bool iguales = false;
 if(vector1.tam == vector2.tam){

 iguales = true;
 unsigned i=0;

 bool encontrado=false;
 unsigned j=0;
  while(j < vector2.tam && !encontrado){
   if(vector1.datos[0] == vector2.datos[j]){
    encontrado = true;
   }else{
    j++;
   }
  }

 while(i < vector1.tam && iguales){
  iguales = false;
   if(vector1.datos[i] == vector2.datos[j]){
    i++;
    if(j == vector2.tam -1){
     j = 0;
    }else{
     j++;
    }
    iguales = true;
   }

 }

 }
 return iguales;

}


void leerVector(Vector& vector){
 vector.tam = 0;
 char a;
 cout << "Introduce cadena: ";
 cin >> a;
 while(a != '.'){
  vector.datos[vector.tam]= a;
  vector.tam++;
  cin >> a;
 }
}


int main() {
 Vector v1, v2;
 leerVector(v1);
 leerVector(v2);
 if(vectoresIguales(v1,v2)){
  cout << "Los vectores son iguales.";
 }else{
  cout << "No son iguales";
 }

 return 0;
}

c) Diseña un procedimiento que tome como parámetros de entrada dos vectores con los arrays ordenados y devuelva (con un parámetro de salida) el vector resultado de realizar la mezcla ordenada de los dos arrays contenidos en los vectores de entrada.
#include <iostream>
using namespace std;

const unsigned MAX =50;

typedef char Componentes[MAX];
struct Vector {
 Componentes datos; // array de caracteres
 unsigned tam; // numero de celdas ocupadas
};

void apartadoC(const Vector& v1, const Vector& v2, Vector& res){
 unsigned i=0;
 unsigned j=0;
 unsigned cnt =0;
 res.tam = v1.tam+v2.tam;
 while(cnt < res.tam && i < v1.tam && j < v2.tam){
  if(v1.datos[i] < v2.datos[j]){
   res.datos[cnt] = v1.datos[i];
   i++;
  }else{
   res.datos[cnt] = v2.datos[j];
   j++;
  }
  cnt++;
 }
 if(i == v1.tam){
  while(cnt < res.tam){
   res.datos[cnt] = v2.datos[j];
   j++;
   cnt++;
  }
 }else if (j == v2.tam){
  while(cnt < res.tam){
     res.datos[cnt] = v1.datos[i];
     i++;
     cnt++;
  }
 }
}

void leerVector(Vector& vector){
 vector.tam = 0;
 char a;
 cout << "Introduce los datos: ";
 cin >> a;
 while(a != '.'){
  vector.datos[vector.tam]= a;
  vector.tam++;
  cin >> a;
 }
}

void mostrarArray(const Vector& res){
 for(unsigned i=0; i < res.tam; i++){
  cout <<"["<<res.datos[i]<<"]";
 }
}


int main() {
 Vector v1, v2, res;
 leerVector(v1);
 leerVector(v2);
 apartadoC(v1,v2, res);
 mostrarArray(res);
 return 0;
}

Diseña un algoritmo para calcular la suma de los elementos de la diagonal principal de una
matriz cuadrada.
include <iostream>
using namespace std;

typedef double TFilas[100];
typedef TFilas TMat[100];

struct TMatriz{
 unsigned dim;
 TMat matriz;
};

void leerDimension(TMatriz& mat){
 cout << "Introducir número de filas y columnas: ";
 cin >> mat.dim;
}

void leerMatriz(TMatriz& mat){
 cout << "Introduce los valores de la matriz."<< endl;
 for(unsigned f =0; f < mat.dim; f++){
  for(unsigned c =0; c < mat.dim; c++){
   cout << "Matriz["<<f+1<<"]["<<c+1<<"]->";
   cin >> mat.matriz[f][c];
  }
 }
}

void mostrarMatriz(const TMatriz& mat){
 for(unsigned f =0; f < mat.dim; f++){
  for(unsigned c =0; c < mat.dim; c++){
   cout << mat.matriz[f][c]<<" ";
  }
  cout << endl;
 }
}

double sumaDiagonal(const TMatriz& mat){
 double suma=0;
 for(unsigned f =0; f < mat.dim; f++){
  for(unsigned c =0; c < mat.dim; c++){
    if(c==f){
     suma = suma + mat.matriz[f][c];
    }
  }
 }
 return suma;
}

int main() {
 cout << "Suma de la diagonal de una matriz." << endl; 
 TMatriz matriz;
 leerDimension(matriz);
 leerMatriz(matriz);
 mostrarMatriz(matriz);
 cout << "La suma de la diagonal es "<< sumaDiagonal(matriz);

 return 0;
}


Una matriz tiene un punto silla en una de sus componentes, si ese componente es el mayor valor de su columna y el menor de su fila. Diseña un algoritmo que recogiendo de teclado los componentes de una matriz cuadrada de enteros de hasta un máximo de 10x10, muestre en la pantalla las coordenadas de todos sus puntos silla.
##include <iostream>
using namespace std;

typedef double TFilas[10];
typedef TFilas TMat[10];

struct TMatriz{
 unsigned dim;
 TMat matriz;
};

void leerDimension(TMatriz& mat){
 do{
 cout << "Introducir número de filas y columnas: ";
 cin >> mat.dim;
 }while(mat.dim > 10);
}

void leerMatriz(TMatriz& mat){
 cout << "Introduce los valores de la matriz."<< endl;
 for(unsigned f =0; f < mat.dim; f++){
  for(unsigned c =0; c < mat.dim; c++){
   cout << "Matriz["<<f+1<<"]["<<c+1<<"]->";
   cin >> mat.matriz[f][c];
  }
 }
}

void mostrarMatriz(const TMatriz& mat){
 for(unsigned f =0; f < mat.dim; f++){
  for(unsigned c =0; c < mat.dim; c++){
   cout << mat.matriz[f][c]<<" ";
  }
  cout << endl;
 }
}

double mayorColumna(const TMatriz& mat, unsigned columna){
 double mayor = mat.matriz[0][columna];
 for(unsigned f=1; f < mat.dim; f++){
  if(mayor < mat.matriz[f][columna]){
   mayor =  mat.matriz[f][columna];
  }
 }
 return mayor;
}

double menorFila(const TMatriz& mat, unsigned fila){
 double menor = mat.matriz[fila][0];
  for(unsigned c=1; c< mat.dim; c++){
   if(menor > mat.matriz[fila][c]){
    menor =  mat.matriz[fila][c];
   }
  }
  return menor;
}


void buscarPuntos(const TMatriz& mat){
 for(unsigned f=0; f < mat.dim; f++){
  for(unsigned c=0; c < mat.dim; c++){
   if(mat.matriz[f][c] == menorFila(mat, f) && menorFila(mat, f)==mayorColumna(mat, c)){
    cout << "El elemento de la fila "<< f+1 << " y la columna "<< c+1 << " es un punto de silla."<< endl;
   }
  }
 }
}
int main() {
 cout << "Buscar punto de silla." << endl; // prints !!!Hello World!!!
 TMatriz matriz;
  leerDimension(matriz);
  leerMatriz(matriz);
  mostrarMatriz(matriz);
  buscarPuntos(matriz);
 return 0;
}

Un tablero n-goro es un tablero con n x (n+1) casillas. Una propiedad interesante es que se pueden visitar todas sus casillas haciendo el siguiente recorrido por diagonales. Empezamos por la casilla (1,1) y recorremos la diagonal principal hacia la derecha y hacia abajo hasta llegar a la casilla (n,n). La siguiente casilla a visitar sería la (n+1,n+1) que no existe porque nos saldríamos del tablero por abajo. En estos casos siempre se pasa a la casilla equivalente en al primera fila, es decir, la (1,n+1). Ahora seguimos moviéndonos hacia la derecha y hacia abajo. Pero la siguiente casilla sería la (2,n+2) que no existe porque nos hemos salido por la derecha. En estos casos se continúa por la casilla equivalente de la primera columna, es decir, la (2,1). De nuevo nos movemos hacia la derecha y hacia abajo, hasta alcanzar la casilla (n,n-1). La siguiente casilla sería la (n+1,n), pero como nos saldríamos por abajo pasamos a la casilla equivalente de la primera fila (1,n). Si se continúa con este proceso se termina visitando todas las casillas del tablero.
Diseñe un procedimiento que dada una constante N devuelve como parámetro de salida un
tablero N-goro con sus casillas rellenas con el número correspondiente al momento en que se
visitan.
#include <iostream>
using namespace std;

typedef double TFilas[10];
typedef TFilas TMat[10];

struct TMatriz{
 unsigned nco, nfi;
 TMat matriz;
};

void leerDimension(TMatriz& mat){
 cout << "Introducir número de filas: ";
 cin >> mat.nfi;
 mat.nco= mat.nfi+1;
}
void inicializar(TMatriz& mat){
 for(unsigned i=0; i < mat.nfi; i++){
  for(unsigned j= 0; j < mat.nco; j++){
   mat.matriz[i][j]= 0;
  }
 }
}

void escribirMatriz(TMatriz& mat){
 unsigned fila = 0;
 unsigned columna =0;
 for(unsigned i = 1; i <= mat.nfi*mat.nco; i++){
  if(mat.matriz[fila][columna]== 0){
   mat.matriz[fila][columna]= i;

   fila++;
   columna++;

   if(fila >= mat.nfi){
   fila = 0;
   }
   if(columna >= mat.nco){
   columna =0;
   }
  }
 }

}


void mostrarMatriz(const TMatriz& mat){
 for(unsigned f =0; f < mat.nfi; f++){
  for(unsigned c =0; c < mat.nco; c++){
   cout << mat.matriz[f][c]<<"  ";
  }
  cout << endl;
 }
}


int main() {
 
 TMatriz matriz;
 leerDimension(matriz);
 inicializar(matriz);
 escribirMatriz(matriz);
 mostrarMatriz(matriz);
 return 0;
}



2 comentarios:

  1. Vaya, el primero que es el que no entiendo el enunciado no funciona XD
    ¡Gracias!

    ResponderEliminar
    Respuestas
    1. Buenas. No se si te refieres a la primera ronda de ejercicios C++ o al primer ejercicio de aquí. En cualquier caso el enunciado "no tiene que funcionar". Está ahí y ya... No se a que te refieres.

      Saludos;)

      Eliminar