Professional Documents
Culture Documents
c++
El siguiente es el primer ejercicio que hice con matrices. Quizás alguno de estos ejercicios
te puedan servir como una base. Puedes leer el post anterior sobre vectores, matrices y
punteros si aún no haz trabajo con ellos.
Esta clase matriz tendrá 3 atributos: Matriz,número de filas y número de columnas. Tiene
un constructor por defecto,constructor copiador y un constructor por parámetro que recibe
el número de filas y columnas.
NOTA: He aplicado un poco de templates para manejar la matriz con varios tipos de datos
(int, float, char,double) y sobrecarga de operadores para la suma, resta y multiplicación de
matrices.
Recien estoy aprendiendo a usar estas 2 características importantes del lenguaje (templates
y sobrecarga de operadores) por lo tanto, estos temas serán tratados a profundidad el
proximo año.
En breve:
Un template es una manera de que funciones, clases métodos puedan ser usados con varios
tipos de datos. Imagínense crear una lista de datos y tener que crear funciones insertar,
eliminar, buscar, concatenar, etc para cada tipo de dato. Si los métodos y la clase tienen la
misma lógica para que reescribir código si podemos reutilizar.
La sobrecarga de operadores es una manera de realizar las mismas operaciones que solemos
hacer con tipos de datos comunes con tipos abstractos de datos. Por ejemplo, la sobrecarga
me permitió sumar 2 objetos de tipo Matriz y almacenar el resultado en otro objeto Matriz,
del modo c = a + b
Al grano:
matriz.h
view source
print?
01 #ifndef MATRIZ_H
02 #define MATRIZ_H
03
04 #include <iostream>
05 #include <time.h>
06
07 using namespace std;
08
09 template <class T>
10 class Matriz
11 {
12 private:
13 T mayor_,menor_,moda_,ele,**matr1;
14 int dim_matriz;
15 public:
16 int fils,cols;
17 T escalar;
18
19 Matriz();
20 Matriz(int,int);
21 Matriz(const Matriz &m);//constructor copia
22
23 void llenar_teclado();
24 void llenar_aleatorio();
25 void imprimir();
26
27 T mayor();
28 T menor();
29 T moda();
30
31 void inter_filas(int,int);
32 void inter_cols(int,int);
33
34 bool esSimetrica();
35 bool esIdentidad();
36 void multi_escalar(T);
37 void transpuesta();
38
39 Matriz<T> operator+ (const Matriz &matr2);
40 Matriz<T> operator- (const Matriz &matr2);
41 Matriz<T> operator* (const Matriz &matr2);
42
43 void eliminar();
44
45 ~Matriz();
46 protected:
47 };
48
49 #endif // MATRIZ_H
Implemetanción de la clase:
matriz.cpp
view source
print?
001 #include "Matriz.h"
002
003 //Constructor por defecto
004 template<typename T>
005 Matriz<T>::Matriz()
006 {
007 fils=4;
008 cols=4;
009 }
010
011 //Constructor copia
012 template<typename T>
013 Matriz<T>::Matriz(const Matriz &m)
014 {
015 *this = m;
016 }
017
018 //Constructor por parametro
019 template<typename T>
020 Matriz<T>::Matriz(int fils_ , int cols_)
021 {
022 fils = fils_;
023 cols = cols_;
024 matr1 = new T*[fils];
025 for(int i=0;i<fils;i++){
026 matr1[i] = new T[cols];
027 }
028 }
029
030 //Llenar aleatoriamente una matriz
031 template<typename T>
032 void Matriz<T>::llenar_aleatorio()
033 {
034 //srand(time(NULL));
035 for(int i=0;i<fils;i++){
036 for(int j=0;j<cols;j++){
037 matr1[i][j] = rand() % 30;
038 }
039 }
040 mayor_= matr1[0][0];
041 menor_= matr1[0][0];
042 srand(time(NULL));
043 }
044
045 //Llenar una matriz desde teclado
046 template<typename T>
047 void Matriz<T>::llenar_teclado()
048 {
061
062 //Imprimir matriz
063 template<typename T>
064 void Matriz<T>::imprimir()
065 {
066 for(int i=0;i<fils;i++){
067 for(int j=0;j<cols;j++){
068 cout << matr1[i][j] << " ";
069 }
070 cout << endl << endl;
071 }
072 cout << endl << endl;
073 }
074
075 //Obtener el mayor de la matriz
076 template<typename T>
077 T Matriz<T>::mayor()
078 {
085 }
086 return mayor_;
087 }
088
089 //Obtener el menor de la matriz
090 template<typename T>
091 T Matriz<T>::menor()
092 {
099 }
100 return menor_;
101 }
102
103 //Obtener la moda de la matriz
104 template<typename T>
105 T Matriz<T>::moda()
106 {
107 //creo una matriz auxiliar
108 Matriz maux(fils,cols);
109
110 //lleno la matriz con ceros
111 for(int i=0;i<fils;i++){
112 for(int j=0;j<cols;j++){
113 maux.matr1[i][j] = 0;
114 }
115 }
116
117 dim_matriz = fils * cols;
118 int y=0;//para retener una fila n veces
119 int z=0;//para retener una columna n veces
120
121 //empiezo a comparar cada elemento n veces
122 for(int x=0;x<dim_matriz;x++){
129 }
130 //pasar a la siguiente columna despues de n comparaciones
131 z++;
132 if(z==cols){//empiezo a comparar con la siguiente fila
133 z=0;//empiezo nuevamente en la 1era columna
134 y++;//paso a la siguiente fila
135 }
136 }
137
138 //obtengo el valor mayor de la matriz
139 mayor_ = maux.mayor();
140
if(mayor_==1){//si ningun valor se ha repetido mas de una vez no hay
141
moda
142 return -1;
151 }
152 return moda_;
153 }
154
155 //Intercambiar dos filas en una matriz
156 template<typename T>
157 void Matriz<T>::inter_filas(int fil1, int fil2)
158 {
175
176 //Intercambiar dos columnas en una matriz
177 template<typename T>
178 void Matriz<T>::inter_cols(int col1, int col2)
179 {
180 if(col1 > cols || col2 > cols){
181 cout << "Por favor, hasta cuando " << endl;
182 } else{
183 T temp;
184 col1--;
185 col2--;
186
187 for(int i=0;i<fils;i++){
188 temp = matr1[i][col1];
189 matr1[i][col1] = matr1[i][col2];
190 matr1[i][col2] = temp;
191 }
cout << "Se intercambio la columna " << col1 + 1 << " por la " <<
192
col2 + 1 << endl;
193 imprimir();
194 }
195 }
196
197 //Verificar si una matriz es simetrica
198 template<typename T>
199 bool Matriz<T>::esSimetrica()
200 {
201 if(fils!=cols) {
202 return false;
203 }
204
205 for(int i=0;i<fils;i++){
206 for(int j=0;j<cols;j++){
207 if (matr1[i][j]!=matr1[j][i]){
208 return false;
209 }
210 }
211 }
212 return true;
213 }
214
215 //Verificar si una matriz es identidad
216 template<typename T>
217 bool Matriz<T>::esIdentidad()
218 {
219 if(fils!=cols) {
220 return false;
221 }
222
223 for(int i=0;i<fils;i++){
224 for(int j=0;j<cols;j++){
225 if (i == j) {
226 if (matr1[i][j] != 1)
227 return false;
228 } else {
229 if (matr1[i][j] != 0)
230 return false;
231 }
232 }
233 }
234 return true;
235 }
236
237 //Multiplicar a una matriz por un escalar
238 template<typename T>
239 void Matriz<T>::multi_escalar(T escalar)
240 {
245 }
cout << "Se multiplico a la matriz por el escalar " << escalar <<
246
endl;
247 imprimir();
248 }
249
250 //Obtener la transpuesta de una matriz
251 template<typename T>
252 void Matriz<T>::transpuesta()
253 {
254 Matriz matresult(cols,fils);
255 for(int i=0;i<cols;i++){
256 for(int j=0;j<fils;j++){
257 matresult.matr1[i][j]= matr1[j][i];
258 }
259 }
260 matresult.imprimir();
261 }
262
263 //Suma de matrices con sobrecarga de operadores
264 template<typename T>
265 Matriz<T> Matriz<T>::operator+ (const Matriz &matr2)
266 {
267 Matriz matresult(fils,cols);
268 for (int i=0;i<fils;i++){
269 for (int j=0;j<cols;j++){
270 matresult.matr1[i][j] = matr1[i][j] + matr2.matr1[i][j];
271 }
272 }
273 return matresult;
274 }
275
276 //Resta de matrices con sobrecarga de operadores
277 template<typename T>
278 Matriz<T> Matriz<T>::operator- (const Matriz &matr2)
279 {
280 Matriz matresult(fils,cols);
281 for (int i=0;i<fils;i++){
282 for (int j=0;j<cols;j++){
283 matresult.matr1[i][j] = matr1[i][j] - matr2.matr1[i][j];
284 }
285 }
286 return matresult;
287 }
288
289 //Multiplicacion de matrices con sobrecarga de operadores
290 template<typename T>
291 Matriz<T> Matriz<T>::operator* (const Matriz &matr2)
292 {
293 Matriz matresult(fils,matr2.cols);
294 T total;
315
316 template<typename T>
317 void Matriz<T>::eliminar()
318 {
319 for(int i=0;i<fils;i++){
320 delete[] matr1[i];
321 }
322 delete[] matr1;
323 }
324
325 template<typename T>
326 Matriz<T>::~Matriz(){}
main.cpp
view source
print?
01 #include <iostream>
02 #include "Matriz.h"
03 #include "Matriz.cpp"
04
05 using namespace std;
06
07 int main()
08 {
09 srand(time(NULL));//para no generar los mismos numeros aleatorios
10 int fils,cols,fil1,col1,fil2,col2;
11
12 cout << "Ingresa nro de filas " << endl;
13 cin >> fils;
14 cout << "Ingresa nro de columnas " << endl;
15 cin >> cols;
16 cout << endl;
17
18 Matriz<int> a(fils,cols);
19 Matriz<int> b(fils,cols);
Matriz<int> c(fils,cols);//matriz para almacenar el resultado de
20
las operaciones
21
a.llenar_aleatorio();//existe el metodo llenar_teclado() para otros
22
tipos
23 b.llenar_aleatorio();
24
25 cout << "Operaciones con matrices " << endl;
26 cout << "Matriz A " << endl;
27 a.imprimir();
28
29 cout << "Matriz B " << endl;
30 b.imprimir();
31
32 cout << "Matriz A + B " << endl;
33 c = a + b;
34 c.imprimir();
35
36 cout << "Matriz A - B " << endl;
37 c = a - b;
38 c.imprimir();
39
40 cout << "Matriz A * B " << endl;
41 c = a * b;
42 c.imprimir();
43
44 cout << "Operaciones basicas con la matriz A" << endl;
45 cout << "Matriz A " << endl;
46 a.imprimir();
47
48 cout << "El mayor de la matriz es: " << a.mayor() << endl;
49 cout << "El menor de la matriz es: " << a.menor() << endl;
50 cout << "La moda de la matriz es: " << a.moda() << endl;
51 cout << (a.esSimetrica() ? "" : "No") << " Es simetrica." << endl;
52 cout << (a.esIdentidad() ? "" : "No") << " Es identidad." << endl;
53 cout << endl;
54
55 cout << "Ingresa el escalar " << endl;
56 cin >>a.escalar;
57 a.multi_escalar(a.escalar);
58
59 cout << "Intercambio: Ingresa dos filas del 1 al " << fils << endl;
60 cin >>fil1;
61 cin >>fil2;
62 a.inter_filas(fil1,fil2);
63
cout << "Intercambio: Ingresa dos columnas del 1 al " << cols <<
64
endl;
65 cin >>col1;
66 cin >>col2;
67 a.inter_cols(col1,col2);
68
69 cout << "Transpuesta de A " << endl;
70 a.transpuesta();
71
72 a.eliminar();
73 b.eliminar();
74 c.eliminar();
75
76 return 0;
77 }
Particularmente, todos los ejercicios no son nada difíciles de resolver, pero yo me estanqué
en la moda y creo que fue el problema que me hizo pensar un rato.
Lo resolví, pero sinceramente no me siento bien con la solución. No me gustó porque tiene
una complejidad de O(n2) y con una matriz muy grande puede tarda mucho debido al
número de recorridos y comparaciones.
Crear otra matriz auxiliar con el mismo nro de filas columas y llenarla con ceros.
Recorrer la matriz original e ir comparando el primer elemento con todos los otros
elementos de la matriz y contar sus repeticiones y así sucesivamente con los demás
elementos.
Si encuentro una repetición, incremento en uno el valor en esa posición de la matriz
auxiliar.
Luego hallar el mayor elemento de la matriz auxiliar.
Y finalmente recorrer la matriz auxiliar, cuando algún elemento de esta matriz sea
igual al mayor elemento, quiere decir, que ese fue el elemento que más se repitió en
la matriz original. Por lo tanto la moda se encuentra en esa posición.
view source
print?
01 Matriz original
02 17 16 10 26
03 10 3 9 19
04 29 7 1 6
05 6 20 0 10
06
07 Matriz auxiliar al inicio
08 0 0 0 0
09 0 0 0 0
10 0 0 0 0
11 0 0 0 0
12
13 Matriz auxiliar despues de las comparaciones
14 con el nro de repeticiones de los valores
15 1 1 3 1
16 3 1 1 1
17 1 1 1 2
18 2 1 1 3
Un tip que me dió el profe es reducir el nro de comparaciones creando una matriz booleana
e ir poniendo unos y ceros a los números que ya comparé para luego no volver a comparar
con los números que comparé anteriormente. Voy a seguir resolviendo el problema,si
alguien tiene otra solución y puede explicarla fantástico.