|
> 2つの値の大小をどんどん入力していって、最後に大きい順にまとめて
> 表示したいのですが、どうすればいいでしょう。
各チーム(値)について、対戦相手と自分の負け数を記録しておいて、
負け数ゼロがチャンピオン。
記録から、チャンピオンの対戦相手の負け数を減らします。
チャンピオンを記録から除いて、新たなチャンピオンを選びます。
これを繰り返せばよいでしょう。
参考にならないかもしれませんが、C++ のプログラムを書いてみました。
#include <iostream>
#include <sstream>
#include <map>
#include <set>
#include <cctype>
using std::cout;
typedef std::multiset<char> Set;
struct Team {
int lose;
Set rivals;
Team() : lose(0) { }
};
typedef std::map<char, Team> Map;
void input(Map &record)
{
std::string buf;
while (cout << "> ", getline(std::cin, buf)) {
std::istringstream iss(buf); char n1, op, n2, x;
if (!(iss >> n1) || n1 == '.') break;
if (!(iss >> op >> n2) || iss >> x || op!='<' && op!='>'
|| !std::islower(n1) || !std::islower(n2))
cout << "bad input\n";
else {
Team *t1 = &record[n1]; t1->rivals.insert(n2);
Team *t2 = &record[n2]; t2->rivals.insert(n1);
(op == '<') ? t1->lose++ : t2->lose++;
}
}
}
char get_winner(Map &record)
{
char winner = 0;
for (Map::iterator it = record.begin(); it != record.end(); ++it)
if (it->second.lose == 0) {
if (winner) return 0;
winner = it->first;
}
return winner;
}
void remove(Map &record, char team)
{
Set *s = &record[team].rivals;
for (Set::iterator it = s->begin(); it != s->end(); ++it) {
Team *t = &record[*it];
t->lose -= t->rivals.erase(team);
}
record.erase(team);
}
int main()
{
Map record;
input(record);
while (record.size() > 0) {
char winner = get_winner(record);
if (winner == 0) { cout << "can't sort\n"; return 1; }
cout << winner;
remove(record, winner);
}
cout << '\n';
}
-----------------------------
実行結果
> a>b
> b<c
> a < c
> .
cab
|