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

 

 


Tema destacado: Guía rápida para descarga de herramientas gratuitas de seguridad y desinfección


+  Foro de elhacker.net
|-+  Programación
| |-+  Programación C/C++ (Moderadores: Eternal Idol, Littlehorse, K-YreX)
| | |-+  Ayuda
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] 2 Ir Abajo Respuesta Imprimir
Autor Tema: Ayuda  (Leído 5,907 veces)
agustinp99

Desconectado Desconectado

Mensajes: 6


Ver Perfil
Ayuda
« en: 10 Octubre 2019, 15:01 pm »

Hola buen dia, tengo una duda con un ejercicio que me dieron. Tengo que armar una calculadora de polaca inversa y estoy tratando de, a partir de la ecuación brindada por el usuario, tomar el primer numero, el segundo, luego el signo y asi sucesivamente. El problema es que no logro hacerlo, ya que no encuentro alguna funcion o algo que me detecte si el caracter es un numero o un signo (ya que si es un espacio lo salteo con un if antes). Si alguien puede tirarme algun consejo se lo agradeceria!


En línea

agustinp99

Desconectado Desconectado

Mensajes: 6


Ver Perfil
Re: Ayuda
« Respuesta #1 en: 10 Octubre 2019, 15:01 pm »

Esto es en codigo C


En línea

K-YreX
Moderador
***
Desconectado Desconectado

Mensajes: 1.008



Ver Perfil
Re: Ayuda
« Respuesta #2 en: 10 Octubre 2019, 15:09 pm »

En vez de poner dos mensajes seguidos es mejor que modifiques el primero e incluyas lo que necesites.

Para lo que quieres hacer tienes una librería que es <ctype.h> en la que tienes funciones como <isdigit()>, <isspace()>, <ispunct()>, <isgraph()>, etc. Vamos, para saber qué tipo de carácter tienes.
Te dejo un enlace donde aparecen las funciones que tienes y una tabla para que veas qué caracteres se consideran de puntuación y cuáles se consideran graficables, etc.
http://www.cplusplus.com/reference/cctype/?kw=cctype
En línea

Código
  1. cout << "Todos tenemos un defecto, un error en nuestro código" << endl;
agustinp99

Desconectado Desconectado

Mensajes: 6


Ver Perfil
Re: Ayuda
« Respuesta #3 en: 10 Octubre 2019, 15:16 pm »

Uh perfecto, ahora averiguo bien. Muchisimas gracias
En línea

agustinp99

Desconectado Desconectado

Mensajes: 6


Ver Perfil
Re: Ayuda
« Respuesta #4 en: 10 Octubre 2019, 15:29 pm »

En vez de poner dos mensajes seguidos es mejor que modifiques el primero e incluyas lo que necesites.

Para lo que quieres hacer tienes una librería que es <ctype.h> en la que tienes funciones como <isdigit()>, <isspace()>, <ispunct()>, <isgraph()>, etc. Vamos, para saber qué tipo de carácter tienes.
Te dejo un enlace donde aparecen las funciones que tienes y una tabla para que veas qué caracteres se consideran de puntuación y cuáles se consideran graficables, etc.
http://www.cplusplus.com/reference/cctype/?kw=cctype
Tengo otra duda, porque yo tengo que ingresar la ecuacion en notacion polaca al programa. Como puedo hacer para ir guardando el primer numero, el segundo y su signo? He visto que lo hacian con pilas pero mi profesor me dijo que lo trate de hacer de otra forma pero no me sale una idea

ESTO ES LO QUE VENIA PENSANDO

#include <stdio.h>
#include <string.h>
#include <ctype.h>
int main()
{
   char c[100];
   char str[10];
   int i;
   int u;
   printf ("Ingrese notacion polaca inversa: ");
   scanf ("%s",c);
      for (i=0;i<= strlen(c);i++){
         if (isdigit(c) && c!= " "){
         str=c;
         u++;
         }   
   }
   printf ("El numero guardado es %s", str);
   }
« Última modificación: 10 Octubre 2019, 15:31 pm por agustinp99 » En línea

K-YreX
Moderador
***
Desconectado Desconectado

Mensajes: 1.008



Ver Perfil
Re: Ayuda
« Respuesta #5 en: 11 Octubre 2019, 01:33 am »

No está mal aunque hay que pulir un par de cosas:
Antes de nada, los códigos ponlos entre etiquetas de Código GeSHi porque sino los índices no se ven y la i entre corchetes se convierte en cursiva y la u entre corchetes, en subrayado...
  • Para pedir una cadena al usuario no se usa <scanf()>, se usa <fgets()>
Código
  1. #define SIZE 100 // definimos un maximo de longitud para la cadena. Esto se pone justo despues de las librerias
  2. char cadena[SIZE];
  3. printf("Introduce una cadena: ");
  4. fgets(cadena, SIZE, stdin);
El siguiente problema es que al introducir una cadena y pulsar ENTER, el ENTER también se guardará en la cadena. Esto lo arreglamos rápido así:
Código
  1. cadena[strlen(cadena)-1] = '\0';
  • La segunda condición de tu bucle <while()> es innecesaria. Preguntas si <c> es un dígito Y si no es un espacio... Siempre que se cumpla que es un dígito, se cumplirá también que no es un espacio. Y si no es un dígito, la segunda condición dará igual.

Si lo que quieres conseguir es el resultado de calcular la expresión en notación polaca inversa, te falta esa parte.
En línea

Código
  1. cout << "Todos tenemos un defecto, un error en nuestro código" << endl;
dijsktra

Desconectado Desconectado

Mensajes: 110


Mr Edsger Dijsktra (Tribute to)


Ver Perfil
Re: Ayuda
« Respuesta #6 en: 11 Octubre 2019, 15:37 pm »

Tengo otra duda, porque yo tengo que ingresar la ecuacion en notacion polaca al programa. Como puedo hacer para ir guardando el primer numero, el segundo y su signo? He visto que lo hacian con pilas pero mi profesor me dijo que lo trate de hacer de otra forma pero no me sale una idea


Las pilas por debajo están simuladas con vectores... O sea, que expones los vectores que se ocultarían en la implementación de una pila normalemente...

EDITO
En esta versión implemento un analizador de notación polaca inversa.
Esto es, primero los operandos y después el operador. Como en (3 4 -)


Código
  1. /*
  2.  
  3. An stack can be simulated by a vector
  4.  
  5. +-----+
  6. |     |
  7. +-----+ N
  8. |  2  |
  9. +-----+
  10. |  1  |
  11. +-----+
  12. |  +  |
  13. +-----+ 0
  14.  
  15.  
  16. */
  17. #include <stdlib.h>
  18. #include <stdio.h>
  19. #include <assert.h>
  20. #include <string.h>
  21.  
  22. #define MAX 100000
  23. #define DEBUG
  24.  
  25. int polish (const char V[][25], const int N)
  26. {
  27.  int n,top;
  28.  int S[MAX];
  29.  for( n=top=0;n<N;n++)
  30.  {
  31. #ifdef DEBUG
  32.    int i;
  33.    for(  i=n ; i < N ; i++) printf("%s ",V[i]);
  34.    printf("\n\n");
  35. #endif
  36.  
  37.    if (strtol(V[n],NULL,10))
  38.      S[top++]=atoi(V[n]);
  39.    else
  40.      {
  41. assert(top>1);
  42. const int a = S[--top];
  43. const int b = S[--top];
  44. if (!strcmp(V[n],"+"))
  45.  S[top++] = a + b;
  46. else if (!strcmp(V[n],"-"))
  47.  S[top++] = a - b;
  48. else if (!strcmp(V[n],"*"))
  49.  S[top++] = a * b;
  50. else if (!strcmp(V[n],"/"))
  51.       {
  52. assert(!b);
  53. S[top++] = a / b;
  54.       }
  55.      }
  56. #ifdef DEBUG
  57.    for(  i=0 ; i < top-1 ; i++) printf("%d ",S[i]);
  58.    printf("%d\n\n",S[top-1]);
  59. #endif
  60.  };
  61.  assert(top==1);
  62.  return S[--top];
  63. }
  64.  
  65.  
  66. int main(int argc, char* args[])
  67. {
  68.  char V[MAX][25];
  69.  
  70.  int N;
  71.  for(N=0;scanf("%s",V[N])==1 && strcmp(V[N],"\n");N++);
  72.  printf("%d\n",polish(V,N));
  73.  return 0;
  74.  
  75. }

Y un ejemplo de ejecuci'on. Para la expresi'on en notaci'on polaca
Código:
3 4 + 7 * 9 10 5 6 + * - - 

En la ejecución se da la evoluición de la cadena de entrada y del estado de la pila...
Código:
3 4 + 7 * 9 10 5 6 + * - - 

3

4 + 7 * 9 10 5 6 + * - -

3 4

+ 7 * 9 10 5 6 + * - -

7

7 * 9 10 5 6 + * - -

7 7

* 9 10 5 6 + * - -

49

9 10 5 6 + * - -

49 9

10 5 6 + * - -

49 9 10

5 6 + * - -

49 9 10 5

6 + * - -

49 9 10 5 6

+ * - -

49 9 10 11

* - -

49 9 110

- -

49 101

-

52




« Última modificación: 13 Octubre 2019, 17:58 pm por dijsktra » En línea

Si la depuración es el proceso de eliminar fallos en el software, entonces programar debe ser el proceso de ponerlos dentro. (Edsger Dijsktra)
agustinp99

Desconectado Desconectado

Mensajes: 6


Ver Perfil
Re: Ayuda
« Respuesta #7 en: 11 Octubre 2019, 17:05 pm »

Las pilas por debajo están simuladas con vectores... O sea, que expones los vectores que se ocultarían en la implementación de una pila normalemente...

¡Atención ! mi solución entiende que notación polaca es   + 3 4 , en lugar de 3 + 4 o 3 4 +.
(Solo hay que cambiar el orden de lectura de los operandos)

 El programa solo evalua una expresion polaca metida correctamente... y sin parantesis...

no se puede + 3 (4+4) , sino que hay que escribir + 3 4 4 +

REPITO, no se si es lo que buscas...

Código
  1. /*
  2.  
  3. An stack can be simulated by a vector
  4.  
  5. +-----+
  6. |     |
  7. +-----+ N
  8. |  2  |
  9. +-----+
  10. |  1  |
  11. +-----+
  12. |  +  |
  13. +-----+ 0
  14.  
  15.  
  16. */
  17.  
  18.  
  19. #include <cstdlib>
  20. #include <iostream>
  21. #include <cassert>
  22. #include <cstring>
  23.  
  24. using namespace std;
  25. int polish(char S[][25],  int N)
  26. {
  27.  for(N; N > 1 ; )
  28.    {
  29.      const int b = atoi(S[--N]);
  30.      const int a = atoi(S[--N]);
  31.      const char op = *S[--N];
  32.      cout << b << " " << a <<  " " << op << endl;
  33.      switch (op) {
  34.      case '+': sprintf(S[N++],"%d",a+b);
  35. break;
  36.      case '-': sprintf(S[N++],"%d",a-b);
  37. break;
  38.      case '*': sprintf(S[N++],"%d",a*b);
  39. break;
  40.      case '/':
  41. assert(b!=0);
  42. sprintf(S[N++],"%d",a/b);
  43. break;
  44.      }
  45.    }
  46.  return atoi(S[N-1]);
  47. }
  48.  
  49.  
  50.  
  51. #define MAX 100000
  52. int main(int argc, char* args[])
  53. {
  54.  char S[MAX][25];
  55.  int top ;
  56.  for(top=0;scanf("%s",S[top])==1 && strcmp(S[top],"\n");top++ );
  57.  printf("%d\n",polish(S,top));
  58.  return 0;
  59. }

Y un ejemplo de ejecuci'on.

Para la expresi'on en notaci'on polaca
Código:
- 15 + 1 * 2 + 3 4

el programa da
Código:
4 3 +
7 2 *
14 1 +
15 15 -
0


Hola!! Si me sirve un monton, te hago una pregunta nomas, que hace el args en el main? porque yo uso el argv pero nose si es lo mismo

Ademas de que no entiendo que hace el for de esa forma
« Última modificación: 11 Octubre 2019, 17:08 pm por agustinp99 » En línea

agustinp99

Desconectado Desconectado

Mensajes: 6


Ver Perfil
Re: Ayuda
« Respuesta #8 en: 11 Octubre 2019, 19:33 pm »

No está mal aunque hay que pulir un par de cosas:
Antes de nada, los códigos ponlos entre etiquetas de Código GeSHi porque sino los índices no se ven y la i entre corchetes se convierte en cursiva y la u entre corchetes, en subrayado...
  • Para pedir una cadena al usuario no se usa <scanf()>, se usa <fgets()>
Código
  1. #define SIZE 100 // definimos un maximo de longitud para la cadena. Esto se pone justo despues de las librerias
  2. char cadena[SIZE];
  3. printf("Introduce una cadena: ");
  4. fgets(cadena, SIZE, stdin);
El siguiente problema es que al introducir una cadena y pulsar ENTER, el ENTER también se guardará en la cadena. Esto lo arreglamos rápido así:
Código
  1. cadena[strlen(cadena)-1] = '\0';
  • La segunda condición de tu bucle <while()> es innecesaria. Preguntas si <c> es un dígito Y si no es un espacio... Siempre que se cumpla que es un dígito, se cumplirá también que no es un espacio. Y si no es un dígito, la segunda condición dará igual.

Si lo que quieres conseguir es el resultado de calcular la expresión en notación polaca inversa, te falta esa parte.
Voy entendiendo, el problema es que sigo sin poder guardar lo numeros en alguna variable, ya que hago un for que vaya desde 1 hasta el argc y lo que quiero hacer ahora es preguntar si el argv es un digito(que eso sé como se hace) y luego, a partir de ese numero guardarlo en una variable entera, por ejemplo x. Al hacer esta iteracion con la condicion, si yo tengo mas de dos numeros ya la variable x tomaria solamente el ultimo y no se como hacer para poder guardar todo en distintas variables
En línea

K-YreX
Moderador
***
Desconectado Desconectado

Mensajes: 1.008



Ver Perfil
Re: Ayuda
« Respuesta #9 en: 11 Octubre 2019, 23:37 pm »

La función <main()> puede recibir dos parámetros: un <int> y un <char*[]>. El primero indica el número de parámetros que le pasas al programa cuando lo ejecutas desde línea de comandos y el segundo es como una matriz donde cada fila es uno de los parámetros y cada columna es una letra. El nombre que le des da igual, siempre es lo mismo.

Como te han dicho, una pila internamente se puede implementar con un <array>. Entonces lo que tienes que hacer es un <array> de números en donde guardar los números hasta encontrar un operador. Yo estoy hablando para una notación polaca inversa, es decir, 3 4 +.
Te dejo el siguiente pseudocódigo. Esto es para que lo entiendas. Cuando entiendas cómo funciona tienes que pasarlo a C ya que el pseudocódigo no está escrito en C.
Código:
INICIO
    posicionActual := 0
    PEDIR expresion
    PARA i := 0 HASTA expresion.longitud - 1 HACER
        SEGUN expresion[i] HACER
            numero:
                numeros[posicionActual++] = expresion[i]
            +:
                numeros[posicionActual - 2] := numeros[posicionActual - 2] + numeros[posicionActual - 1]
                posicionActual := posicionActual - 2
            *:
                numeros[posicionActual - 2] := numeros[posicionActual - 2] + numeros[posicionActual - 1]
                posicionActual := posicionActual - 2

            //...igual para el resto de operadores

        FIN SEGUN
    FIN PARA

    MOSTRAR numeros[0]
FIN
En línea

Código
  1. cout << "Todos tenemos un defecto, un error en nuestro código" << endl;
Páginas: [1] 2 Ir Arriba Respuesta Imprimir 

Ir a:  

WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines