File indexing completed on 2024-04-21 03:41:50
0001 /* 0002 Task.cpp - source code of class Task 0003 SPDX-FileCopyrightText: 2001 Sebastian Stein <seb.kde@hpfsc.de> 0004 SPDX-FileCopyrightText: 2008 Tiago Porangaba <tiago.porangaba@ltia.fc.unesp.br> 0005 SPDX-FileCopyrightText: 2008 Tadeu Araujo <tadeu.araujo@ltia.fc.unesp.br> 0006 SPDX-FileCopyrightText: 2008 Danilo Balzaque <danilo.balzaque@ltia.fc.unesp.br> 0007 0008 SPDX-License-Identifier: GPL-2.0-or-later 0009 */ 0010 0011 #include "Task.h" 0012 0013 #include <cmath> 0014 #include <ctime> 0015 #include <QRandomGenerator> 0016 0017 #include <QDebug> 0018 0019 /** constructor of class task */ 0020 Task::Task() 0021 { 0022 #ifdef DEBUG 0023 qDebug() << "constructor task"; 0024 #endif 0025 } 0026 0027 /** destructor of class task */ 0028 Task::~Task() 0029 { 0030 #ifdef DEBUG 0031 qDebug() << "destructor task"; 0032 #endif 0033 } 0034 0035 /** create a task with random ratios and operations; the generated task 0036 * can be customized by the given parameters: 0037 * pmax_md: maximum main denominator 0038 * pnr_ratios: number of ratios -> pnr_ratios - 1 operations 0039 */ 0040 void Task::create_task(unsigned int pmax_md, short pnr_ratios, 0041 short padd_add, short padd_div, 0042 short padd_mult, short padd_sub) 0043 { 0044 unsigned int max_product_length = 0; 0045 int main_denominator = 1; 0046 0047 do { 0048 /* delete a maybe given task */ 0049 clean(); 0050 0051 /* generate the operations and count the max. mul/div in one block */ 0052 max_product_length = make_operation(padd_add, padd_div, padd_mult, padd_sub, pnr_ratios); 0053 0054 #ifdef DEBUG 0055 qDebug() << "1: max_product_length: " << max_product_length; 0056 #endif 0057 0058 /* later we must be able to find a main denominator; 0059 * so 2 ^ max_product_length couldn't be bigger than the max. denominator */ 0060 } while ((unsigned int) pow(2.0, (double) max_product_length) > pmax_md); 0061 0062 #ifdef DEBUG 0063 qDebug() << "2: max_product_length: " << max_product_length; 0064 #endif 0065 0066 /* find a main denominator */ 0067 main_denominator = make_main_dn(pmax_md, max_product_length); 0068 0069 #ifdef DEBUG 0070 qDebug() << "after make_main_dn()"; 0071 #endif 0072 0073 /* create the ratios' numerators */ 0074 make_numerators(main_denominator, pnr_ratios); 0075 0076 #ifdef DEBUG 0077 qDebug() << "after make_numerators()"; 0078 #endif 0079 0080 /* create the ratios' denominators */ 0081 make_denominators(main_denominator, pmax_md, padd_div, padd_mult); 0082 0083 #ifdef DEBUG 0084 qDebug() << "main deno: " << main_denominator; 0085 qDebug() << "prim fakt: " << prim_fac_vector.size(); 0086 #endif 0087 0088 return; 0089 } 0090 0091 /** set ratio n in the ratio_vector */ 0092 void Task::set_ratio_n(unsigned short number, int numerator, int denominator) 0093 { 0094 /* do not set something outside our vector */ 0095 if (number > ratio_vector.size() - 1) 0096 number = 0; 0097 ratio_vector[number].setNumerator(numerator); // set numerator 0098 ratio_vector[number].setDenominator(denominator); // set denominator 0099 return; 0100 } 0101 0102 /** set ratio n in the ratio_vector */ 0103 void Task::set_ratio_n(unsigned short number, const Ratio &fraction) 0104 { 0105 /* do not set something outside our vector */ 0106 if (number > ratio_vector.size() - 1) 0107 number = 0; 0108 ratio_vector[number].setNumerator(fraction.numerator()); // set numerator 0109 ratio_vector[number].setDenominator(fraction.denominator()); // set denominator 0110 return; 0111 } 0112 0113 /** returns the ratio given by number from the ratio_vector */ 0114 Ratio Task::get_ratio_n(unsigned short number) const 0115 { 0116 /* do not set something outside our vector */ 0117 if (number > ratio_vector.size() - 1) 0118 number = 0; 0119 return ratio_vector[number]; 0120 } 0121 0122 /** set operation given by the number in the op_vector */ 0123 void Task::set_op_n(unsigned short number, short operation) 0124 { 0125 /* do not set something outside our vector */ 0126 if (number > op_vector.size() - 1) 0127 number = 0; 0128 op_vector[number] = operation; 0129 return; 0130 } 0131 0132 /** returns the operation given by number from the op_vector */ 0133 short Task::get_op_n(unsigned short number) const 0134 { 0135 /* do not set something outside our vector */ 0136 if (number > op_vector.size() - 1) 0137 number = 0; 0138 return op_vector[number]; 0139 } 0140 0141 /** add a new ratio at the end of the ratio vector */ 0142 void Task::add_ratio(const Ratio &new_ratio) 0143 { 0144 ratio_vector.push_back(new_ratio); 0145 return; 0146 } 0147 0148 /** add a new ratio at the end of the ratio vector */ 0149 void Task::add_ratio(int numerator, int denominator) 0150 { 0151 Ratio new_ratio(numerator, denominator); 0152 ratio_vector.push_back(new_ratio); 0153 return; 0154 } 0155 0156 /** add a new operation at the end of the operation vector */ 0157 void Task::add_operation(short operation) 0158 { 0159 op_vector.push_back(operation); 0160 return; 0161 } 0162 0163 /** just outputs the whole given task to stdout; for debugging */ 0164 QTextStream & Task::display(QTextStream & str) 0165 { 0166 #ifdef DEBUG 0167 qDebug() << "task::display()"; 0168 #endif 0169 0170 /* this is our pointer on the ratio_vector, set it to the beginning */ 0171 RatioArray::iterator ratio_pointer = ratio_vector.begin(); 0172 0173 /* this is our pointer on the op_vector, set it to the beginning */ 0174 ShortArray::iterator op_pointer = op_vector.begin(); 0175 0176 /* we need this array to look up the fitting chars for the operations */ 0177 const char a[] = "+-*/"; 0178 0179 /* check, if a qSetFieldWidth() was given to the stream */ 0180 int weite = str.fieldWidth(); 0181 int pweite = weite; 0182 str << qSetFieldWidth(0); 0183 0184 /* check, if ratio number and operation number fit together */ 0185 if (ratio_vector.size() != op_vector.size() + 1) { 0186 qDebug() << "Number of ratios and operations do not fit."; 0187 return str; 0188 } 0189 0190 while (pweite-- > 0) 0191 str << " "; 0192 0193 /* display all numerators */ 0194 for (ratio_pointer = ratio_vector.begin(); 0195 ratio_pointer != ratio_vector.end(); ++ratio_pointer) { 0196 str << qSetFieldWidth(5) << ratio_pointer->numerator() << " "; 0197 } 0198 str << QLatin1Char('\n'); 0199 0200 pweite = weite; 0201 while (pweite-- > 0) 0202 str << " "; 0203 0204 /* display all operations */ 0205 for (op_pointer = op_vector.begin(); 0206 op_pointer != op_vector.end(); ++op_pointer) { 0207 str << " ----- " << a[*op_pointer]; 0208 } 0209 str << " ----- = \n"; 0210 0211 pweite = weite; 0212 while (pweite-- > 0) 0213 str << " "; 0214 0215 /* display all denominators */ 0216 for (ratio_pointer = ratio_vector.begin(); 0217 ratio_pointer != ratio_vector.end(); ++ratio_pointer) { 0218 if (ratio_pointer == ratio_vector.end() - 1) 0219 return str << qSetFieldWidth(5) << ratio_pointer->denominator() << " "; 0220 str << qSetFieldWidth(5) << ratio_pointer->denominator() << " "; 0221 } 0222 str.flush(); 0223 return str; 0224 } 0225 0226 /** solves the given task and returns the result as a ratio */ 0227 Ratio Task::solve() 0228 { 0229 Ratio ergebnis(0, 1); /* that is the starting point */ 0230 0231 /* this is our pointer on the ratio_vector, set it to the beginning */ 0232 RatioArray::iterator ratio_pointer = ratio_vector.begin(); 0233 0234 /* add a temp operation at the beginning */ 0235 op_vector.insert(op_vector.begin(), ADD); 0236 0237 /* this is our pointer on the op_vector, set it to the beginning */ 0238 ShortArray::iterator op_pointer = op_vector.begin() + 1; 0239 0240 /* check, if ratio number and operation number fit together */ 0241 if (ratio_vector.size() != op_vector.size()) { 0242 qDebug() << "Number of ratios and operations do not fit."; 0243 return ergebnis; 0244 } 0245 0246 do { 0247 /* we have to decide our next action by the given operation */ 0248 switch (*op_pointer) { 0249 case ADD : 0250 case SUB : 0251 switch (*(op_pointer - 1)) { 0252 /* we only have to add/sub the next ratio */ 0253 case ADD : 0254 ergebnis = ergebnis + *ratio_pointer++; 0255 break; 0256 case SUB : 0257 ergebnis = ergebnis - *ratio_pointer++; 0258 break; 0259 } 0260 break; 0261 case MUL : 0262 case DIV : 0263 switch (*(op_pointer - 1)) { 0264 /* the next ratio is a product, so we have to 0265 * compute this product first and than add/sub it */ 0266 case ADD : 0267 ergebnis = ergebnis + 0268 product(ratio_pointer, op_pointer); 0269 break; 0270 case SUB : 0271 ergebnis = ergebnis - 0272 product(ratio_pointer, op_pointer); 0273 break; 0274 } 0275 break; 0276 } 0277 /* check if we reached the and of the task */ 0278 if (ratio_pointer == ratio_vector.end()) 0279 break; 0280 0281 #ifdef DEBUG 0282 qDebug() << "Schleifenende"; 0283 #endif 0284 0285 } while (++op_pointer != op_vector.end()); 0286 0287 #ifdef DEBUG 0288 qDebug() << "after do while in solve()"; 0289 #endif 0290 0291 /* if the last operation was an add/sub we haven't add/subed it until now */ 0292 --op_pointer; 0293 switch (*op_pointer) { 0294 case ADD : 0295 ergebnis = ergebnis + *ratio_pointer; 0296 break; 0297 case SUB : 0298 ergebnis = ergebnis - *ratio_pointer; 0299 break; 0300 } 0301 0302 /* erase the temp operation */ 0303 op_vector.erase(op_vector.begin()); 0304 0305 /* before we return the result we have to reduce it */ 0306 ergebnis.reduce(); 0307 0308 return ergebnis; /* return the solution */ 0309 } 0310 0311 /* returns the number of ratios in the vector */ 0312 int Task::getNumberOfRatios() const 0313 { 0314 #ifdef DEBUG 0315 qDebug() << "task::getNumberOfRatios()"; 0316 #endif 0317 return ratio_vector.count(); 0318 } 0319 0320 /* returns the number of operations in the vector */ 0321 int Task::getNumberOfOperations() const 0322 { 0323 #ifdef DEBUG 0324 qDebug() << "task::getNumberOfOperations()"; 0325 #endif 0326 return op_vector.count(); 0327 } 0328 0329 /* removes all ratios and operations from the given task */ 0330 void Task::clean() 0331 { 0332 #ifdef DEBUG 0333 qDebug() << "task::clean()"; 0334 #endif 0335 ratio_vector.clear(); 0336 op_vector.clear(); 0337 0338 return; 0339 } 0340 0341 /** this function is called by the solving function to compute a given 0342 * product (or div) and return the solution */ 0343 Ratio Task::product(RatioArray::iterator & ratio_pointer, 0344 ShortArray::iterator & op_pointer) 0345 { 0346 #ifdef DEBUG 0347 qDebug() << "task::product()"; 0348 #endif 0349 /* the function's parameters are pointing to the next ratio; 0350 * to the starting point of the product */ 0351 Ratio product(ratio_pointer->numerator(), ratio_pointer->denominator()); 0352 0353 ++ratio_pointer; 0354 do { 0355 switch (*op_pointer) { 0356 case ADD : 0357 product = product + *ratio_pointer++; 0358 ++op_pointer; 0359 break; 0360 case SUB : 0361 product = product - *ratio_pointer++; 0362 ++op_pointer; 0363 break; 0364 case MUL : 0365 product = product * *ratio_pointer++; 0366 ++op_pointer; 0367 break; 0368 case DIV : 0369 product = product / *ratio_pointer++; 0370 ++op_pointer; 0371 break; 0372 } 0373 } while (op_pointer != op_vector.end()); 0374 0375 /* we get here if the product consists of the whole given task starting 0376 * at the point given by the function's parameters */ 0377 return product; 0378 } 0379 0380 /** generate the operations randomly; return how many mul or div 0381 * are in one block */ 0382 unsigned short Task::make_operation(short padd_add, short padd_div, short padd_mult, short padd_sub, 0383 short pnr_ratios) 0384 { 0385 #ifdef DEBUG 0386 qDebug() << "task::make_operation()"; 0387 #endif 0388 unsigned short max_product_length = 0; 0389 unsigned short operations = 0; 0390 unsigned short counter = 0; 0391 0392 /* this is our pointer on the op_vector, set it to the beginning */ 0393 ShortArray::iterator op_pointer; 0394 0395 /* clear the old operations */ 0396 op_vector.clear(); 0397 0398 /* generate the operations */ 0399 if (padd_add == YES && padd_div == NO && padd_mult == NO && padd_sub == NO) { 0400 for (short counter = 0; counter < pnr_ratios - 1; counter++) 0401 op_vector.push_back(ADD); 0402 } else if (padd_div == YES && padd_add == NO && padd_mult == NO && padd_sub == NO) { 0403 for (short counter = 0; counter < pnr_ratios - 1; counter++) 0404 op_vector.push_back(DIV); 0405 } else if (padd_mult == YES && padd_add == NO && padd_div == NO && padd_sub == NO) { 0406 for (short counter = 0; counter < pnr_ratios - 1; counter++) 0407 op_vector.push_back(MUL); 0408 } else if (padd_sub == YES && padd_add == NO && padd_div == NO && padd_mult == NO) { 0409 for (short counter = 0; counter < pnr_ratios - 1; counter++) 0410 op_vector.push_back(SUB); 0411 } else { 0412 do { 0413 operations = QRandomGenerator::global()->bounded(4); 0414 switch (operations) { 0415 case ADD: 0416 if (padd_add == YES) { 0417 op_vector.push_back(ADD); 0418 counter++; 0419 } 0420 break; 0421 case SUB: 0422 if (padd_sub == YES) { 0423 op_vector.push_back(SUB); 0424 counter++; 0425 } 0426 break; 0427 case DIV: 0428 if (padd_div == YES) { 0429 op_vector.push_back(DIV); 0430 counter++; 0431 } 0432 break; 0433 case MUL: 0434 if (padd_mult == YES) { 0435 op_vector.push_back(MUL); 0436 counter++; 0437 } 0438 break; 0439 } 0440 } while (counter < (pnr_ratios - 1)); 0441 } 0442 0443 if (padd_mult == YES || padd_div == YES) { 0444 short flag_counter = 0; 0445 0446 /* loop through all operations */ 0447 for (op_pointer = op_vector.begin(); 0448 op_pointer != op_vector.end(); ++op_pointer) { 0449 /* look if we got a mul/div or add/sub */ 0450 if (*op_pointer == DIV || *op_pointer == MUL) { 0451 flag_counter++; 0452 } else { 0453 /* we have to decide, if this was the end of a mul/div block or 0454 * just another add/sub */ 0455 if (flag_counter > 0) { 0456 /* it was the end of a mul/div block; lets look if it was 0457 * longer than the blocks before and save it; than restart */ 0458 if (flag_counter > max_product_length) 0459 max_product_length = flag_counter; 0460 flag_counter = 0; 0461 } /* if (flag_counter > 0) */ 0462 } /* if (*op_pointer == DIV || *op_pointer == MUL) */ 0463 } /* for (op_pointer = op_vector.begin(); ...) */ 0464 0465 /* just to correct the things a little bit if the last operation was a 0466 * mul/div as well */ 0467 if (flag_counter > max_product_length) 0468 max_product_length = flag_counter; 0469 max_product_length++; 0470 } else { 0471 /* if (pmul_div == YES) */ 0472 /* a task is given only with add/sub ops; so we want a max. 0473 * of pnr_ratios / 2 + 1 prime factors, but at least */ 0474 max_product_length = (unsigned short)(float(pnr_ratios) / 2) + 1; 0475 if (max_product_length < 2) 0476 max_product_length = 2; 0477 } /* if (pmul_div == YES) */ 0478 0479 return max_product_length; 0480 } 0481 0482 /** find a denominator for the task */ 0483 int Task::make_main_dn(unsigned int pmax_md, unsigned short max_product_length) 0484 { 0485 int denominator; 0486 0487 /* find a main denominator in the given limits by pmax_md and check 0488 * if the main denominator has enough prime factors */ 0489 do { 0490 denominator = QRandomGenerator::global()->bounded(pmax_md) + 1; 0491 } while ((pmax_md < 1) || 0492 (prim_factor_nr(denominator) < max_product_length)); 0493 0494 return denominator; 0495 } 0496 0497 /** returns the count number's prime factors and stores the prime factors 0498 * in the prim_fac_vektor vektor */ 0499 unsigned short Task::prim_factor_nr(int number) 0500 { 0501 unsigned int tmp_number = number; 0502 PrimeNumber primeNumber; 0503 Tprime_factor prim_fac_struct; 0504 0505 /* delete all the prime factors of the old main denominator */ 0506 prim_fac_vector.clear(); 0507 0508 /* test if we can find prime factors */ 0509 for (primeNumber.move_first(); primeNumber.get_current() <= tmp_number;) { 0510 /* if the current selected prime number is a divisor */ 0511 if (tmp_number % primeNumber.get_current() != 0) { 0512 primeNumber.move_forward(); /* no, test next one */ 0513 } else { 0514 /* yes, we found a new prime factor; so first we use the divisor */ 0515 tmp_number = int (tmp_number / primeNumber.get_current()); 0516 0517 /* now we add the prime factor to our prime factor vector */ 0518 prim_fac_struct.factor = primeNumber.get_current(); 0519 prim_fac_struct.flag = UNUSED; 0520 prim_fac_vector.push_back(prim_fac_struct); 0521 } 0522 } 0523 #ifdef DEBUG 0524 PrimeFactorArray::iterator prim_fac_pointer = prim_fac_vector.begin(); 0525 qDebug() << "Primfaktoren von: " << number; 0526 for (prim_fac_pointer = prim_fac_vector.begin(); 0527 prim_fac_pointer != prim_fac_vector.end(); 0528 ++prim_fac_pointer) 0529 qDebug() << (*prim_fac_pointer).factor; 0530 qDebug() << "Anzahl: " << prim_fac_vector.size(); 0531 #endif 0532 0533 return prim_fac_vector.size(); 0534 } 0535 0536 /** set the numerators randomly */ 0537 void Task::make_numerators(int main_denominator, short pnr_ratios) 0538 { 0539 /* I think it is to easy to deal with ratios like 1/1 or 4/4; so 0540 * I limit the maximum of a numerator */ 0541 int max_numerator = int (main_denominator * float(0.7)); 0542 0543 /* add a new ratio to the task and compute the numerator randomly */ 0544 for (short tmpcounter = 0; tmpcounter < pnr_ratios; tmpcounter++) { 0545 (*this).add_ratio(QRandomGenerator::global()->bounded(max_numerator) + 1, 1); 0546 } 0547 return; 0548 } 0549 0550 /** create the ratios' denominators */ 0551 void Task::make_denominators(int main_denominator, short pmax_md, 0552 short padd_div, short padd_mult) 0553 { 0554 /* this is our pointer on the ratio_vector, set it to the beginning */ 0555 RatioArray::iterator ratio_pointer = ratio_vector.begin(); 0556 0557 /* this is our pointer on the op_vector, set it to the beginning */ 0558 ShortArray::iterator op_pointer = op_vector.begin() + 1; 0559 0560 /* this is a pointer on the array with the prime factors of the main 0561 * denominator */ 0562 PrimeFactorArray::iterator prim_fac_pointer; 0563 0564 unsigned short unused_fac = prim_fac_vector.size(); 0565 unsigned short next_fac; 0566 unsigned short tmp_counter; 0567 int tmp_deno; 0568 0569 /* check, if ratio number and operation number fit together */ 0570 if (ratio_vector.size() != op_vector.size() + 1) { 0571 qDebug() << "Number of ratios and operations do not fit."; 0572 return; 0573 } 0574 0575 /* first make all denominators */ 0576 for (ratio_pointer = ratio_vector.begin(); 0577 ratio_pointer != ratio_vector.end(); ++ratio_pointer) { 0578 do { 0579 tmp_deno = QRandomGenerator::global()->bounded(pmax_md) + 1; 0580 } while (main_denominator % tmp_deno != 0); 0581 (*ratio_pointer).setDenominator(tmp_deno); 0582 } 0583 0584 /* if the ratio is connected to a mul or div operation, we have to do some 0585 * extra work and regenerate the denominators */ 0586 if (padd_mult == YES || padd_div == YES) { 0587 /* lets loop through all ratios and check, if there is a mul/div 0588 * after the ratio */ 0589 ratio_pointer = ratio_vector.begin(); 0590 op_pointer = op_vector.begin(); 0591 do { 0592 if (*op_pointer == MUL || *op_pointer == DIV) { 0593 /* yes, there is a mul/div after the ratio; 0594 * reset the prime number structure */ 0595 for (prim_fac_pointer = prim_fac_vector.begin(); 0596 prim_fac_pointer != prim_fac_vector.end(); 0597 ++prim_fac_pointer) 0598 (*prim_fac_pointer).flag = UNUSED; 0599 0600 /* how many prime factors are available? */ 0601 unused_fac = prim_fac_vector.size() - 1; 0602 0603 /* now loop through this mul/div section until we find a add/sub */ 0604 do { 0605 /* the prim_fac_vector is sorted, but we do not want the 0606 * factors in this sorted way as our denominators; 0607 * so we choose one randomly */ 0608 next_fac = QRandomGenerator::global()->bounded(unused_fac); 0609 tmp_counter = 0; 0610 0611 /* check the prime factors, if they are unused */ 0612 for (prim_fac_pointer = prim_fac_vector.begin(); 0613 prim_fac_pointer != prim_fac_vector.end(); 0614 ++prim_fac_pointer) { 0615 if ((*prim_fac_pointer).flag == UNUSED) { 0616 tmp_counter++; /* we found a unused factor */ 0617 } 0618 /* we found the factor, which we have chosen randomly */ 0619 if (tmp_counter > next_fac) 0620 break; 0621 } 0622 /* mark the factor as used, so we can not use it again in 0623 * this mul/div section */ 0624 (*prim_fac_pointer).flag = USED; 0625 0626 /* store the factor as our new denominator for this ratio */ 0627 (*ratio_pointer).setDenominator((*prim_fac_pointer).factor, false); 0628 unused_fac--; /* now there is one factor less available */ 0629 0630 /* move to the next ratio */ 0631 ratio_pointer++; 0632 op_pointer++; 0633 } while ((op_pointer != op_vector.end()) && 0634 (*op_pointer == MUL || *op_pointer == DIV)); 0635 0636 /* we always miss to set the last ratio in a mul/div section; 0637 * so we have to fix this here */ 0638 if (ratio_pointer != ratio_vector.end()) { 0639 /* the prim_fac_vector is sorted, but we do not want the 0640 * factors in this sorted way as our denominators; 0641 * so we choose one randomly */ 0642 next_fac = QRandomGenerator::global()->bounded(unused_fac); 0643 tmp_counter = 0; 0644 0645 /* check the prime factors, if they are unused */ 0646 for (prim_fac_pointer = prim_fac_vector.begin(); 0647 prim_fac_pointer != prim_fac_vector.end(); 0648 ++prim_fac_pointer) { 0649 if ((*prim_fac_pointer).flag == UNUSED) { 0650 tmp_counter++; /* we found a unused factor */ 0651 } 0652 /* we found the factor, which we have chosen randomly */ 0653 if (tmp_counter > next_fac) 0654 break; 0655 } 0656 /* mark the factor as used, so we can not use it again in 0657 * this mul/div section */ 0658 (*prim_fac_pointer).flag = USED; 0659 0660 /* store the factor as our new denominator for this ratio */ 0661 (*ratio_pointer).setDenominator((*prim_fac_pointer).factor, false); 0662 unused_fac--; /* now there is one factor less available */ 0663 0664 /* move to the next ratio */ 0665 ratio_pointer++; 0666 op_pointer++; 0667 } 0668 } else { 0669 /* if (*op_pointer == MUL || ...) */ 0670 ratio_pointer++; 0671 op_pointer++; 0672 } 0673 } while (ratio_pointer != ratio_vector.end() && 0674 op_pointer != op_vector.end()); 0675 0676 /* now we will swap all ratios, if there is a div in front of */ 0677 ratio_pointer = ratio_vector.begin(); 0678 ratio_pointer++; 0679 0680 for (op_pointer = op_vector.begin(); op_pointer != op_vector.end(); 0681 ++op_pointer) { 0682 if (*op_pointer == DIV) { 0683 (*ratio_pointer).reziproc(); 0684 } 0685 ratio_pointer++; 0686 } 0687 } /* if (pmul_div == YES) */ 0688 0689 return; 0690 } 0691 0692 0693 /* ------ some prototyps of non class functions ------ */ 0694 0695 /** it is possible to code: cout << task_object << endl; */ 0696 QTextStream & operator<< (QTextStream & str, Task & ptask) 0697 { 0698 return ptask.display(str); 0699 }