Título: Dividir polinomio en monomios C++ Publicado por: gomezjuan en 18 Mayo 2020, 13:39 pm Necesito hacer un programa que dado un polinomio lo guarde en un string, lo divida en monomios y se asegure de que la estructura es correcta y devuelva error si no tiene esa estructura.
La estructura que debe tener el monomio es: ``` 1. Signo + o - 2. COEFICIENTE: uno o mas dígitos enteros (0,...,9) 3. x 4. signo ^ 5. EXPONENTE: uno o mas dígitos enteros (0,...,9) ``` He pensado en dividir el polinomio en monomios cada vez que lea un signo y guardarlo en un vector, pero no se como asegurarme de que cumple la estructura: Tengo: Código
Por consola imprime: Código: +3x^2 Título: Re: Dividir polinomio en monomios C++ Publicado por: K-YreX en 18 Mayo 2020, 17:05 pm La estructura que debe tener el monomio es: ``` 1. Signo + o - 2. COEFICIENTE: uno o mas dígitos enteros (0,...,9) 3. x 4. signo ^ 5. EXPONENTE: uno o mas dígitos enteros (0,...,9) ``` Esta estructura que dices que debe cumplirse no se cumple. Casos:
De todas maneras, una vez que ya lo tienes separado en monomios, te digo cómo puedes validar cada uno de estos. Mi recomendación es que crees una clase Monomio con coeficiente y exponente. Así podrás manejar los datos fácilmente y no desperdigarlos. Una idea del algoritmo sería: Código: validarMonomio(string) : Monomio // Funcion que recibe un string (monomio) y devuelve un objeto de tipo Monomio Es un poco largo pero no lo podía probar así que he ido separando y explicando cada posible situación para procurar no dejarme nada. Ahora pásalo a C++ y si te da algún problema, coméntalo. Suerte. PD: Además puede darse que tengas varios monomios del mismo grado (como en tu ejemplo: -4 y +1). Una vez separados todos, deberías comprobarlo y juntarlos. Título: Re: Dividir polinomio en monomios C++ Publicado por: gomezjuan en 18 Mayo 2020, 18:05 pm Muchas gracias, no entiendo muy bien a que te refieres con la primera linea la de validar monomio.
La estructura del monomio seria así? Código: struct monomio { Título: Re: Dividir polinomio en monomios C++ Publicado por: gomezjuan en 18 Mayo 2020, 18:58 pm He eliminado lo del signo ^ y ahora despues de la x tendria que ir un numero directamente o nada si el exponente es 1.
Código: #include <string> Título: Re: Dividir polinomio en monomios C++ Publicado por: Serapis en 18 Mayo 2020, 19:08 pm Se te está pidiendo un reconocedor de lenguaje, un autómata.
Tienes que empezar por definir correctamente el problema. La mejor manera es hacerlo en BNF... valor = [signo] numero [variable] expresion = monomio|numero [operador expresion] // uno y/o más numeros o monomios monomio = [signo] numero [potencia] potencia = opPotencia numero signo = "+"|"-" // un signo también es un operador como se verá más abajo. numero = digito numero // uno o más dítitos. digito = "0"|"1"|"2"|"3"|"4"|"5"|"6"|"7"|"8"|"9" operador = "+"|"-"|"*"|"/" // Se puede añadir los operadores que se quiera. opPotencia = "^" variable = "a"|"b"|"c"| ... |"x"|"y"|"z" // OJO: Variable es una sola letra minúscula (deducido a partir de la expresión de ejemplo) Desde ahí se puede pasar ya a codificarlo, pero se requiere cierta experiencia para poder hacerlo clara y eficientemente... para aprender es mejor interponer el propio autómata sus estados, así que es ése el pseudocódigo que te pongdré más abajo... Ahora se trata de generar una tabla con los estados de transición conforme a las reglas previas: Una tabla de estados es un cuadro donde se colocan todas las variables en juego (pueden agruparse caso de 0-9, a-z cuando para ellos se dan idénticas condiciones sin excepción), esto es, el estado actual, los estados previos y se rellena con el estado de transición. En vertical el token actualmente siendo leído, en horizontal el token previo (no hay problema en intercambiarlo, siempre que quede claro). La tabla recoge a que estado avanza desde el token previo al token actual... previo| signo | 0-9 | a-z | separador | operador | potencia | ---------------------------------------------------------------- actual|--------------------------------------------------------- ---------------------------------------------------------------- signo | 6? | 1 | 5 | - | 2 | e | ---------------------------------------------------------------- 0-9 | 6 | 1 | e | - | 2 | 1 | ---------------------------------------------------------------- a-z | 6 | 5 | e | - | 2 | e | ---------------------------------------------------------------- sepa. | x | x | x | - | x | e | ---------------------------------------------------------------- oper. | e | 1 | 2 | - | e | e | ---------------------------------------------------------------- opPow | e | e | 7 | - | e | e | ---------------------------------------------------------------- otros | e | e | e | - | e | e | ---------------------------------------------------------------- La tabla de estados se lee como sigue: - Un valor 'e' significa un estado de error. Si se da debe abortarse y darse por fallida la validación de la expresión. - Un valor 'x' significa que es un estado superfluo, no se hace nada (debe ignorarse, esto supone devolver a token su valor previo) y seguir leyendo. - Un valor '-' significa que dicho estado no se dará, porque cuando sucedió, es transitorio en el mismo ciclo al estado previo. - Un valor '6?' significa un estado 6, pero que debe hacerse una comprobación posterior (in situ). - El resto de valores indican el estado al que se cambia, desde el token actual y sabiendo el token previo. El estado final de la validación debe ser 1 ó 5. Estos valores señalan que se ha validado correctamente, si al llegar al final de la expresión se tiene un estado 2 ó 6, la expresión hasta ese momento es correcta, pero incompleta, por tanto se da como errónea. Como hablamos de tokens... conviene crear una enumeración y un array que 'tokenice' cada carácter en nuestro 'lenguaje' Antes de nada, pues, establecemos valores para reconocerlos. Código: enumeracion TipoToken Inicialmente el 'estado previo' debe ponerse en 1. Se empieza recorriendo carácter a carácter en un bucle... se obtiene un token y debe considerarse el estado previo, para asignar el estado conforme a la tabla de estados, decrita más arriba. Código: // NOTA: considera un 'break;' con cada caso... (tramitándolo como 'C'). p.d.: Intercambiado valores en token= signo y previo= digito con el opuesto token= digito y previo= signo. Reasignando otros valores de estado, se puede dejar más claro... 0 = desconocido, 1 = separador, 2 = operador, 3 = signo, 4 = digito, 5 = variable Prevtoken conviene que se establezca inicialmente siempre al estado asignado a 'digito', para que pase a un estado válido si el primer carácter lo es. NOTA: Al ver que luego has puesto otra expresión he recalado en la previa y he visto que no me percaté de que usas expresiones algebraicas... El pseudocódigo como estaba resolvía acertadamente las expresiones aritméticas, pero no las algebraicas... como esa que pusiste al inicio: "+3x^2-2x^1+9x^5-4+5x^3+1". Es solo añadir alguna regla más y un estado distinto para el operador de potencia y luego añadir en la función 'ParseExpresion', los casos para dicho nuevo estado. Hago los cambios para que quede correctamente. También resolverá correctamente un término suelto como 3x^0+5 si se pone como 3x+5 Título: Re: Dividir polinomio en monomios C++ Publicado por: K-YreX en 18 Mayo 2020, 22:01 pm Muchas gracias, no entiendo muy bien a que te refieres con la primera linea la de validar monomio. La primera línea era solo para definir una función llamada validarMonomio() que recibe como parámetro un string y devuelve un Monomio. El prototipo de la función sería:La estructura del monomio seria así? Código: struct monomio { Código
Para usar la struct Monomio: Código
También puedes crear constructores, gets()/sets(),... Incluso crear una class para hacer los atributos privados y manejar los objetos a partir de los métodos. |