|
|
Question : How do I express this in code?
|
|
|
|
Recap: There's a contest between students A-G to see who can launch an object the farthest in feet. I wanted to identify instances when there are ties between different students i.e. where their throws are the exact same distance. I don't care if a student ties himself.
Ok, if you run this code you'll notice that student D shows up twice in the 22 feet line. How do I get rid of this so that no student is repeated twice at any distsance? I see what is wrong and can explain it in words..but my mind freezes up when I want to change the code...help?
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:
|
#include <iomanip>
#include <iostream>
#include <string>
#include <sstream>
#include <set>
#include <vector>
#include <algorithm>
using namespace std;
struct StudentAttempt
{
int distance;
string studentName;
};
bool cmpAttempts(StudentAttempt left, StudentAttempt right) {
if( left.distance < right.distance ) {
return true;
}
else if( left.distance == right.distance ) {
if( left.studentName < right.studentName ) {
return true;
}
else
return false;
}
else
return false;
}
bool isDistEqual( StudentAttempt left, StudentAttempt right) {
return ( left.distance == right.distance
&& left.studentName != right.studentName );
}
size_t printAllEqual(const vector<StudentAttempt>& v, const StudentAttempt& sa, stringstream& ss ) {
vector<StudentAttempt>::const_iterator i = v.begin();
size_t sz = 0;
bool bFirst = true;
while (i != v.end()) {
if(isDistEqual(*i,sa)) {
if (!bFirst) ss << ',';
ss << i->studentName;
++sz;
}
++i;
bFirst = false;
}
return sz;
}
int main() {
StudentAttempt throwDist[] = {
{50, "A"}, {22, "A"}, {16, "B"}, {44, "C"},
{33, "D"}, {34, "E"}, {22, "F"}, {21, "G"},
{49, "A"}, { 5, "B"}, { 2, "C"}, {22, "A"},
{33, "B"}, {22, "C"}, {22, "D"}, {44, "E"}, {22, "D"}
};
set<int> handled;
int len = sizeof( throwDist )/ sizeof( throwDist[0] );
vector<StudentAttempt> dist(throwDist, throwDist + len);
vector<StudentAttempt>::iterator it = dist.begin();
sort( dist.begin(), dist.end(), cmpAttempts);
//unique( dist.begin(), dist.end(), cmpDist);
for( ; it != dist.end(); it++ ) {
stringstream ss;
pair<set<int>::iterator,bool> p = handled.insert(it->distance);
if (!p.second) continue; // already handled
if(0 < printAllEqual(dist,*it,ss))
cout << setw(2) << (*it).distance
<< " feet: " << (*it).studentName << ss.str() << endl;
}
}
|
|
|
|
|
Answer : How do I express this in code?
|
|
Well, in
{33, "B"}, {22, "C"}, {22, "D"}, {44, "E"}, {22, "D"}
you have that very duplicate entry - just remove it after it is sorted, e.g.
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:
|
#include <iomanip>
#include <iostream>
#include <string>
#include <sstream>
#include <set>
#include <vector>
#include <algorithm>
using namespace std;
struct StudentAttempt
{
int distance;
string studentName;
};
bool cmpEntry(StudentAttempt left, StudentAttempt right) {
return left.distance == right.distance && left.studentName == right.studentName;
}
bool cmpAttempts(StudentAttempt left, StudentAttempt right) {
if( left.distance < right.distance ) {
return true;
}
else if( left.distance == right.distance ) {
if( left.studentName < right.studentName ) {
return true;
}
else
return false;
}
else
return false;
}
bool isDistEqual( StudentAttempt left, StudentAttempt right) {
return ( left.distance == right.distance
&& left.studentName != right.studentName );
}
size_t printAllEqual(const vector<StudentAttempt>& v, const StudentAttempt& sa, stringstream& ss ) {
vector<StudentAttempt>::const_iterator i = v.begin();
size_t sz = 0;
bool bFirst = true;
while (i != v.end()) {
if(isDistEqual(*i,sa)) {
if (!bFirst) ss << ',';
ss << i->studentName;
++sz;
}
++i;
bFirst = false;
}
return sz;
}
int main() {
StudentAttempt throwDist[] = {
{50, "A"}, {22, "A"}, {16, "B"}, {44, "C"},
{33, "D"}, {34, "E"}, {22, "F"}, {21, "G"},
{49, "A"}, { 5, "B"}, { 2, "C"}, {22, "A"},
{33, "B"}, {22, "C"}, {22, "D"}, {44, "E"}, {22, "D"}
};
set<int> handled;
int len = sizeof( throwDist )/ sizeof( throwDist[0] );
vector<StudentAttempt> dist(throwDist, throwDist + len);
vector<StudentAttempt>::iterator it = dist.begin();
sort( dist.begin(), dist.end(), cmpAttempts);
unique( dist.begin(), dist.end(), cmpEntry); // removes identical duplicates from the sorted vector
for( ; it != dist.end(); it++ ) {
stringstream ss;
pair<set<int>::iterator,bool> p = handled.insert(it->distance);
if (!p.second) continue; // already handled
if(0 < printAllEqual(dist,*it,ss))
cout << setw(2) << (*it).distance
<< " feet: " << (*it).studentName << ss.str() << endl;
}
}
|
|
|
|
|