Софтуерно Инженерство
Loading...
+ Нов въпрос
Zmyrt avatar Zmyrt 2 Точки

Task 3 - Algebra helper ( Exam )

Здравейте колеги !

Вече ден втори след изпитът продължава да ми убягва едно нещо по въпросната задача 3 .

Ако правилно съм разбрал структурата "multimap" подрежда елементите си спрямо ключът и по възходящ ред .

Ако има ключове с равни стойности то се запазва редът в който са въведени като елементи в структурата .

Тази информация съм си я набавил от известни сайтове в интернет .

Можете ли да прегледате кодът, който съм написал и да разтълкуваме заедно, защо елементите с еднакви ключове не се подреждат по ред на въвеждането им като "input" ?

https://pastebin.com/DUw4Tpxu

Програмата се държи добре, докато не срещне елементи с еднакви ключове. Реално изходът е адекватен , но не удовлетворява малкото, капризно условиице :

  "If two or more equations have the same result he keeps their order from the input. The first one remains first, second one – second"

Старал съм се да напиша четимо кодът , дано лесно се разбира какво съм искал да постигна...

Условие на задачата : 

=======================================================================================

Little Ibrahim has some trouble with his math homework. He tries to learn some equation by heart. Help him out!
Ibrahim remembers the equations in his head by memorizing their result. He has good visual memory and utilizes it. He arranges the equations in his head in descending order by their result.
If two or more equations have the same result he keeps their order from the input. The first one remains first, second one – second, etc …
An equation will only be constructed from a 2 integers and an operating between the 2 integers.
NOTE: only the following 5 operations should be supported:
    + (sum)
    - (subtraction) 
    * (multiplication)
    / (integer division)
    % (integer modulo)
NOTE 2: there will be no brackets. Nothing fancy – just 2 integers and an operation between them.
Input
First a single integers (N) indicating how many equations will follow (each on a different line).
Next read (N) lines of equations. Each equation contains a number, after that an operations and then another number – always in that order.

Examples :

- Input 1 -

3

1 / 2

1 * 2

1 + 2 

- Output 1 -

1 + 2

1 * 2

1 / 2

- Input 2 -

4

2 * 0

6 % 4

5 + 3

2 - 6

- Output 2 -

5 + 3

6 % 4

2 * 0

2 - 6

- Input 3 -

4

2 * 13

6 % 3

20 + 6

2 - 2

- Output 3 -

2 * 13

20 + 6

6 % 3

2 - 2

=======================================================================================

Чакам идеи и благодаря предварително !  :)

Тагове:
0
C++ Fundamentals 19/11/2019 19:52:48
MartinBG avatar MartinBG 1215 Точки

Не си дал условието на задачата или поне примерен вход и очакван резултат.

На пръв поглед, обръщаш последователността при извеждане на резултата, защото го прекарваш през stack.

0
Zmyrt avatar Zmyrt 2 Точки

Да , наистина не бях го дал, не съобразих . Сега е ОК , ако имаш време може да го погледнеш...

Поздрави ! 

0
MartinBG avatar MartinBG 1215 Точки

Както казах в предишния пост, резултатите са обърнати, защото ги прекарваш през стек.

Представи си следния ценарий:

Key : Value

0 : 0

1 : 1

1 : 2

1 : 3

2 : 4

В multimap-a елементите ще са точно в този ред, но като ги прекараш през стека, те ще бъдат изведени така:

2 : 4

1: 3

1 : 2

1: 1

0 : 0

Докато по условие се иска да са:

2 : 4

1 : 1

1 : 2

1 : 3

0 : 0

Задачата ще се реши по-лесно, ако ползваш map<int, vector<string> >

0
19/11/2019 20:52:04
Zmyrt avatar Zmyrt 2 Точки

Прекарвам резултатите през стека само, за да ги изведа в низходящ ред.

Защото ако ги сортирам със "sort" oт <algorithm>  ми разбърква елементите с еднакъв ключ.

Освен това , ако махна въвеждането в "stack" и вместо това извикам "cout" на съответният елемент се получава пак неправилен резултат но в обратна последователност ( съдя по даденият "output" ) .

Извинявай Мартине ,  но или не схващам проблемът или той е другаде . 

Дай да зарежем "stack" - а . Ако го махнем резулта е в обратна последователност , но пак разменя местата на еднаквите ключове :)

 

П.С.

Копираното съдържание е малко бъгаво по неизвестни за мен причини , моля въведи ръчно input-ите , задължително с интервали между символите

П.С .С 

...и благодаря ти , че отделяш от времето си за колегите си !!! 

0
19/11/2019 23:04:27
MartinBG avatar MartinBG 1215 Точки

 Демо код:

#include <iostream>
#include <map>
#include <stack>

int main() {
  std::multimap<int, std::string> mm{ };

  mm.emplace(1, "first");
  mm.emplace(1, "second");
  mm.emplace(2, "third");
  mm.emplace(2, "fourth");

  std::cout << "In multimap:" << std::endl;
  for (const auto& pair : mm) {
    std::cout << pair.first << ":" << pair.second << std::endl;
  }

  std::stack<std::pair<int, std::string>> revStack{ };

  for (const auto& pair : mm) {
    revStack.push(pair);
  }

  std::cout << "After stack:" << std::endl;
  while (!revStack.empty()) {
    const auto pair = revStack.top();
    std::cout << pair.first << ":" << pair.second << std::endl;
    revStack.pop();
  }

  return 0;
}

Output:

In multimap:
1:first
1:second
2:third
2:fourth
After stack:
2:fourth
2:third
1:second
1:first

Live demo

В multimap-a стойностоти са сортирани по ключ, а идентичните ключове са в реда. в който са били въведени, както и трябва да бъде.

След стека резултатите се извеждат в намаляваща стойност по ключа (както се очаква), но реда на идентичните ключове е обърнат ("second" e преди "first").

Не знам кое те обърква.

 

0
dmartinov avatar dmartinov 36 Точки

Печата ти ги в обратен ред, защото ключовете в multimap са наредени възходящо, а твоята цел е да ги принтираш низходящо. За целта промени си инициализацията на multimap-а ето така:

multimap <  int, string, greater<>  > database;

След, което можеш да печаташ директно от мапа без да има нужда да записваш резултатите в stack след което да ги вадиш от там. Спестяваш си една излишна стъпка. Печаташ резултата ето така:

for (multimap < int, string > ::iterator it = database.begin(); it != database.end(); ++it)
    {
        std::cout <<  it->second << std::endl;
    }

Впрочем дори да се опиташ да приложиш първоначалната си стратегия, стъпката със stack-а пак можеше да си я спестиш, като ползваш reverse_iterrator. Дефинира се ето така:

std::multimap<int, std::string>::reverse_iterrator rItr;

И го ползваш за печатане ето така:

for (rItr = database.rbegin();  rItr != database.rend(); ++rItr {

std::cout << rItr -> second << std::endl;

}

Да, това пак нямаше да даде правилна подредба на резултатите, но няма да си играеш да създаваш stack, да го пълниш и после да печаташ и да го изпразваш.

0
20/11/2019 13:18:45
MartinBG avatar MartinBG 1215 Точки

Отделно от основната дискусия, ето решение с multimap, при което няма нужда от пренареждане на елементите:

#include <iostream>
#include <map>

int main() {
  std::multimap<int, std::string, std::greater<>> mm{
      { 2 * 13, "2 * 13" },
      { 6 % 3,  "6 % 3" },
      { 20 + 6, "20 + 6" },
      { 2 - 2,  "2 - 2" }
  };

  for (const auto& pair : mm) {
    std::cout << pair.first << " <- " << pair.second << std::endl;
  }

  return 0;
}

Output:

26 <- 2 * 13
26 <- 20 + 6
0 <- 6 % 3
0 <- 2 - 2

0
Zmyrt avatar Zmyrt 2 Точки

Супер!  Благодаря за идеите , колеги . Ок е задачата вече . 

Не знаех за наличието на трети параметър на мултимап . Реално само с добавянето на  " greater< int > "  приключи заигравката .

А и това за "обратният" итератор не го знаех а излежда полезно.

0