elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado: Curso de javascript por TickTack


  Mostrar Mensajes
Páginas: 1 ... 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 [20] 21 22 23 24 25 26
191  Programación / Programación C/C++ / Re: tableros en: 5 Marzo 2014, 17:06 pm
Hola. ¿Qué simbolos dibujan esos códigos ASCII? A mí no me parecen símbolos de un tablero de ajedrez o similar ...  :huh:

No se si querrás producir algo como esto:

+---+---+---+---+
| a | b | c | d |
+---+---+---+---+
| e | f | g | h |
+---+---+---+---+


Bueno, esperando a que respondas pero si ese es el caso aquí tienes un pequeño código que hace la tarea. Por comodida, creé la función fillRow que rellena una fila dada de la matriz con los caracteres de una cadena pasada como argumento. En este caso puse 'x' como relleno de la casilla, y espacio para dejar vacía la misma. Reemplaza el símbolo de relleno por el que tú requieres. Además, puedes cambiar las constantes M y N por otros valores en caso de querer redimensionar la matriz.

Código
  1. #include <stdlib.h>
  2. #include <stdio.h>
  3.  
  4. #define M 8
  5. #define N 8
  6.  
  7. void fillRow( char **, int, const char *);
  8. void printBoard( char ** );
  9.  
  10. int main() {
  11.  
  12. char **A;
  13. int i;
  14.  
  15. /* Inicializa la matriz, y termina si ocurre error */
  16. if ( ( A = (char **) malloc ( M * sizeof(char *) ) ) == NULL )
  17. return -1;
  18. for (i = 0; i < M; i++ )
  19. if ( ( A[i] = (char *) malloc ( N * sizeof(char) ) ) == NULL )
  20. return -1;
  21.  
  22. fillRow( A, 0, "xxx xx x" );
  23. fillRow( A, 1, "x  x  x " );
  24. fillRow( A, 2, "x x x x " );
  25. fillRow( A, 3, "xxxxx   " );
  26. fillRow( A, 4, "xx      " );
  27. fillRow( A, 5, "xx xx xx" );
  28. fillRow( A, 6, "x  xxxx " );
  29. fillRow( A, 7, "xxxxxxxx" );
  30.  
  31. /* imprimir el tablero */
  32. printBoard( (char **)A );
  33.  
  34. return 0;
  35. }
  36.  
  37. /* Rellena la fila i de la matriz A con los elementos del vector x */
  38. void fillRow( char **A, int i, const char *x) {
  39.  
  40. int j;
  41.  
  42. for (j = 0; j < N; j++)
  43. A[i][j] = x[j];
  44. }
  45.  
  46. /* Imprime un tablero de 8x8, rellenando las casillas con los
  47.  * caracteres almacenados en la matriz A
  48.  */
  49. void printBoard( char **A ) {
  50.  
  51. int i, j;
  52. char c, *s;
  53.  
  54. puts("+---+---+---+---+---+---+---+---+");
  55. for (i = 0; i < M; i++) {
  56. putchar('|');
  57. for (j = 0; j < N; j++)
  58. if ( A[i][j] != '\0' )
  59. printf(" %c |", A[i][j]);
  60. else
  61. printf("   |");
  62. puts("\n+---+---+---+---+---+---+---+---+");
  63. }
  64. putchar('\n');
  65. }
192  Programación / Programación C/C++ / Re: ayuda en: 5 Marzo 2014, 16:57 pm
Estimados engelx y leosansan,

Me acuso culpable de tener problemas de visión al no haber leído la palabra "centenar". A cualquiera le ocurre un lapsus de lectura, y esto no es motivo para descalificar la preparación de la persona. La solución que propuse es correcta de no ser por la condición i + j + k = 100 que sinceramente no había leído. ¡Sencillamente eso!

Y me parece que ustedes han exagerado este caso con el único motivo de descalificarme. Si me quieren fuera del foro, pues díganmelo, o dirijan una petición al moderador sustentada con los delitos de que me acusan.

El programa se corrige al añadir la condición i + j + k == 100 dentro del if y ajustar los valores de i_MAX, j_MAX y k_MAX para que no excedan de 98.

Respecto al código complejo, pues traté de hacer un programa un poco elaborado, que "hablara" con el usuario y fuera flexible en el sentido de que las constantes A, B, C, T pudieran ser cambiadas para resolver un problema con valores diferentes. Me acuso también culpable de estos delitos!!! Ah, ..... y la línea

printf("%d, %d, %d, %d\n", i_MAX, j_MAX, k_MAX, i_MAX*j_MAX*k_MAX);

no iba, era sólo con propósitos de debug  :D
193  Programación / Programación C/C++ / Para entender el algoritmo de inserción en: 4 Marzo 2014, 19:02 pm
En esta ocasión quiero compartir un programita divertido que muestra de manera interactiva la ejecución del algoritmo de ordenamiento por inserción. Básicamente va ordenando el arreglo e indicando por pantalla lo que va haciendo: cómo se mueven los elementos y cómo va quedando el vector tras cada paso ....

Un programita amigable y con un propósito bien didáctivo .... enjoy it!!

Código
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3.  
  4. #define N 5
  5.  
  6. int main(void) {
  7.  
  8. int x[N] = {7, 3, 11, 5, 1};
  9. int i, j, k;
  10. int aux;
  11.  
  12. printf("Arreglo original: \n");
  13. for (k = 0; k < N; k++)
  14. printf(" %d", x[k]);
  15. printf("\n");
  16.  
  17. for (i = 1; i < N; i++) {
  18.  
  19. /* buscamos desde 0 hasta i - 1, el primer elemento que sea
  20. * mayor que x[i] */
  21. printf("ubicando %d ...", x[i]);
  22. j = 0;
  23. while (j < i && x[j] <= x[i])
  24. j++;
  25.  
  26. if ( j < i ) {
  27.  
  28. /* insertar x[i] en la posición j, y desplazar los
  29. * restantes elementos hacia la derecha */
  30. printf(" poner en posicion %d\n", j);
  31.  
  32. for (k = 0; k < N; k++)
  33. printf(" %d", x[k]);
  34. printf("  -> ");
  35.  
  36. aux = x[i];
  37. for (k = i; k > j; k--)
  38. x[k] = x[k-1];
  39. x[j] = aux;
  40.  
  41. for (k = 0; k < N; k++)
  42. printf(" %d", x[k]);
  43. printf("\n");
  44. }
  45. else
  46. printf(" sin cambios\n");
  47. }
  48. printf("El arreglo final ordenado es:\n");
  49. for (i = 0; i < N; i++)
  50. printf(" %d", x[i]);
  51. printf("\n");
  52.  
  53. return 0;
  54. }
194  Programación / Programación C/C++ / Re: Ayuda con arrays y punteros en: 4 Marzo 2014, 18:46 pm
Para ayudarte mejor creo que debes darnos más información sobre el contexto de tu trabajo. Pareciera que quisieras ordenar un arreglo de cadenas, .... ahora no le veo sentido a guardar los resultados de las permutaciones.

Ten en cuenta que el número de permutaciones puede ser mayor a la cantidad de elementos del arreglo, o sea que no sabrás de antemano cuántas cadenas intermedias debes guardas. Quizá se requiera dimensionamiento dinámico (aumento de la longitud del vector en tiempo de ejecución).

Por otra parte, si tratas de implementar un algoritmo de ordenamiento, ¿por qué la permutación de los elementos se realiza incondicionalmente, es decir, sin verificar ninguna condición de orden entre los elementos?

Debes aclararnos mejor sobre el trabajo que se quiere realizar ...
195  Programación / Programación C/C++ / Re: ayuda en: 4 Marzo 2014, 17:28 pm
Saludos a todos. Como profesor de matemáticas me permito hacer algunos comentarios. Es básicamente un problema lógico de combinatoria. Pero quiero decir que el planteamiento de suponer un máximo de 100 asistentes hombres no es técnicamente correcto (empezando porque es un completamente arbitrario). Además, hay que tener en cuenta que elegido un valor para la cantidad de hombres, aún existen muchos pares de combinaciones de mujer-niño. O sea, se tienen tres variables i, j, k y no una.

En síntesis, el problema consiste en encontrar todas las tripletas de valores i, j, k que satisfagan:

A*i + B*j + C*k = T

siendo A, B, C la cantidad de monedas aportadas por cada hombre, mujer o niño respectivamente, T el total de monedas, y siendo i, j, k enteros positivos.
Y efectivamente hay infinitas soluciones, por tratarse de más incógnitas que ecuaciones!!!

Yo voy a suponer (no se si esto se halle efectivamente entre las condiciones del ejercicio) que hubo por lo menos uno hombre, por lo menos una mujer y por lo menos un niño, así que i, j, k deben ser mayores o iguales a 1.

Ahora, ¿cuáles son los mayores valores posibles de i, de j  y de k? Pues, el máximo de i viene dado cuando j  y k tienen los valores mínimos: j = k = 1 (una sola mujer y un solo niño). Ello produce:

i_MAX = (T - 1*B - 1*C)/A;

(redondeando i_MAX al entero más cercano por debajo). Similarmente se obtienen el máximo de j y el máximo de k:

j_MAX = (T - 1*A - 1*C)/B;
k_MAX = (T - 1*A - 1*B)/C;


Sacando las cuentas se obtiene un máximo de:

103 hombres
78 mujeres
192 niños

Luego debemos probar todas las combinaciones para 1 <= i <= i_MAX, 1 <= j <= j_MAX, 1 <= k <= k_MAX, y seleccionar aquéllas donde  A*i + B*j + C*k == T. Ahora sabiendo todo esto,el código del programa resulta bien sencillo, pero les cuento que se hallan 106 soluciones, jeje. La que se propuso H = 33, M = 46, N = 21 es una de ellas pero hay otras por ejemplo:

H = 25, M = 46, N = 36
H = 26, M = 21, N = 96
H = 27, M = 36, N = 57

y muchas más.

El programa aquí:
Código
  1. #include <stdlib.h>
  2. #include <stdio.h>
  3.  
  4. /* Nota: Sean
  5.  *
  6.  *  A la cantidad de monedas que aporta cada hombre
  7.  *  B la cantidad de monedas que aporta cada mujer
  8.  *  C la cantidad de monedas que aporta cada nino
  9.  *  T el total de monedas
  10.  *
  11.  * entones tenemos:
  12.  */
  13. #define A 75
  14. #define B 99
  15. #define C 40
  16. #define T 7869
  17. /* por otra parte, siendo i la cantidad de hombres, j la cantidad
  18.  * de mujeres y k la cantidad de ninos, la condicion buscada es que
  19.  *  
  20.  *  A*i + B*j + C*k = T
  21.  *
  22.  * siendo i, j, k numeros enteros y positivos. La solucion la buscaremos
  23.  * por tanteo (fuerza bruta) mostrando todas las combinaciones posibles.
  24.  */
  25.  
  26. int main () {
  27.  
  28. int i, j, k, count;
  29. int i_MAX, j_MAX, k_MAX;
  30.  
  31. printf( "********************************************\n"
  32.    "Programa de calculo de combinaciones\n"
  33.    "********************************************\n\n" );
  34.  
  35. printf( "Condiciones:\n"
  36. " cada hombre aporta %d monedas\n"
  37. " cada mujer aporta  %d monedas\n"
  38. " cada nino aporta   %d monedas\n"
  39. " Total:             %d monedas.\n\n",
  40. A, B, C, T );
  41.  
  42. /* El maximo valor posible de i sera el cociente entero de
  43. * (T - 1*B - 1*C) entre A, es decir, el valor entero de i que satisface
  44. * la ecuacion:
  45. *
  46. *  A*i + B*j + C*k = T
  47. *
  48. * con los valores minimos de j = 1, k = 1. De modo similar se calculan
  49. * los valores maximos posibles de j y k.
  50. */
  51. i_MAX = (T - 1*B - 1*C)/A;
  52. j_MAX = (T - 1*A - 1*C)/B;
  53. k_MAX = (T - 1*A - 1*B)/C;
  54.  
  55. printf("%d, %d, %d, %d\n", i_MAX, j_MAX, k_MAX, i_MAX*j_MAX*k_MAX);
  56.  
  57. count = 0;
  58. for ( i = 1; i <= i_MAX; i++ )
  59. for ( j = 1; j <= j_MAX; j++ )
  60. for ( k = 1; k <= k_MAX; k++ )
  61. if ( A*i + B*j + C*k == T ) {
  62. printf( "Se encontro la combinacion H = %d, M = %d, N = %d\n",
  63. i, j, k);
  64. count ++;
  65. }
  66. printf( "%d resultados. -- FIN DEL PROGRAMA --\n", count);
  67. }

y el resultado que arroja (larguísimo):

********************************************
Programa de calculo de combinaciones
********************************************

Condiciones:
 cada hombre aporta 75 monedas
 cada mujer aporta  99 monedas
 cada nino aporta   40 monedas
 Total:             7869 monedas.

Se encontro la combinacion H = 1, M = 6, N = 180
Se encontro la combinacion H = 1, M = 46, N = 81
Se encontro la combinacion H = 2, M = 21, N = 141
Se encontro la combinacion H = 2, M = 61, N = 42
Se encontro la combinacion H = 3, M = 36, N = 102
Se encontro la combinacion H = 3, M = 76, N = 3
Se encontro la combinacion H = 4, M = 11, N = 162
Se encontro la combinacion H = 4, M = 51, N = 63
Se encontro la combinacion H = 5, M = 26, N = 123
Se encontro la combinacion H = 5, M = 66, N = 24
Se encontro la combinacion H = 6, M = 1, N = 183
Se encontro la combinacion H = 6, M = 41, N = 84
Se encontro la combinacion H = 7, M = 16, N = 144
Se encontro la combinacion H = 7, M = 56, N = 45
Se encontro la combinacion H = 8, M = 31, N = 105
Se encontro la combinacion H = 8, M = 71, N = 6
Se encontro la combinacion H = 9, M = 6, N = 165
Se encontro la combinacion H = 9, M = 46, N = 66
Se encontro la combinacion H = 10, M = 21, N = 126
Se encontro la combinacion H = 10, M = 61, N = 27
Se encontro la combinacion H = 11, M = 36, N = 87
Se encontro la combinacion H = 12, M = 11, N = 147
Se encontro la combinacion H = 12, M = 51, N = 48
Se encontro la combinacion H = 13, M = 26, N = 108
Se encontro la combinacion H = 13, M = 66, N = 9
Se encontro la combinacion H = 14, M = 1, N = 168
Se encontro la combinacion H = 14, M = 41, N = 69
Se encontro la combinacion H = 15, M = 16, N = 129
Se encontro la combinacion H = 15, M = 56, N = 30
Se encontro la combinacion H = 16, M = 31, N = 90
Se encontro la combinacion H = 17, M = 6, N = 150
Se encontro la combinacion H = 17, M = 46, N = 51
Se encontro la combinacion H = 18, M = 21, N = 111
Se encontro la combinacion H = 18, M = 61, N = 12
Se encontro la combinacion H = 19, M = 36, N = 72
Se encontro la combinacion H = 20, M = 11, N = 132
Se encontro la combinacion H = 20, M = 51, N = 33
Se encontro la combinacion H = 21, M = 26, N = 93
Se encontro la combinacion H = 22, M = 1, N = 153
Se encontro la combinacion H = 22, M = 41, N = 54
Se encontro la combinacion H = 23, M = 16, N = 114
Se encontro la combinacion H = 23, M = 56, N = 15
Se encontro la combinacion H = 24, M = 31, N = 75
Se encontro la combinacion H = 25, M = 6, N = 135
Se encontro la combinacion H = 25, M = 46, N = 36
Se encontro la combinacion H = 26, M = 21, N = 96
Se encontro la combinacion H = 27, M = 36, N = 57
Se encontro la combinacion H = 28, M = 11, N = 117
Se encontro la combinacion H = 28, M = 51, N = 18
Se encontro la combinacion H = 29, M = 26, N = 78
Se encontro la combinacion H = 30, M = 1, N = 138
Se encontro la combinacion H = 30, M = 41, N = 39
Se encontro la combinacion H = 31, M = 16, N = 99
Se encontro la combinacion H = 32, M = 31, N = 60
Se encontro la combinacion H = 33, M = 6, N = 120
Se encontro la combinacion H = 33, M = 46, N = 21
Se encontro la combinacion H = 34, M = 21, N = 81
Se encontro la combinacion H = 35, M = 36, N = 42
Se encontro la combinacion H = 36, M = 11, N = 102
Se encontro la combinacion H = 36, M = 51, N = 3
Se encontro la combinacion H = 37, M = 26, N = 63
Se encontro la combinacion H = 38, M = 1, N = 123
Se encontro la combinacion H = 38, M = 41, N = 24
Se encontro la combinacion H = 39, M = 16, N = 84
Se encontro la combinacion H = 40, M = 31, N = 45
Se encontro la combinacion H = 41, M = 6, N = 105
Se encontro la combinacion H = 41, M = 46, N = 6
Se encontro la combinacion H = 42, M = 21, N = 66
Se encontro la combinacion H = 43, M = 36, N = 27
Se encontro la combinacion H = 44, M = 11, N = 87
Se encontro la combinacion H = 45, M = 26, N = 48
Se encontro la combinacion H = 46, M = 1, N = 108
Se encontro la combinacion H = 46, M = 41, N = 9
Se encontro la combinacion H = 47, M = 16, N = 69
Se encontro la combinacion H = 48, M = 31, N = 30
Se encontro la combinacion H = 49, M = 6, N = 90
Se encontro la combinacion H = 50, M = 21, N = 51
Se encontro la combinacion H = 51, M = 36, N = 12
Se encontro la combinacion H = 52, M = 11, N = 72
Se encontro la combinacion H = 53, M = 26, N = 33
Se encontro la combinacion H = 54, M = 1, N = 93
Se encontro la combinacion H = 55, M = 16, N = 54
Se encontro la combinacion H = 56, M = 31, N = 15
Se encontro la combinacion H = 57, M = 6, N = 75
Se encontro la combinacion H = 58, M = 21, N = 36
Se encontro la combinacion H = 60, M = 11, N = 57
Se encontro la combinacion H = 61, M = 26, N = 18
Se encontro la combinacion H = 62, M = 1, N = 78
Se encontro la combinacion H = 63, M = 16, N = 39
Se encontro la combinacion H = 65, M = 6, N = 60
Se encontro la combinacion H = 66, M = 21, N = 21
Se encontro la combinacion H = 68, M = 11, N = 42
Se encontro la combinacion H = 69, M = 26, N = 3
Se encontro la combinacion H = 70, M = 1, N = 63
Se encontro la combinacion H = 71, M = 16, N = 24
Se encontro la combinacion H = 73, M = 6, N = 45
Se encontro la combinacion H = 74, M = 21, N = 6
Se encontro la combinacion H = 76, M = 11, N = 27
Se encontro la combinacion H = 78, M = 1, N = 48
Se encontro la combinacion H = 79, M = 16, N = 9
Se encontro la combinacion H = 81, M = 6, N = 30
Se encontro la combinacion H = 84, M = 11, N = 12
Se encontro la combinacion H = 86, M = 1, N = 33
Se encontro la combinacion H = 89, M = 6, N = 15
Se encontro la combinacion H = 94, M = 1, N = 18
Se encontro la combinacion H = 102, M = 1, N = 3
106 resultados. -- FIN DEL PROGRAMA --

 :laugh:
196  Foros Generales / Sugerencias y dudas sobre el Foro / Sitio externo para subir los archivos fuente en: 3 Marzo 2014, 18:49 pm
A veces cuando colocamos fragmentos de código muy grandes en nuestros posts, los mismos se hacen de una extensión inmensa. Imagínense si se trata de un proyecto grande con varias cabecera, y fuentes ...

Me gustaría saber si ustedes recomienda un sitio externo especializado en subir archivos fuentes de C, y colocar en nuestros post sólo el link a dichos sitios

..........  :huh:
197  Programación / Programación C/C++ / Biblioteca de matriz de cadenas en: 3 Marzo 2014, 18:44 pm
Hola a todos. En esta ocasión quiero compartir un trabajo con la comunidad. También se aceptan críticas (de buena fe), sugerencias, etc ...

A veces queremos leer texto organizado en forma de tabla, con filas y columas. Por ejemplo, a partir de un fichero de texto formateado en columnas, o en el resultado de convertir una hoja de cálculo a un .txt
En tales ocasiones es común crear una matriz bidimensional de cadenas para almacenar los datos.

Como es una tarea rutinaria y repetitiva, quise desarrollar una clase "StringMatrix" de matriz de cadenas. Dicha clase posee su respectivo constructor por defecto, un constructor de copia (para obtener un objeto nuevo como copia idéntica del contenido de otro), un operador de asignación (para hacer el contenido de un StringMatrix idéntido al de otro), así como los tradicionales getElement y putElement para obtener y colocar elementos desde y en la matriz. Funcionan así:
Código
  1. putElement(i, j, str);
escribe el contenido del string str en la posición (i,j) de la matriz (los valores de los índices empiezan en cero). Es de hacer notar que trabaja "por copia", esto es, el elemento (i,j) reserva su espacio de memoria propio donde copia el contenido de str, luego el propio str puede alterado luego sin afectar el contenido de la matriz. Por otra parte, si se pide asignar en una posición que excede el tamaño de la matriz, se intenta dimensionar la misma previamente. Devuelve -1 en caso de error (por ejemplo, si falla la asignación de memoria), y 0 en caso de éxito.

Código
  1. str = getElement(i, j);
devuelve en str una copia del contenido del elemento (i,j) de la matriz. Es importante que devuelva un valor "por copia", pues así podemos alterar el string str devuelto sin afectar la matriz original.

Los métodos NRows() y NCols(), que no toman argumentos, devuelven la cantidad de filas y columnas, respectivamente, de la matriz (al crear el objeto, estos números valen cero). Por su parte, los métodos addRow() y addColumn() sirven para añadir una fila o una columna a la matriz.

Finalmente el destructor como era de esperarse libera toda la memoria dinámicamente asignada y retorna. Se cuenta con un método peculiar Reinitialize() el cual también libera la memoria asignada y pone las dimensiones de la matriz a cero. Es similar al destructor, excepto que no destruye al objeto (éste sigue vivo) sino que lo pone en las mismas condiciones de cuándo fue creado. Es como "vaciar" la matriz para poder llenarla de nuevo.

CONDICIONES DE PRECAUCIÓN: Es de hacer notar que si el objeto no se crea con éxito (falla la petición de memoria realizada), sus dimensiones se ponen en -1. Los métodos getElement() y putElement() inspeccionan primero si existe esta condición de error y en dicho caso no se ejecutan. De un modo similar los métodos addRow() y addColumn() inspecionan si la petición de memoria fue exitosa y sólo en ese caso incrementan el contador de filas o de columnas. En caso contrario, no se añade ninguna fila o columna, y las dimensiones de la matriz permanecen iguales.

En mi opinión pueden mejorarse algunas cosas, como los nombres de los métodos (quizá addCol() en lugar de addColumn()), y añadir la posibilidad de eliminar una fila o columna solamente. También incorporar un método para redimensionar, que automáticamente añada las filas o columnas que hagan falta si se pasa de una dimensión menor a una mayor, o elimine las que sobren en caso contrario.

Aquí el fichero de cabecera de la clase. Ojo: el que algunos comentarios están en inglés no significa que me lo haya copiado de internet >:(, sino que los puse en ese idioma por si navegando por el inmenso mundo que es la web, este código llega a ser leído fuera de fronteras hispanas (jeje, aunque eso requeriría mucha suerte  :laugh:)

Código
  1. /* SMATRIX.H
  2.  * Declaración de la clase sMatrix
  3.  * Las funciones miembro están definidas en smatrix.cpp
  4.  *
  5.  * Por Yoel Monsalve.
  6.  */
  7.  
  8. #ifndef SMATRIX_H
  9. #define SMATRIX_H
  10.  
  11. /*** Definición de la clase StringMatrix ***/
  12. class StringMatrix { // matriz de cadenas de caracteres
  13. public:
  14. StringMatrix(); /* constructor por defecto */
  15. StringMatrix( StringMatrix & ); /* constructor de copia */
  16. ~StringMatrix(); /* destructor */
  17. void ReInitialize(void);
  18. char *getElement(int, int);
  19. int putElement(int, int, const char *);
  20. int NRows();
  21. int NCols();
  22. int addRow(); /* añadir una fila: devuelve 0 si tuvo éxito, -1 si no tuvo */
  23. int addColumn(); /* añadir una columna: devuelve 0 si tuvo éxito, -1 si no tuvo */s
  24.  
  25. StringMatrix &operator = (StringMatrix &);
  26. private:
  27. char ***Matrix; /* para almacenar físicamente los elementos de la matriz */
  28. int _NRows; /* cantidad de filas */
  29. int _NCols; /* cantidad de columnas */
  30. };
  31.  
  32. #endif

y ahora el código fuente de la clase:

Código
  1. /* SMATRIX.CPP
  2.  * Definiciones de funciones miembro de la clase sMatrix.
  3.  *
  4.  * Por Yoel Monsalve.
  5.  */
  6.  
  7. #include <stdio.h>
  8. #include <stdlib.h>
  9. #include <string.h>
  10. #include "smatrix.h"
  11.  
  12. /* Default constructor.
  13.  * Constructor por defecto. */
  14. StringMatrix :: StringMatrix( ) {
  15.  
  16. Matrix = (char ***) malloc( sizeof(char **) );
  17.  
  18. if (Matrix != NULL)
  19. _NRows = _NCols = 0; /* success */
  20. else
  21. _NRows = _NCols = -1; /* constructor failed !!! */
  22. }
  23.  
  24. /* Copy constructor. Creates a new object as a copy of other object.
  25.  * Constructor de copia. Crea un nuevo objeto como una copia de otro objeto. */
  26. StringMatrix :: StringMatrix ( StringMatrix &S ) {
  27.  
  28. int i, j;
  29.  
  30. Matrix = (char ***) malloc( sizeof(char **) );
  31. if (Matrix != NULL)
  32. _NRows = _NCols = 0; /* success */
  33. else {
  34. _NRows = _NCols = -1; /* constructor failed !!! */
  35. return;
  36. }
  37.  
  38. /* resize at the same size of S */
  39. if ( S.NRows() < 0 || S.NCols() < 0 ) return;
  40. while ( _NRows < S.NRows() )
  41. addRow();
  42. while ( _NCols < S.NCols() )
  43. addColumn();
  44.  
  45. printf("%d, %d\n", S.NRows(), S.NCols());
  46. /* and copy here the content of S */
  47. for ( i = 0; i < _NRows; i++ )
  48. for ( j = 0; j < _NCols; j++ )
  49. Matrix[i][j] = S.getElement(i, j);
  50. }
  51.  
  52. /* Assignment operator, from other StringMatrix object.
  53.  * Operador de asignacióm, a partir de otro objeto StringMatrix. */
  54. StringMatrix & StringMatrix :: operator = (StringMatrix &S) {
  55.  
  56. int i, j;
  57.  
  58. /* avoid self-assignment */
  59. if ( &S == this ) return *this;
  60.  
  61. /* caution if matrix creation failed */
  62. if ( _NRows < 0 || _NCols < 0 )
  63. return *this;
  64.  
  65. /* resize at the same size of S */
  66. if ( S.NRows() < 0 || S.NCols() < 0 ) return *this;
  67. while ( _NRows < S.NRows() )
  68. addRow();
  69. while ( _NCols < S.NCols() )
  70. addColumn();
  71.  
  72. /* and copy here the content of S */
  73. for ( i = 0; i < _NRows; i++ )
  74. for ( j = 0; j < _NCols; j++ )
  75. Matrix[i][j] = S.getElement(i, j);
  76. }
  77.  
  78. /* "Re-initializes" the object. Frees the dinamic allocated memory, and
  79.  * it puts the dimensions to zero. This is, returns he object to the original
  80.  * state like it was created.
  81.  *
  82.  * "Re-inicializa" el objeto. Libera la memoria dinámicamente asignada,
  83.  * y pone las dimensiones a cero. Es decir, devuelve el objeto al estado
  84.  * original como fue creado */
  85. void StringMatrix :: ReInitialize( ) {
  86.  
  87. int i, j;
  88.  
  89. /* if matrix creation failed, try create it again */
  90. if ( _NRows < 0 || _NCols < 0 ) {
  91. Matrix = (char ***) malloc( sizeof(char **) );
  92. if (Matrix != NULL)
  93. _NRows = _NCols = 0; /* success */
  94. else {
  95. _NRows = _NCols = -1; /* constructor failed !!! */
  96. return;
  97. }
  98. }
  99.  
  100. /* frees the allocated memory space */
  101. if (_NRows > 0) {
  102. for (i = 0; i < _NRows; i++) {
  103. if (_NCols > 0) {
  104. for (j = 0; j < _NCols-1; j++)
  105. free(Matrix[i][j]);
  106. Matrix[i][j] = NULL;
  107. }
  108. free(Matrix[i]);
  109. Matrix[i] = NULL;
  110. }
  111. }
  112. _NRows = _NCols = 0;
  113. }
  114.  
  115. /* Class destructor /
  116.  * Destructor de la clase */
  117. StringMatrix :: ~StringMatrix( ) {
  118. int i, j;
  119.  
  120. /* frees the allocated memory assigned to the objects /
  121. * libera el espacio de memoria asignado a los objetos */
  122. for (i=0; i<_NRows; i++) {
  123. for (j=0; j<_NCols; j++) {
  124. free( Matrix[i][j] );
  125. Matrix[i][j] = NULL;
  126. }
  127. free( Matrix[i] );
  128. Matrix[i] = NULL;
  129. }
  130. free( Matrix );
  131. Matrix = NULL;
  132.  
  133. _NRows = -1;
  134. _NCols = -1;
  135. }
  136.  
  137. /* Get the number of rows of the matriz /
  138.  * Obtener el numero de filas de la matriz */
  139. int StringMatrix :: NRows( ) {
  140.  
  141. return _NRows;
  142. }
  143.  
  144. /* Get the number of columns of the matriz /
  145.  * Obtener el numero de columnas de la matriz */
  146. int StringMatrix :: NCols( ) {
  147.  
  148. return _NCols;
  149. }
  150.  
  151. /* Get an specific element in the matrix. Warning: the indexes start in zero.
  152.  * On success is returned a copy of the string stored in such element of
  153.  * the matrix. On error, returns NULL.
  154.  
  155. /* Obtener un elemento especifico de la matriz. Cuidado: los índices empiezan
  156.  * en cero. En caso exitoso devuelve una copia de la cadena almacenada en
  157.  * dicho elemento de la matriz. En caso de error, devuelve NULL. */
  158. char * StringMatrix :: getElement( int i, int j ) {
  159.  
  160. char *s;
  161.  
  162. /* caution if matrix creation failed */
  163. if ( _NRows < 0 || _NCols < 0 )
  164. return NULL;
  165.  
  166. /* must be 0 <= i <= _N_Rows - 1, and 0 <= j <= _NCols - 1 */
  167. if (i < 0 || i >= _NRows || j < 0 || j >= _NCols)
  168. return NULL;
  169.  
  170. if ( ( s = (char *) malloc ( (strlen(Matrix[i][j]) + 1) * sizeof(char) ) ) == NULL )
  171. return NULL;
  172.  
  173. strcpy(s, Matrix[i][j]);
  174. return s;
  175. }
  176.  
  177. /* Puts an element in a specified position of the matrix. If the position
  178.  * exceed the size of matrix, the same is automatically resized.
  179.  * On success returns 0, and -1 otherwise.
  180.  *
  181.  * Pone un elemento en una posicion especificada de la matriz. Si la posicion
  182.  * excede el tamano de la matriz, la misma es redimensionada automaticamente.
  183.  * Devuelve 0 si tuvo exito, -1 si no tuvo. */
  184. int StringMatrix :: putElement( int i, int j, const char * s ) {
  185.  
  186. char *cPtr;
  187.  
  188. /* caution if matrix creation failed */
  189. if ( _NRows < 0 || _NCols < 0 )
  190. return -1;
  191.  
  192. /* fail if i < 0, or j < 0 */
  193. if ( i < 0 | j < 0 )
  194. return -1;
  195.  
  196. /* if i > _NRows - 1, completed rows that are needed */
  197. while ( i >= _NRows )
  198. addRow();
  199.  
  200. /* if j > _NCols - 1, completed columns that are needed */
  201. while ( j >= _NCols )
  202. addColumn();
  203.  
  204. /* now, copies the s string in the (i,j) element of the matrix (allocates
  205. * memory before) */
  206. if ( ( cPtr = (char *) realloc( Matrix[i][j], (strlen(s) + 1) * sizeof(char) ) ) != NULL ) {
  207. strcpy(cPtr, s);
  208. Matrix[i][j] = cPtr;
  209. return 0;
  210. }
  211. else
  212. return -1;
  213.  
  214. }
  215.  
  216. /* Add a row to the matrix. On success returs 0, and -1 otherwise.
  217.  *
  218.  * Anade una fila a la matriz. Devuelve 0 si tuvo éxito, -1 si no tuvo. */
  219. int StringMatrix :: addRow() {
  220.  
  221. char ***xPtr;
  222. char **yPtr;
  223. char *zPtr;
  224. int j;
  225.  
  226. /* caution if matrix creation was failed */
  227. if ( _NRows < 0 ) return -1;
  228.  
  229. /* allocate memory for one more row */
  230. if ( ( xPtr = (char ***) realloc( Matrix, (_NRows + 1) * sizeof(char **) ) ) != NULL ) {
  231. Matrix = xPtr;
  232.  
  233. /* if matrix already has columns added */
  234. if ( _NCols > 0 ) {
  235. /* complete the new row with empty elements */
  236. if ( ( yPtr = (char **) malloc( _NCols * sizeof(char *) ) ) != NULL ) {
  237. Matrix[_NRows] = yPtr;
  238. for (j = 0; j < _NCols; j++) {
  239. if ( ( zPtr = (char *) malloc( sizeof(char) ) ) != NULL ) {
  240. Matrix[_NRows][j] = zPtr;
  241. *zPtr = '\0';
  242. }
  243. else
  244. return -1;
  245. }
  246. }
  247. else
  248. return -1;
  249. }
  250. /* otherwise */
  251. else {
  252. /* complete the new row with empty elements */
  253. if ( ( yPtr = (char **) malloc( 1 * sizeof(char *) ) ) != NULL ) {
  254. Matrix[_NRows] = yPtr;
  255. if ( ( zPtr = (char *) malloc( sizeof(char) ) ) != NULL ) {
  256. Matrix[_NRows][0] = zPtr;
  257. *zPtr = '\0';
  258. }
  259. else
  260. return -1;
  261. }
  262. else
  263. return -1;
  264. }
  265. }
  266. else
  267. return -1;
  268.  
  269. /* Success, then increase _NRows and return. */
  270. _NRows++;
  271. return 0;
  272. }
  273.  
  274. /* Add a column to the matrix. On success returs 0, and -1 otherwise.
  275.  *
  276. /* Anade una columna a la matriz. Devuelve 0 si tuvo éxito, -1 si no tuvo. */
  277. int StringMatrix :: addColumn() {
  278.  
  279. char **yPtr;
  280. char *zPtr;
  281. int i;
  282.  
  283. /* return if matrix creation was failed */
  284. if (_NRows <= 0 || _NCols < 0) return -1;
  285.  
  286. for (i = 0; i < _NRows; i++) {
  287. /* allocate memory for one more column */
  288. if ((yPtr = (char **) realloc( Matrix[i], (_NCols + 1) * sizeof(char *) ) ) != NULL ) {
  289. Matrix[i] = yPtr;
  290. if ( ( zPtr = (char *) malloc( sizeof(char) ) ) != NULL ) {
  291. Matrix[i][_NCols] = zPtr;
  292. *zPtr = '\0';
  293. }
  294. else
  295. return -1;
  296. }
  297. else
  298. return -1;
  299. }
  300.  
  301. /* Success, then increase _NCols and return. */
  302. _NCols++;
  303. return 0;
  304. }

Podemos ver ahora su funcionamiento, en el sencillo archivo de prueba que crea dos matrices, llena una con cuatro cadenas. Luego, en la segunda matriz se copia el contenido de la primera, y éste se imprime por la pantalla ¡Fácil!

Código
  1. #include <stdio.h>
  2. #include <smatrix.h>       /* fichero de cabecera de la clase */
  3.  
  4. int main() {
  5.  
  6. StringMatrix S, M;
  7. int i, j;
  8.  
  9. S.putElement(0, 0, "hugo");
  10. S.putElement(0, 1, "paco");
  11. S.putElement(1, 0, "maria");
  12. S.putElement(1, 1, "luisa");
  13.  
  14. /* copia contenido de S en M */
  15. M = S;
  16. /* y lo imprime en pantalla */
  17. for (i = 0; i < 2; i++) {
  18. for (j = 0; j < 2; j++)
  19. printf("%s\t", M.getElement(i, j) );
  20. fputs("\n", stdout);
  21. }
  22.  
  23. return 0;
  24. }

NOTA: para compilar el fichero de prueba, llamado por ejemplo test.cpp, enlazado con el fichero smatrix.cpp que define la clase StringMatrix, usar la orden:

g++ -o test test.cpp smatrix.cpp

y suponiendo que los tres archivos test.cpp, smatrix.cpp y smatrix.h están en el mismo directorio. Para un proyecto grande valdría la pena crear directorios src, include, lib donde poner los ficheros apropiados y compilar adecuadamente según el caso. Se puede también hacer una biblioteca con esta y otras clases de utilería, ustedes ya saben ...

Sugerencias, comentarios ?????
198  Programación / Programación C/C++ / Re: como regreso mas de un variable de una funcion con un apuntador?? en: 3 Marzo 2014, 17:17 pm
Es justo lo que había supuesto, un lapsus involuntario ... (también me ha sucedido). No problem!!!
199  Programación / Programación C/C++ / Re: como regreso mas de un variable de una funcion con un apuntador?? en: 2 Marzo 2014, 21:09 pm
Bueno, comentando acerca del free ha debido ser un despiste o lapsus de eferion, pues si desasignas la memoria del arreglo, el mismo ya no será útil  :huh:

Ahora ya no hablando del programa de eferion sino más en general. Sabemos que sobre gustos no hay nada escrito, pero si se permite mi opinión siempre me ha parecido más elegante la solución de pasar parámetros por referencia a la función. De ese modo se pueden realizar modificaciones a los mismos, con el mismo efecto como si la función devolviera varios parámetros de retorno (que no es permitido en C).

Incluso si usaras un estructura, puede pasarse la misma como argumento por referencia de la función, en lugar de devolver la estructura como valor de retorno.

La razón por la que me inclino por esta modalidad es que (y repito es una opinión personal) luce más acorde con la filosofía original de diseño de C. A ver, por ejemplo cuando usas la función estándar fread para leer de un fichero, no obtienes el arreglo de bytes leídos como valor de retorno, ¿verdad? En su lugar, dicho arreglo (un puntero a char) es pasado como argumento de entrada.

El valor de retorno de las funciones debería ser utilizado más bien para indicar si hubo un error en la ejecución de la misma (devuelve -1) o ejecución exitosa (devuelve 0). O en el caso de funciones de E/S como fread para indicar la cantidad de elementos leídos.

Saludos
200  Programación / Programación C/C++ / Re: [C] pase de parametros en: 2 Marzo 2014, 20:56 pm
Jeje, bueno yo no se por qué el autor del post usó una estructura (aunque sinceramente me pareció algo complicado), sólo traté de aclarar la duda planteada respetando hasta lo posible la integridad del tema original  :D
Páginas: 1 ... 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 [20] 21 22 23 24 25 26
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines