Преобразование Infix в Postfix с переменными и функциями из math.h (чтобы определить символьный интеграл позже) - PullRequest
1 голос
/ 28 декабря 2011

Ну, привет всем.

Этот код доставил мне много трудностей.Не знал, как это сделать и т. Д. Наконец, у меня появилась идея, как преобразовать его в постфиксную нотацию (RPN).

Это мой код, но он дает мне много ошибок, любую помощь ».Буду признателен;>

#include <math.h>
#include <conio.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define math_length 14
#define FOUND 1
#define NOT_FOUND 2


typedef char* string;


string read();
string transform(string infix);
char zmienna;
string math[math_length]={"cos", "sin", "tan", "acos", "asin", "atan", "cosh", "sinh", "tanh", "exp", "log", "pow", "sqrt"};
char mathsingle[math_length]={"ABCDEFGHIJKLM"};
int *i=0;

int main (int argc, char *argv)
{
string infix, postfix;
infix=read();

if(argc>1)
    zmienna=argv[1];
else zmienna='x';


postfix=transform(infix);


printf("Oto wynik:%s",postfix);
getch();
free(infix);
return 0;    
}

string read()
{

int licznik=0;
int znak;
string tab, bufor;


bufor=(char*) malloc (sizeof(char));
if (bufor==NULL)
    exit(EXIT_FAILURE);

do
    {
    znak=getchar();

    if (znak!=10)
        {
        licznik++;
        tab=(string) realloc(bufor,licznik);
        if (tab!=NULL)
            {
            bufor=tab;
            bufor[licznik-1]=znak;
            }       
        else
            {
            free(bufor);
            puts ("Blad (re)alokacji pamieci");
            exit (EXIT_FAILURE);
            }
        }
    }
while (znak!=10);
licznik++;
tab=(string) realloc(bufor,licznik);
if (tab!=NULL)
    {
    bufor=tab;
    bufor[licznik-1]='\0';
    }       
return bufor;
}
string transform(string infix)
{
    int c=0;
    string *stos, postfix;
    char func[5];
    int detective=0,liczba_stosow=0;

    stos[liczba_stosow] = (string) malloc (strlen(infix));
    if (stos[liczba_stosow]==NULL)
        exit (EXIT_FAILURE);
    postfix = (string) malloc (strlen(infix));
    if (postfix==NULL)
        exit (EXIT_FAILURE);
    int **b = 0;

    int j=0;

    b = (int**) malloc (sizeof(int)*liczba_stosow);
    b[liczba_stosow] = (int*) malloc (sizeof(int)*strlen(infix));
    if (b[liczba_stosow]==NULL) exit (EXIT_FAILURE);
    *(b[liczba_stosow])=0;

    while(infix[*i]!='\0')
    {
//----------------------------------------------------------------------------CYFRY I ZMIENNA----------------------------------------------------------------------------------------------------------------
        if(infix[*i]<58 && infix[*i]>47 && infix[*i]==zmienna)
        {
            //WYJŚCIE
            postfix[j]=infix[*i];
            *i++;
            j++;
        }
//----------------------------------------------------------------------------LITERY-------------------------------------------------------------------------------------------------------------------------
        else if(infix[*i]>96 && infix[*i]<123)
        {
            //POBIERA AŻ DO NAWIASU, POTEM SZUKA STRINGA W math POPRZEZ strcmp. PO NAWIASIE ODSYŁA DO INNEJ FUNKCJI KTÓRA TRANSFORMUJE TEN KAWAŁEK
            while((infix[*i]!='(') || (c!=6)) //pobiera do (
            {
                func[c]=infix[*i];
                c++;
                *i++;
            }
            if (c==6)
                exit(EXIT_FAILURE); //jak ktoś nie umie pisać i podana funkcja będzie dłuższa niż te dozwolone, to zamiast przekraczać zakres, program wywala error
            for(c=0; c<math_length; c++) //szuka stringa
                if(strcmp(func,math[c])==0)
                {
                    detective=FOUND;

                    break;  
                }
                else detective=NOT_FOUND;
            if (detective==NOT_FOUND) //jeśli szukało a nie znalazło to dupa->wywala error
                exit(EXIT_FAILURE);




        }
//--------------------------------------------------------------------------OPERATORY-------------------------------------------------------------------------------------------------------------------------
        else if(infix[*i] == ('+' || '-' || '*' || '/' || '^'))
        {
            //3 PRZYPADKI, KAŻDY PO 2 ODDZIELNE PODPKTY, STOS ALBO WYJŚCIE
            if(*(b[liczba_stosow])==0)
            {
                stos[liczba_stosow][*(b[liczba_stosow])]=infix[*i];
                *(b[liczba_stosow])++;
                i++;
            }
            else
                switch (stos[liczba_stosow][*(b[liczba_stosow])-1])
                {
                case '+':
                case '-':
                    stos[liczba_stosow][*(b[liczba_stosow])]=infix[*i];
                    *(b[liczba_stosow])++;
                    *i++;
                    break;
                case '*':
                case '/':
                    if(infix[*i]==('/' || '^'))
                    {
                        stos[liczba_stosow][*(b[liczba_stosow])]=infix[*i];
                        *(b[liczba_stosow])++;
                        i++;
                    }
                    else
                    {
                        postfix[j]=stos[liczba_stosow][*(b[liczba_stosow])-1];
                        j++;
                        stos[liczba_stosow][*(b[liczba_stosow])-1]=infix[*i];
                        i++;
                    }
                    break;
                default: //zostaje tylko ^
                    if(infix[*i]=='^')
                    {
                        stos[liczba_stosow][*(b[liczba_stosow])]=infix[*i];
                        *(b[liczba_stosow])++;
                        i++;
                    }
                    else
                    {
                        postfix[j]=stos[liczba_stosow][*(b[liczba_stosow])-1];
                        j++;
                        stos[liczba_stosow][*(b[liczba_stosow])-1]=infix[*i];
                        i++;
                    }
                    break;
                }
        }
//---------------------------------------------------------------------------------NAWIAS L------------------------------------------------------------------------------------------------------------------
        else if(infix[*i]=='(')
        {
        liczba_stosow++;
        *i++;
        stos[liczba_stosow] = (string) malloc (strlen(infix));
        if (stos[liczba_stosow]==NULL) exit (EXIT_FAILURE);

        b[liczba_stosow] = (int*) malloc (sizeof(int)*strlen(infix));
        if (b[liczba_stosow]==NULL) exit (EXIT_FAILURE);

        stos[liczba_stosow]=NULL;
        b[liczba_stosow]=0;
        }
//---------------------------------------------------------------------------------NAWIAS P------------------------------------------------------------------------------------------------------------------
        else if(infix[*i]==')')
        {
            for(c=*(b[liczba_stosow]); c>0; c--)
            {               
                postfix[j]=stos[liczba_stosow][c];
                j++;
            }
            *i++;
            free(stos[liczba_stosow]);
            free(b[liczba_stosow]);
            liczba_stosow--;

            if(detective==FOUND)
            {
            postfix[j]=mathsingle[c];  //dodaje na koniec wielką literę odpowiadającą funkcji

            for(c=0; c<5; c++)      //czyści tablicę dla przyszłych pokoleń
                func[c]=0;
            c=0;
            detective=0;
            j++;
        }
//-----------------------------------------------------------------------------NIEZNANY ZNAK-----------------------------------------------------------------------------------------------------------------
        else exit(EXIT_FAILURE);
    }

//-----------------------------------------------------------------------------KONIEC TRANSFORMACJI----------------------------------------------------------------------------------------------------------





    //LICZY POCHODNA Z POST FIXA
}
    return postfix;
}

Пожалуйста, не обращайте внимания на комментарии, так как они на польском языке.

Я работаю над Visual Studio 2010 Ultimate.Вот ошибки, которые я получаю:

синтаксическая ошибка: отсутствует ';'before 'type'

'b': необъявленный идентификатор (получить их с помощью 'b' и 'j')

для нижнего индекса требуется массив или указатель типа

'free':слишком мало аргументов для вызова

Кстати, пожалуйста, не издевайтесь надо мной слишком сильно, я просто начинаю свое приключение с программирования.

1 Ответ

1 голос
/ 28 декабря 2011

Переместите объявления переменных b и j в начало функции transform(). Изменения:

string transform(string infix)
{
    int c=0;
    string *stos, postfix;
    char func[5];
    int detective=0,liczba_stosow=0;

    stos[liczba_stosow] = (string) malloc (strlen(infix));
    if (stos[liczba_stosow]==NULL)
        exit (EXIT_FAILURE);
    postfix = (string) malloc (strlen(infix));
    if (postfix==NULL)
        exit (EXIT_FAILURE);
    int **b = 0;

    int j=0;

    ...
}

до:

string transform(string infix)
{
    int c=0;
    string *stos, postfix;
    char func[5];
    int detective=0,liczba_stosow=0;
    int **b = 0;
    int j=0;

    stos[liczba_stosow] = (string) malloc (strlen(infix));
    if (stos[liczba_stosow]==NULL)
        exit (EXIT_FAILURE);
    postfix = (string) malloc (strlen(infix));
    if (postfix==NULL)
        exit (EXIT_FAILURE);

    ...
}

Стандарт C99 допускает:

смешанные объявления и код: объявление переменной больше не ограничено областью действия файла или началом составного оператора (блока)

, но компиляторы VC не поддерживают C99 (см. здесь ).

EDIT: Обратите внимание, что еще одна проблема с кодом - использование неинициализированной переменной stos в функции transform().

...