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

 

 


Tema destacado: Introducción a Git (Primera Parte)


  Mostrar Mensajes
Páginas: [1] 2 3 4 5 6 7 8 9 10 11
1  Programación / Programación C/C++ / Re: Pila en C++ en: 6 Noviembre 2022, 00:15 am
Pfff... Hay muchos errores. Es posible que entre tanto código pierdas la perspectiva.

  • Separa la interacción (cin, cout) de la implementación de la pila
  • No uses variables globales. Tiene un pase que quieras hacer una pila "singleton", o sea, que no puedas más que declarar una valor de pila (p_pila), pero nunca la variable auxiliar. Si no, corres el riesgo de asumir valores que en realidad no tiene

Siguiendo un poco "tu voz", esto es lo que he enmendado.

Código
  1. #include <iostream>
  2. #include <stdlib.h>
  3. using namespace std;
  4.  
  5.  
  6.  
  7. typedef struct pila {
  8. int elemento;
  9. pila* enlace;
  10. } pila_t, *pila_tp;
  11.  
  12. void push(const int n);
  13. int pop();
  14. int empty();
  15. void display();
  16. void liberar();
  17.  
  18.  
  19. static pila* p_pila = NULL;
  20.  
  21. int main() {
  22.  
  23. int opcion;
  24.  
  25. cout << "Pila de tipo dinamica" << endl;
  26. cout << "\tMenu\n";
  27. cout << "1)Insertar nuevo elemento a la pila" << endl;
  28. cout << "2)Sacar elemento de la pila" << endl;
  29. cout << "3)Mostrar los elementos de la pila" << endl;
  30. cout << "4)Liberar memoria" << endl;
  31. cout << "5)Salir\n\n";
  32.  
  33. do {
  34.  
  35. cout << "Escoga un opcion: " ;
  36. cin >> opcion;
  37. switch (opcion) {
  38.  
  39. case 1:
  40. int n;
  41. cout << "Numero a insertar ";
  42. cin >> n;
  43. push(n); break;
  44. case 2:
  45. if (!empty())
  46. cout << pop() << endl;
  47. else
  48. cout << "Pila vacia" << endl
  49. ;
  50. break;
  51. case 3:
  52. display(); break;
  53. case 4:
  54. liberar(); break;
  55. case 5:
  56. cout << "Saliendo del programa"; break;
  57. default: cout << "Opcion no valida";
  58.  
  59. }
  60. } while (opcion != 5);
  61.  
  62. return 0;
  63. }
  64.  
  65. int empty() {
  66. return p_pila == NULL;
  67. }
  68.  
  69.  
  70. void push(const int n) {
  71. pila_tp p_aux = new pila;
  72.    p_aux->elemento=n;
  73. p_aux->enlace = p_pila;
  74. p_pila = p_aux;
  75. }
  76.  
  77. int pop() {
  78. /* Take control of p_aux!*/
  79. const int n = p_pila->elemento;
  80. pila_tp p_aux = p_pila;
  81. p_pila = p_aux->enlace;
  82. delete p_aux;
  83. return n;
  84. }
  85.  
  86.  
  87. /* I/O operation */
  88. void display() {
  89. pila_tp p_aux = p_pila;
  90. while (p_aux != NULL)
  91. {
  92. cout << "\t" << p_aux->elemento << endl;
  93. p_aux = p_aux->enlace;
  94. }
  95. }
  96.  
  97. void liberar() {
  98. pila_tp p_aux = p_pila;
  99. while (p_aux!= NULL) {
  100. const pila_tp p_next = p_aux->enlace;
  101. delete p_aux;
  102. p_aux = p_next;
  103. }
  104. p_pila = NULL;
  105.  
  106. }
  107.  
  108.  
  109.  
  110.  


Resultado
Código:

Pila de tipo dinamica
        Menu
1)Insertar nuevo elemento a la pila
2)Sacar elemento de la pila
3)Mostrar los elementos de la pila
4)Liberar memoria
5)Salir

Escoga un opcion: 1
Numero a insertar 10
Escoga un opcion: 1
Numero a insertar 13
Escoga un opcion: 3
        13
        10
Escoga un opcion: 1
Numero a insertar 256
Escoga un opcion: 3
        256
        13
        10
Escoga un opcion: 2
256
Escoga un opcion: 3
        13
        10
Escoga un opcion:




2  Programación / Programación C/C++ / Re: Mostrar el mayor valor de una pila en: 12 Agosto 2022, 17:02 pm
A ver, aprecio dos errores en tu programa.

En primer lugar, propiamente no estás implementando una pila. Es cierto que parece que la simulas con un vector y un indice al ultimo elemento ( por cierto, es más natural marcar cuantos elementos tiene la pila), pero no das ninguna rutina de abstracción y el programador puede acceder al tipo emulador (vector e indice) con total libertad. Queda a tu elección el rigor con que lo quieras tratar.

 En el mundo Python por ejemplo, ya nadie implementaria un tipo para pila, todo el mundo usa las listas directamente, como tu sugieres.

Si escoges la implementación hecha en la librer'ia estadard, esta es tu rutina.


Código
  1. #include <stack>
  2. #include <iostream>
  3. #include <cassert>
  4. #include <algorithm> // using max function.
  5.  
  6. int compute_max(const std::stack<int> &s)
  7. {
  8.    assert(s.size() > 0);
  9.    std::stack<int> copy(s);
  10.    int M = copy.top();
  11.    copy.pop();
  12.    while (!empty(copy))
  13.    {
  14.        M = std::max(M,copy.top());
  15.        copy.pop();
  16.    }
  17.    return M;
  18. }
  19.  

Observa que el problema est'a solo definido si como m'inimo tienes un elemento en la pila, y observa como debemos hacer una copia de la pila original, para no modificiarla.

Código
  1. int main(int argc, char const *argv[])
  2. {
  3.    std::stack<int>  s ;
  4.    int N;
  5.    for( ; std::cin >> N ;)
  6.       s.push(N);
  7.    int M = compute_max(s);
  8.    std::cout << M;
  9.    return 0;
  10. }


Para experimentar interactivamente con el programa,,,


Código:
34  -1 45 67
^Z
67
3  Programación / Programación C/C++ / Re: Comparacion de arrays y eliminacion de elementos iguales en: 9 Junio 2022, 10:52 am
Lo que Serapis propone es emular la unión de conjuntos con vectores, dado que en su representación más básica en C, los conjuntos consisten en vectores con elementos no repetidos.


Un algoritmo que hace esto muy eficiente (dadas ciertas restricciones*), es una versión del algoritmo 'counting-sort'.
...

Dicho brevemente, sea  max(A) el maximo numero de A, N el tamaño de A y M el tamaño de B .

Entonces la solucion de Serapis
  • Tiempo:   O(max(A)+N+M)
  • Memoria: O(max(A)+N+M)
La mía, (si implementese la uni'on de conjuntos, con memoria dinamica... etc)
  • Tiempo:   O(N*M)
  • Memoria: O(N+M)

en resumen, es una solución de compromiso, dependiendo del valor relativo del máximo y las longitudes de A y B se puede bajar en tiempo de N*M a lineal en N+M+max(A)... a base de invertir en memoria, que nunca baja,por supuesto...

Bueno, no estoy muy seguro de lo que digo. CAUTION.

4  Programación / Programación C/C++ / Re: Comparacion de arrays y eliminacion de elementos iguales en: 2 Junio 2022, 10:16 am
Hay una pequeña confusion en lo que planteas.
  • si hablas de eliminar elementos iguales (como en la prosa), la operacion es A union B \ (A intersec. B) . Es decir A={1,2,3,4,5} B={2,4,6,8,10} C={1,3,5,8,10}, lo que dice Falo.
  • si hablas de resta o diferencias de conjuntos (como en el programa), la operación es A\B, quitando del primero los del segundo. Es decir A={1,2,3,4,5} B={2,4,6,8,10} C={1,3,5}NO ES CONMUTATIVA (Esto es importante). a

Empiezo por la segunda - que creo que es la que quires realmente hacer. el mayor fallo es que no inicializas k y el bucle no es correcto. mira este.


Código
  1.   k=0;
  2.   for(i=0;i<TC;i++){
  3.   for(j=0;j<TC && a[i]!=b[j];j++); // cuerpo vacio a proposito
  4.   if (j==TC) {
  5.         c[k]=a[i];
  6.         k++;
  7.         }
  8.    }
  9.  
Y la salida es

Código:
A={     1       2       3       4       5       }
B={     2       4       6       8       10      }
La diferencia es: { 1  3  5 }

En el caso de la primera, es cierto que C puede llegar a ser la suma de A y B (si no tienen elementos en comun). Pon, por ejemplo, c[5+5] . El bucle se repite para ambos lados.


Código
  1.  
  2.        k=0;
  3. for(i=0;i<TC;i++){
  4.   for(j=0;j<TC && a[i]!=b[j];j++); // cuerpo vacio a porposito
  5.           if (j==TC) {
  6.              c[k]=a[i];
  7.              k++;
  8.           }
  9.       }
  10.  
  11. for(i=0;i<TC;i++){
  12.   for(j=0;j<TC && b[i]!=a[j];j++); // cuerpo vacio a proposito.
  13.           if (j==TC) {
  14.             c[k]=b[i];
  15.             k++;
  16.         }
  17.    }

Y la salida es .

Código:
A={     1       2       3       4       5       }
B={     2       4       6       8       10      }
La diferencia es: { 1  3  5  6  8  10 }
5  Programación / Programación C/C++ / Re: Modificar busqueda binaria en: 2 Junio 2022, 06:12 am
Si tenes como premisa que el dato de entrada es un numero que se encuentra en el arreglo, que creo que es este el caso que planteaste, seria asi

Código:
hacer mientras (bajo <= alto)
    centro = (bajo + alto) / 2
    si (clave = array[centro])
        hacer mientras (centro < size)
            si (clave < array[centro])
                devolver centro
            centro = centro + 1
        Repetir
        devolver -1
    o si (clave < array[centro])
        alto = centro
    sino
        bajo = centro + 1
repetir

La primera solucion de Serapis devuelve el indice donde esta la clave y no el siguiente mayor.

Ésta, -si fuese correcta, que depende de los valores iniciales de alto y bajo- no es efficiente como la búsqueda binaria, sino que degrada a busqueda lineal O(n)...
Imagina un millon de 1´s y la ultima posición es 2...
Código:
11111.....112
Entonces, el programa itera 500.000 veces, o sea O(N/2) = O(N).
La que yo expuse, iteraría como mucho 20 (<= log_2 10^6)
6  Programación / Programación C/C++ / Re: Modificar busqueda binaria en: 2 Junio 2022, 05:37 am
 ;-) ;-) ;-) ;-) Gracias jca1!

1000 veces lo hubiera visto y 1000 veces no me habría dado cuenta del error tipográfico.

Corrijo en el original , poniendo EDIT y dando crédito.
7  Programación / Programación C/C++ / Re: Modificar busqueda binaria en: 1 Junio 2022, 21:51 pm
Te paso la original y una variación que devuelve el indice del primer número mayor y en caso contrario devuelve el tamaño del vector size . (Esto es más natural que -1..)

Tu ya lo cambias si quieres.

Código
  1. #include <iostream>
  2.  
  3. int binary_search(const int V[], const int N, const int elem);
  4. int binary_search2(const int V[], const int N, const int elem);
  5.  
  6. #define size 15
  7.  
  8. int main(){
  9.  
  10. int numero;
  11. int array[size] = {0, 1, 1, 2, 3, 5, 8, 13, 13, 21, 34, 55, 89, 144, 144};
  12.  
  13. std::cout << "Buscar numero: ";
  14. std::cin >> numero;
  15.  
  16. const int index = binary_search2(array, size,numero);
  17. if (index == size)
  18. std::cout << "No hay elemento mayor a " << numero << std::endl;
  19. else
  20. std::cout << "Array[" << index << "] = " << array[index] << std::endl;
  21.  
  22. return 0;
  23. }
  24.  
  25.  
  26. #define h ((i+j)/2)
  27.  
  28. /* P: N >= 1, V sorted , elem in V*/
  29. /* original */
  30. int binary_search(const int V[], const int N, const int elem)
  31. {
  32.    int i,j;
  33.    i=0;
  34.    j=N;
  35.    while (V[h]!= elem)
  36.        if (V[h]>elem) j=h;
  37.        else i=h+1;
  38.    return h;
  39. }
  40.  
  41. /* P: N >= 1, V sorted , elem in V*/
  42. /* Variation */
  43. int binary_search2(const int V[], const int N, const int elem)
  44. {
  45.    int i,j;
  46.    i=0;
  47.    j=N;
  48. // I : 0<= i < j <= N and V[i] <= V[elem] <= V[j-1]
  49.    while (V[h]!= elem || (h<N-1 && V[h]==V[h+1]))  // <= B: Changes.
  50.        if (V[h]>elem) j=h;
  51.        else i=h+1;
  52.    return h+1; // V[h] points to element.
  53. }
  54.  

EDIT: La linea
Código:
   while (V[h]!= elem || (h<N-1 && V[h]==V[h+1]))  // <= B: Changes.
tenía un error tipográfico. (Crédito: jca1)

La salida da

Código:
Buscar numero: 8
Array[7] = 13

Código:
Buscar numero: 144
No hay elemento mayor a 144

No quiero abrumar con formalismos. Fijate especialmente en:
  • la precondicion P: el array ordenado y el numero que pases tiene que existir
  • la parada B: A la derecha de h hay uno mayor,  o esta en ultima posicion

Un saludo.
8  Programación / Programación C/C++ / Re: Frustracion en: 25 Junio 2021, 21:21 pm
Aqui te va una propuesta de conteo de palabras con recursion...

(No es pa tanta frustración... Más se perdio en Cuba, que decía mi abuelo... ::) :D     )

Decir que es imprescindible llevar control de la primera posición de la linea - si queremos admitir lineas vacias - y del resultado provisional.

 

Código
  1.  
  2. #include <ctype.h>
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5.  
  6.  
  7. // Immersion:
  8. // ac = #i : 0 <= i < n : V[i]='nb' and (i>0 -> V[i-1]='b')
  9. // (s act as index n, in C-ish style)
  10. // 0 <= n <= len(p)
  11. int num_wordG(const char *p,const char *s, int ac)
  12. {
  13.  if (*s)
  14.    if (isspace(*s)) return num_wordG(p,++s,ac); // Rec.
  15.    else return num_wordG(p,s+1,ac+(p==s || isspace(*(s-1)))); // Rec.
  16.  return ac; // Basis case.
  17. }
  18.  
  19.  
  20. int main(int argc, char *args[])
  21. {
  22.  char *line = NULL;
  23.  size_t len = 0 ;
  24.  ssize_t nread;
  25.  for ( ; (nread = getline(&line, &len, stdin)) != -1; )
  26.    {
  27.      line[nread-1]=0; // chop the \n
  28.      printf("%s -> %i\n",line,num_wordG(line,line,0));
  29.    }
  30.  free(line);
  31.  return 0;
  32. }
  33.  
  34.  
  35.  
  36.  

Algunos casos de prueba...

Código:
En un lugar de la Mancha
En un lugar de la Mancha -> 6
son 3 palabras
son 3 palabras -> 3
una
una -> 1

 -> 0

9  Programación / Programación C/C++ / Re: Semaforos en c en: 25 Junio 2021, 17:48 pm
¿¿¿??? Pues eso es lo que puse en mi mensaje:


Tienes Razon, RayR... Acabe cansado de implementarlo y no lei del todo tu respuesta.
10  Programación / Programación C/C++ / Re: Semaforos en c en: 25 Junio 2021, 10:22 am
... A cada hilo le podrías enviar como parámetro entero su número de índice. Cada hilo "n" espera por el semáforo n, e incrementa (sem_post) el semáforo n + 1, a excepción del último (2), que incrementará el primero (0).
El planteamiento es correcto. Pero es importante resaltar el valor inicial de los semáforos. Todos a 0, menos el primero, a 1.

Aqui va una implementación.

Código
  1. #include <pthread.h>
  2. #include <stdlib.h>
  3. #include <stdio.h>
  4. #include <semaphore.h>
  5. #include <unistd.h> // sleep thread.
  6. #include <string.h> // memcopy
  7.  
  8. static const char values[3]={'A','B','C'};
  9. static sem_t semaphore[3];
  10. static pthread_t thread[3];
  11.  
  12. static void *routine(void *arg);
  13.  
  14. int main(int argc, char *args[])
  15. {
  16.    for (int i = 0; i < 3; i++)
  17. if (sem_init(&(semaphore[i]), 0, (i==0)?1:0))
  18.    {
  19. perror("sem_init");
  20. exit(-1);
  21.    }
  22.    for (int i = 0; i < 3; i++)
  23. {
  24.    int *local_idx;
  25.    if ((local_idx= (int *)malloc(sizeof(int)))==NULL)
  26. {
  27.    perror("malloc");
  28.    exit(-1);
  29. }
  30.    *local_idx=i;
  31.    if  (pthread_create(&thread[i], NULL, routine, local_idx))
  32.     {
  33.        perror("pthread_create");
  34.        exit(-1);
  35.     }
  36. }
  37.    for (int i = 0; i < 3; i++)
  38.      if (pthread_join(thread[i], NULL))
  39. {
  40.  perror("pthread_join");
  41.  exit(-1);
  42. }
  43. }
  44.  
  45. static void *routine(void *arg)
  46. {
  47.    int local_id;
  48.    memcpy(&local_id,arg,sizeof(int));
  49.    free(arg);
  50.    for( ; 1 ; )
  51. {
  52.    if (sem_wait(&semaphore[local_id]))
  53. {
  54.    perror("sem_wait");
  55.    exit(-1);
  56. }
  57.    printf("%c",values[local_id]);
  58.    //sleep(1);
  59.    if (sem_post(&semaphore[(local_id+1)%3]))
  60. {
  61.    perror("sem_post");
  62.    exit(-1);
  63. }
  64. }
  65. }
  66.  
  67.  

Ejemplo de salida
Código:
ABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABC...
Páginas: [1] 2 3 4 5 6 7 8 9 10 11
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines