Форум программистов, компьютерный форум CyberForum.ru

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
Levondk
0 / 0 / 0
Регистрация: 22.10.2012
Сообщений: 11
#1

Высчитать значение выражения с приоритетами - C++

03.03.2013, 02:45. Просмотров 701. Ответов 11
Метки нет (Все метки)

Дана строка символов, представляющих собой арифметическое
выражение, содержащее только знаки +,-,*,/,(,) и строчные буквы
английского алфавита. Требуется подсчитать результат выражения.
Вход
Первая строка входа содержит число n ≤ 26 количество параметров,
входящих в арифметическое выражение. Следующие n строк содержат
значение каждого параметра в формате t=x, где t название параметра
(строчная буква английского алфавита), а x из себя представляет
обыкновенную дробь. Следующая строка входа содержит выражение, без
пробелов. Гарантируется, что заданное выражение корректно.
Выход
Выведите результат операции в виде несократимой дроби. Если
знаменатель равен 1, выведите только числитель.
Вот само задание..
Я написал функции для +, -, / и *, но никак не пойму, как нужно составить саму int main (), чтобы программа считала значение выражения по приоритетам, т.е. сперва то, что в скобках, дальше * и /, а дальше уже + и -..

Если не трудно, на основе моей программы помогите дописать или допишите int main ()

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
#include <iostream>
#include <cmath>
using namespace std;
struct frac
{
    int p;
    int q;
};
int gcd ( int a, int b )
{
    if ( a == 0)
        return b;
    return gcd( b%a, a );
}
void krchatel ( frac& a)
{
    int g = gcd ( abs ( a.p ), abs ( a.q ) );
    a.p /= g;
    a.q /= g;
}
frac operator +( const frac& a, const frac& b )
{
    frac c;
    c.p = a.p * b.q + a.q * b.p;
    c.q = a.q * b.q;
    krchatel (c);
    return c;
}
frac operator -( const frac& a, frac& b )
{
    b.p = -b.p;
    return a+b;
}
frac operator *( const frac& a, const frac& b )
{
    frac c;
    c.p = a.p * b.p;
    c.q = a.q * b.q;
    krchatel (c);
    return c;
}
frac operator /( const frac& a, frac& b )
{
    swap( b.p , b.q );
    return a * b;
}
istream& operator >> ( istream& in, frac& f )
{
    char c;
    in >> f.p >> c >> f.q;
    return in;
}
ostream& operator << ( ostream& out, const frac& f )
{
    out << f.p;
if ( f.q != 1 )
    out << "/" << f.q;
return out;
}
int main ()
{
Добавлено через 50 минут
Простите, что АПаю, очень нужна ваша помощь.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
03.03.2013, 02:45     Высчитать значение выражения с приоритетами
Посмотрите здесь:

Вычислить значение выражения C++
Значение выражения C++
Построить класс для работы с очередью с приоритетами C++
C++ Функция добавления и увеличения элемента из очереди с приоритетами
C++ Написать программу, которая вычисляет значение выражения, и определить ее значение для введенных пользователем значений фактических параметров.
C++ Как высчитать факториал?
C++ Многофайловый проект: высчитать значение заданной функции с определенным интервалом
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
NEbO
587 / 455 / 49
Регистрация: 22.01.2009
Сообщений: 1,180
Записей в блоге: 1
Завершенные тесты: 1
03.03.2013, 03:52     Высчитать значение выражения с приоритетами #2
Цитата Сообщение от Levondk Посмотреть сообщение
Дана строка символов, представляющих собой арифметическое
выражение, содержащее только знаки +,-,*,/,(,) и строчные буквы
английского алфавита. Требуется подсчитать результат выражения.
дальше не читал, извините. смотрите в сторону lex/bison. и вообще, их принципов. (если такое название как "книга дракона" вам знакомо, замечательно. если нет, не читайте дальше).
Код
/* Infix notation calculator--calc */

%token NUM
%left '-' '+'
%left '*' '/'
%left NEG
%right '^' /* возведение в степень */

%%

input:    /* пустое выражение */
        | input line
;

line:     '\n'
        | exp '\n'  { echo $1, "\n"; }
;

exp:      NUM                { $$ = $1;         }
        | exp '+' exp        { $$ = $1 + $3;    }
        | exp '-' exp        { $$ = $1 - $3;    }
        | exp '*' exp        { $$ = $1 * $3;    }
        | exp '/' exp        { $$ = $1 / $3;    }
        | '-' exp  %prec NEG { $$ = -$2;        }
        | exp '^' exp        { $$ = pow ($1, $3); }
        | '(' exp ')'        { $$ = $2;         }
;
%%
это простой подсчет выражения (это пример из бизона) для учета скобок, чисел, плюсов, минусов, умножений, делений и минусов перед числами (разумеется, последнее можно реализовать в лексере). Нетрудно догадаться, что парсер написан для пхп, заменив echo на printf можно сделать для сей и плюсов.
Меня бы не смутило ваше сообщение, сам писал мини-компилятор паскаля по курсовой работе. Однако переменные тут вообще ни к чему. прочитал собщение. я дурак, вообще не то написал, но для общего сведения не стану удалять все что было выше.

вообщем, в вашем случае, фактически уже почти составлено дерево синтаксического разбора, как я понимаю (без приоритетов, тупо списком). ну так читайте каждый токен и ищите тот, что с минимальным приоритетом (priority('+') < priority(*), к примеру). это делается через цикл по всем токенам (for (int i = 0 n = tokens.count(); i < n; i++) потом вызывайте рекурсию слева и справа, и там все то же самое будет.
Levondk
0 / 0 / 0
Регистрация: 22.10.2012
Сообщений: 11
03.03.2013, 13:04  [ТС]     Высчитать значение выражения с приоритетами #3
Цитата Сообщение от NEbO Посмотреть сообщение
вообщем, в вашем случае, фактически уже почти составлено дерево синтаксического разбора, как я понимаю (без приоритетов, тупо списком). ну так читайте каждый токен и ищите тот, что с минимальным приоритетом (priority('+') < priority(*), к примеру). это делается через цикл по всем токенам (for (int i = 0 n = tokens.count(); i < n; i++) потом вызывайте рекурсию слева и справа, и там все то же самое будет.
Спасибо, конечно. Но с токенами дел не имел и с данным типом приоритетов тоже. Тему создавал в "для начинающихс ++" , так что всего этого я не знаю..
TakeOver
41 / 31 / 1
Регистрация: 03.02.2013
Сообщений: 61
03.03.2013, 20:21     Высчитать значение выражения с приоритетами #4
гуглите про Обратную Польскую Нотацию.
в википедии очень хорошо расписан алгоритм. да и сам алгоритм очень простой.
после построения ОПН просто делается вычисления на стеке.
у меня когда-то все это вышло в 100-150 строк.
сейчас этого кода, увы нет, ибо я на его основе сделал недоскриптовый язык -)
а если идти флексом и бизоном - то там будет пара тысяч строк, сгенерированного -)
я бы посоветовал ANTLR, его дебажить проще, да и кодогенерация шире.

и да. в коде алгоритм НОДа неверный, надо брать остатки не только слева, но и справа.
Levondk
0 / 0 / 0
Регистрация: 22.10.2012
Сообщений: 11
03.03.2013, 21:27  [ТС]     Высчитать значение выражения с приоритетами #5
TakeOver, Этот алгоритм я вчера изучал, но как его реализовать - вообще без понятия. Именно поэтому я задал вопрос тут, чтобв с кодом помогли) а я уж разобрался, что к чему.

Добавлено через 3 минуты
Цитата Сообщение от TakeOver Посмотреть сообщение
алгоритм НОДа неверный
верный, проверял сам в своих других задачах, нормально работает.
TakeOver
41 / 31 / 1
Регистрация: 03.02.2013
Сообщений: 61
03.03.2013, 21:45     Высчитать значение выражения с приоритетами #6
Цитата Сообщение от Levondk Посмотреть сообщение
TakeOver, Этот алгоритм я вчера изучал, но как его реализовать - вообще без понятия. Именно поэтому я задал вопрос тут, чтобв с кодом помогли) а я уж разобрался, что к чему.

Добавлено через 3 минуты

верный, проверял сам в своих других задачах, нормально работает.
да. верный, не заметил, что а и b меняются местами на каждом этапе рекурсии, но можно было в 2 раза сэкономит ьпамять.
а алгоритм из википедии - "влоб". там все прозрачно написано =)
главное, разве что, сделать лексер входного потока, то есть разбить на токены - число/переменная/знак операции, что тоже легко делается
Levondk
0 / 0 / 0
Регистрация: 22.10.2012
Сообщений: 11
03.03.2013, 21:55  [ТС]     Высчитать значение выражения с приоритетами #7
TakeOver,
выше писал, что не знаю понятия "токен" и на это времени нет) Пока основываясь на написанные мною функции пишу еще пару задачек, а тут, надеюсь, кто-то сможет готовым кодом помочь)
TakeOver
41 / 31 / 1
Регистрация: 03.02.2013
Сообщений: 61
04.03.2013, 00:49     Высчитать значение выражения с приоритетами #8
Цитата Сообщение от Levondk Посмотреть сообщение
TakeOver,
выше писал, что не знаю понятия "токен" и на это времени нет) Пока основываясь на написанные мною функции пишу еще пару задачек, а тут, надеюсь, кто-то сможет готовым кодом помочь)
токен - последовательности символов в лексическом анализе в информатике, соответствующий лексеме.
то есть, либо число, либо знак операции, либо функция и тд.
могу сбросить код своего парсера, который от нечего-делать недавно писал, выкинете все лишнее. + могу код алгоритма Дейкстры скинуть(не тот, что на графы, а тот что инфиксную нотацию в постфиксную преобразует). а интерпритацию ОПН и сами сможете =) (тупо 5-10 условий и 2-3 строки на каждое условие)
если нужно будет - завтра скину.
Levondk
0 / 0 / 0
Регистрация: 22.10.2012
Сообщений: 11
04.03.2013, 00:52  [ТС]     Высчитать значение выражения с приоритетами #9
TakeOver, Ок..давайте попробуем. Завтра скиньте, попробую что-нибудь выудить..
kamre
126 / 130 / 4
Регистрация: 25.12.2011
Сообщений: 443
04.03.2013, 02:33     Высчитать значение выражения с приоритетами #10
Как вариант (с использование boost::rational, но можно его на свой тип заменить):
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
#include <boost/rational.hpp>
 
#include <fstream>
#include <sstream>
#include <string>
 
using namespace std;
 
typedef boost::rational<int> rational_t;
typedef const char* iter_t;
 
rational_t vars[26];
 
bool is_var(char c)
{
    return ('a' <= c) && (c <= 'z');
}
 
struct error {}; // throw in case of errors
 
void print_error(const string &s, iter_t iter)
{
    int consumed = iter - s.c_str();
    cerr << s << endl << string(consumed, ' ') << '^' << endl;
}
 
rational_t expr(iter_t &iter);
rational_t term(iter_t &iter);
rational_t factor(iter_t &iter);
 
bool eval(const string &s, rational_t &value)
{
    iter_t iter = s.c_str();
    try {
        value = expr(iter);
        if (*iter) {
            // not all consumed!
            print_error(s, iter);
            return false;
        }
    } catch (error &e) {
        print_error(s, iter);
        return false;
    }
    return true;
}
 
rational_t expr(iter_t &iter)
{
    if (!*iter)
        throw error();
    rational_t res = term(iter);
    while (*iter == '+' || *iter == '-') {
        bool plus = (*iter++ == '+');
        rational_t r = term(iter);
        if (plus)
            res += r;
        else
            res -= r;
    }
    return res;
}
 
rational_t term(iter_t &iter)
{
    if (!*iter)
        throw error();
    rational_t res = factor(iter);
    while (*iter == '*' || *iter == '/') {
        bool mult = (*iter++ == '*');
        rational_t r = factor(iter);
        if (mult)
            res *= r;
        else
            res /= r;
    }
    return res;
}
 
rational_t factor(iter_t &iter)
{
    if (!is_var(*iter) && *iter != '(')
        throw error();
    if (is_var(*iter))
        return vars[*iter++ - 'a'];
    rational_t r = expr(++iter);
    if (*iter != ')')
        throw error();
    ++iter;
    return r;
}
 
int main()
{
    const char* fname = "input.txt";
    ifstream inp(fname);
    if (!inp) {
        cerr << "Can't open input file " << fname << "!" << endl;
        return 1;
    }
    int n;
    inp >> n;
    if (!inp) {
        cerr << "Not a number on first line!";
        return 1;
    }
    inp.ignore(numeric_limits<std::streamsize>::max(), '\n');
    for (int i = 0; i < n; ++i) {
        string s;
        getline(inp, s);
        char v = s[0];
        if (!is_var(v) || s[1] != '=') {
            cerr << "wrong assignment in line \"" << s << "\", skipped!" << endl;
            continue;
        }
        if (s.find('/') == string::npos)
            s += "/1";
        istringstream iss(s.substr(2));
        iss >> vars[v - 'a'];
    }
    string expr;
    getline(inp, expr);
    rational_t value;
    if (eval(expr, value)) {
        cout << expr << "=";
        if (value.denominator() == 1)
            cout << value.numerator();
        else
            cout << value;
        cout << endl;
    } else {
        cerr << "wrong expression!" << endl;
    }
}
Цитата Сообщение от input.txt
4
a=1/3
b=5/3
x=15
z=10/3
(a+b)*x/z
(a+b)*x/z=9
TakeOver
41 / 31 / 1
Регистрация: 03.02.2013
Сообщений: 61
10.03.2013, 16:06     Высчитать значение выражения с приоритетами #11
уу, совсем забыл, что обещал =(
на олимпиаду ездил, только приехал. вот исходник калькулятора нашел
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
#include <iostream>
#include<vector>
#include<stdio.h>
#include <string>
#include<math.h>
#include<stack>
using namespace std;
#define MODIFER "%LG"
#define tod(x) strtod(x,NULL)
vector<string> args;//ОПН выражение для интерпритации
vector<string>stck;//временный стэк операторов
vector<string> inp;//вектор входных данных после препроцессоинга
inline int prior(const char c){
  switch(c){
    case '#': case '^':case '$'://#- корень, ^ -степень, $ - квадратный корень
      return 3;
    case '*': case '/':
      return 2;
    case '+': case '-':
      return 1;
  }
  return 0;
}
inline int sign(const long double a){
  return a>0?1:-1;
}
inline bool is_num(const char c){
  return ((c>='0'&&c<='9') || c=='.');//нет защиты от дурака, если больше 1 точки в числе.
}
inline bool is_oper(const char c){
  return prior(c);//логично, что если с - не оп-р то его приоритет =0
}
int main(){
  char c;
 
  //препроцессоинг входных данных
  while (scanf("%c",&c)!=EOF&& c!='='){
    if (c=='\n' || c==' ' || c=='\r' || c=='t')//для решения задачи это не нужно, но при дебагге пригодилось
      continue;
    //"извлекаем" числовые константы из данных
    if (is_num(c)){
      char t[1026];
      t[0]=c;
      long i=0;
      while (scanf("%c",&c)!=EOF && is_num(c)){//до тех пор пока в input'e есть цифры - читаем их
    t[++i]=c;
      }
      t[++i]='\0';//большн костылей больших и разных
      inp.push_back((const char *)t);
    }
    if (cin.eof() || c=='=')
      break;//больше костылей больших и разных
    if (c=='\n' || c==' ' || c=='\r' || c=='t')
      continue;
    //преобразуем квадратный корень
    if (c=='#' &&( inp.empty() || (!inp.empty() && (inp.back()[0]=='(' || prior(inp.back()[0])) ))){
//       inp.push_back("2");
//       inp.push_back("#");
    inp.push_back("$"); //пусть это будет знаком квадратного корня
    } else{
      //делаем вычетание из минуса, если дана отрицательная числовая константа
      if (c=='-' && (inp.empty() || inp.back()[0]=='(')){
    inp.push_back("0");
      }
      //заносим оператор.
      char t[2]; t[0]=c; t[1]='\0';
      inp.push_back((const char *)t);
    }
  }
#ifdef debug
  cout<<"infix notation after tokenizing:\n";
#endif
  //преобразование инфиксной записи в постфиксную ОПН через алгоритм Дейкстры
  for (auto &x:inp){
#ifdef debug
      cout<<x<<' ';
#endif
    if (is_num(x[0])){
      args.push_back(x);//тк нашел число, то помещаю его в конец выходного ОПН выражения
    } else if (x=="("){//помещение откр. скобки в стэк. потом уберется
      stck.push_back(x);
    } else if (x==")"){//нет защиты от дурака. если не будет найдена откр. скобка - значит в выражении ошибка
      while(stck.back()!="("){//перебрасываю все операторы из стэка в ОПН выражение, за искл. откр. скобки
    args.push_back(stck.back());
    stck.pop_back();
      }
      stck.pop_back();//скобка
    } else {//послий вариант - Х - оператор. пока приоритет оператора на вершине стэка выше Х - перебрасываю
//операторы из стэка в ОПН. заносу Х в стэк //в зависимости от ассоциативности. левая - меньше-равно, правая
//строго меньше
      while (!stck.empty() && is_oper(stck.back()[0]) && ((prior(stck.back()[0])>prior(x[0]) && x[0]=='$' )|| (prior(stck.back()[0])>=prior(x[0]) && x[0]!='$'))){//единственный право-ассоциативный оп-р - $.
    args.push_back(stck.back());
    stck.pop_back();
      }
      stck.push_back(x);
    }
  }//лексемы закончились. перебрасываю все ооператоры оставшиеся в стэка в ОПН
  while (!stck.empty()){
    args.push_back(stck.back());
    stck.pop_back();
  }
#ifdef debug
  cout<<"\nReverse Polish notation:\n";
  for(auto &x:args){
    cout<<x<<' ';
  }
  cout<<endl;
#endif
  //Интерпритация ОПН выражений, основанная на стэке.
stack<long double> top;//стэк чисел.
top.push(0);//на всякий случай занесу 0. хотя 99.997645677% что это лишнее
#define pop_to_reg(); \
a=top.top(); top.pop();\
b=top.top(); top.pop();
//tod - макрос strtod(x,NULL) преобразование в double
for(auto x=args.begin();x!=args.end();x++){
  if (is_num((*x)[0])){
    top.push(tod(x->c_str()));
  } else {
    register long double a,b; //полурегистры временных значений с вершин стэка.
    switch((*x)[0]){//взятие двух вернихних значений стэка - и помещение рез. операции на вершину стэка.
      case '+':
    pop_to_reg();
    top.push(a+b);
    break;
      case '-':
    pop_to_reg();
    top.push(b-a);
    break;
      case '*':
    pop_to_reg();
    top.push(a*b);
    break;
      case '/':
    pop_to_reg();
    top.push(b/a);
    break;
      case '$'://пришлось разделить корень по основанию и квадратный корень из-за левоассоциативности первого
    a=top.top(); top.pop();
    top.push(sqrt(a));
    break;
      case '#':
    pop_to_reg();
    //pow из math.h почему-то не берет нечетный корень из отриц. числа.
    //функция sign возвращает -1/1 в зависимости от знака числа. fabs - модуль числа.
    //корень = 1/(значение степени корня)
    //проверок за отриц. A и четное B не делается.
    top.push(sign(a)*pow(fabs(a),1.0/b));
    break;
      case '^':
    pop_to_reg();
    top.push(pow(b,a));
    break;
    }
  }
}
//ответ выражения лежит на вершине стэка.
#ifdef debug
  printf("Result=");
#endif
  printf(MODIFER,top.top());
  return 0;
}
правда, без переменных, если еще нужно, то могу скинуть полотно говнокода с переменными и с условиями и циклами(но не вложенными)
говнокод еще тот. писал тогда, когда только начал кресты изучать=)
проверок на ошибки - нет. можно добавить разве что проверку на скобки
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
16.03.2013, 02:15     Высчитать значение выражения с приоритетами
Еще ссылки по теме:

Очередь с приоритетами C++
Очередь с приоритетами C++
Сумма массива с приоритетами C++
C++ Ошибка в очереди с приоритетами
C++ Вычислите значение выражения. Значение х вводится с клавиатуры

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
Levondk
0 / 0 / 0
Регистрация: 22.10.2012
Сообщений: 11
16.03.2013, 02:15  [ТС]     Высчитать значение выражения с приоритетами #12
У вас реально все сложно написано)
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
#include <iostream>
#include <string>
using namespace std;
 
int work(int a, int b, char op)
{
    if (op == '+')
        return a + b;
    if (op == '-')
        return a - b;
    if (op == '*')
        return a * b;
    if (op == '/')
        return a / b;
}
 
int main ()
{
    string s;
    cin >> s;
    s = "(" + s + ")"; 
    char b[100];
    int g = 0;
    int a[100];
    int d = 0;
    for ( int i = 0 ; i < s.size(); i++ )
        {
            if ( s[i] == '+' )
            {
                b[g] = s[i];
                g++;
            }
            if ( s[i] == '-' )
            {
                b[g] = s[i];
                g++;
            }
            if ( s[i] == '/' )
            {
                b[g] = s[i];
                    g++;
            }
            if ( s[i] == '*' )
            {
                b[g] = s[i];
                    g++;
            }
            if ( s[i] == '(' )
            {
                b[g] = s[i];
                    g++;
            }
 
            if (s[i] == ')')
            {
                while (b[g-1] != '(')
                {
                    a[d-2] = work(a[d - 2], a[d-1], b[g-1]);
                    d--;
                    g--;
                }
            }
 
            if ( s[i] >= '0' && s[i] <= '9')
            {
                if (g > 0 && b[g - 1] == '*')
                {
                    a[d - 1] = a[d - 1] * (s[i] - '0');
                    g--;
                } else
                if (g > 0 && b[g - 1] == '/')
                {
                    a[d - 1] = a[d - 1] / (s[i] - '0');
                    g--;
                } else
                {
                    a[d] = s[i] - '0';
                    d++;
                }
            }
        }
    cout << a[0];
}
Вот это я написал для чисел от 0-9 (это чтобы легче было в чар писать). Если кто может допилить или помочь мне самому допилить, то заранее спасибо. Нужно переделать программу для дробей. Т.е. вот мои операторы для дробей. Нужно, чтобы эта программа заработала для любых дробей)

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
struct frac
{
    int p;
    int q;
};
int gcd ( int a, int b )
{
    if ( a == 0)
        return b;
    return gcd( b%a, a );
}
void krchatel ( frac& a)
{
    int g = gcd ( abs ( a.p ), abs ( a.q ) );
    a.p /= g;
    a.q /= g;
}
frac operator +( const frac& a, const frac& b )
{
    frac c;
    c.p = a.p * b.q + a.q * b.p;
    c.q = a.q * b.q;
    krchatel (c);
    return c;
}
frac operator -( const frac& a, frac& b )
{
    b.p = -b.p;
    return a+b;
}
frac operator *( const frac& a, const frac& b )
{
    frac c;
    c.p = a.p * b.p;
    c.q = a.q * b.q;
    krchatel (c);
    return c;
}
frac operator /( const frac& a, frac& b )
{
    swap( b.p , b.q );
    return a * b;
}
istream& operator >> ( istream& in, frac& f )
{
    char c;
    in >> f.p >> c >> f.q;
    return in;
}
ostream& operator << ( ostream& out, const frac& f )
{
    out << f.p;
if ( f.q != 1 )
    out << "/" << f.q;
return out;
}
Когда начинаю заменять int-ы на frac, то возникают проблемы даже со счетчиками в цикле for, поэтому и не смог сам допилить программу..
Yandex
Объявления
16.03.2013, 02:15     Высчитать значение выражения с приоритетами
Ответ Создать тему
Опции темы

Текущее время: 19:56. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru