Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > IT форум > Помощь студентам
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 22.04.2015, 08:30   #1
mith
 
Регистрация: 18.10.2014
Сообщений: 4
Лампочка Дополнить калькулятор на Обратной польской записи

Здравствуйте.
Сделал калькулятор на ОПЗ.
Теперь задача дополнить его так, чтоб можно было вносить вещественные числа и числа с унарным минусом.
Допустим унарный минус я заменю другим символом(#).
Но как реализовать?
Про вещественные вообще не понятно...(Их можно реализовать однозначными, например "2.3")
Помогите пожалуйста.
Вот весь код:
Код:
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
 
typedef struct node
{
    char el;
    struct node *next;
} Stack;
typedef struct node1
{
    double el;
    struct node1 *next;
}Stackdl;
 
Stack* Head=NULL;
Stackdl* Headl=NULL;
 
void Push(char element)
{
    Stack *p;
    p = (Stack*)malloc(sizeof(Stack));
    if(p!=NULL)
    {
        p->el=element;
        p->next=Head;
        Head=p;
printf("Push elem %c \n",element);
 
    }
    else
    {
        puts("Error! Not free memory!");
    }
}
 
char Pop()
{
    char a=Head->el;
    Stack* p=Head;
    Head=Head->next;
    free(p);
printf("Pop elem %c \n", a);
    return a;
}
 
void Pushdl(double element)
{
    Stackdl *p;
    p = (Stackdl*)malloc(sizeof(Stackdl));
    if(p!=NULL)
    {
        p->el=element;
        p->next=Headl;
        Headl=p;
printf("Push elem(dl) %.2lf \n",element);
 
    }
    else
    {
        puts("Error! Not free memory!");
    }
}
 
double Popdl()
{
    double a=Headl->el;
    Stackdl* p=Headl;
    Headl=Headl->next;
    free(p);
printf("Pop elem(dl) %.2lf \n", a);
    return a;
}
 
int IsOperation(char ch)
{
    if(ch=='+' || ch=='-' || ch=='*' || ch=='/')
        return 1;
    return 0;
}
 
int Prior(char oper)
{
    if(oper=='+' ||oper=='-' )
        return 1;
    if(oper=='*' ||oper=='/')
        return 2;
    return 0;
}
 
double calculate(char postfix[])
{
double a=0,b=0,rez=0;
int ind=0;
    for(;postfix[ind]!=NULL;ind++)
    {
        switch(postfix[ind])
        {
        case '+':b=Popdl();a=Popdl();
            rez=a+b; Pushdl(rez);break;
        case '-':b=Popdl();a=Popdl();
            rez=a-b; Pushdl(rez);break;
        case '*':b=Popdl();a=Popdl();
            rez=a*b; Pushdl(rez);break;
        case '/':b=Popdl();a=Popdl();
            rez=a/b; Pushdl(rez);break;
        default:
            rez = postfix[ind]-'0';
            Pushdl(rez);break;
        }
    }
 
    return rez;
}
 
 
 
void main()
{
double rezult;
char infix[100],postfix[100],q;
int i=0,j=0,len;
clrscr();
gets(infix);
Push('(');
len=strlen(infix);
infix[len]=')';
infix[len+1]='\0';
while(Head!= NULL)
{
    for(;infix[i]!= '\0';i++)
    {
        if(infix[i]=='(')
                Push('(');
        else
             if(infix[i]==')')
             {
                 for(;(q=Pop())!= '(';j++)
                     postfix[j]=q;
             }
 
             else if(IsOperation(infix[i]))
             {
                 do{
                     q=Pop();
                     if(Prior(q)>=Prior(infix[i]))
                     {
                        postfix[j]=q;
                        j++;
                    }
                     else{
                         Push(q);
                         break;
                        }
                 }while(1);
 
                Push(infix[i]);
             }
             else
             {
                 postfix[j]=infix[i];
                 j++;
             }
        }
}
 
postfix[j]='\0';
puts(postfix);
rezult=calculate(postfix);
printf("rezult = %.2lf\n",rezult);
getch();
return;
}

Последний раз редактировалось Аватар; 22.04.2015 в 09:31.
mith вне форума Ответить с цитированием
Старый 22.04.2015, 09:49   #2
evg_m
Старожил
 
Регистрация: 20.04.2008
Сообщений: 5,526
По умолчанию

а кто вам сказал что ВСЕ числа и ВСЕ операции являются ОДНОсимвольными.
Основным понятием является ИДЕНТФИКАТОР (непрерывная последовательность символов ограниченная пробелами/переходами строк/и далее по вкусу)
Среди идентификаторов можно выделить идентификаторы операций ( + sin tg ....) и идентификаторы числа ( pi e ... 3.14 -100 )

1. Выделить идентификатор (собрать его в отдельную строку !!)
2. передать полученный идентификатор конвертору (infix to postfix )
3. если не конец строки перейти к п.1
4. выполнить вычисления в OПЗ.
программа — запись алгоритма на языке понятном транслятору
evg_m вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Сделать подсчёт обратной польской записи Вечеслав Qt и кроссплатформенное программирование С/С++ 0 29.06.2013 17:27
Логическая ошибка "Обратной польской записи" Fanyuus Общие вопросы C/C++ 10 22.05.2013 18:50
Вопросы по обратной польской записи АлексВ Паскаль, Turbo Pascal, PascalABC.NET 8 01.06.2012 11:29
[Visual C++] Калькулятор с обратной польской нотацией WhiteKuz Visual C++ 0 22.03.2012 00:13
преобразования польской формы записи уравнения Безбашик Общие вопросы по Java, Java SE, Kotlin 6 12.05.2009 10:25