我正在尝试使用STL映射编写代码,该映射从文件中读取并解析该行。如何跟踪文件中的重复项?关键值是术语和部分。我想把重复项放在一个向量中,但我不太清楚如何。还是有更好的方法吗?
#include <fstream>
#include <iostream>
#include <iomanip>
#include <string>
#include <cstring>
#include <ctime>
#include <utility>
#include <vector>
#include <map>
using namespace std;
int main()
{
map <string, map <string, int> > subjectCourse;
vector <string> duplicate;
// for parsing the input file
char* token;
char buf[1000];
const char* const tab = "\t";
// open the input file
ifstream fin;
fin.open("schedule.txt");
clock_t startTime = clock(); // start timer
if (!fin.good()) throw "I/O error";
while (fin.good())
{
// read line
string line;
getline(fin, line);
strcpy(buf, line.c_str());
if (buf[0] == 0) continue;
// parse line
const string term(token = strtok(buf, tab));
const string section(token = strtok(0, tab));
const string course((token = strtok(0, tab)) ? token : "");
const string instructor((token = strtok(0, tab)) ? token : "");
const string whenWhere( (token = strtok(0, tab)) ? token : "");
if (course.find('-') == string::npos) continue; // invalid line
const string subjectCode(course.begin(), course.begin() + course.find('-'));
subjectCourse[subjectCode][course]++; // enter data to the map
}
fin.close();
for(map<string, map<string, int> >::iterator i = subjectCourse.begin(); i!= subjectCourse.end(); ++i){
cout << (*i).first << ", " << (*i).second.size() << " courses.\n";
for(map<string, int>::iterator j = (*i).second.begin(); j != (*i).second.end(); ++j)
cout << " " << (*j).first << ", " << (*j).second << " class(es).\n";
}
答案 0 :(得分:2)
看起来像你需要的是std::multimap。
答案 1 :(得分:0)
我更喜欢multimap:
#include <fstream>
#include <iostream>
#include <iomanip>
#include <string>
#include <cstring>
#include <ctime>
#include <utility>
#include <vector>
#include <map>
using namespace std;
int main()
{
multimap <string, string> subjectCourse;
vector <string> duplicate;
// for parsing the input file
char* token;
char buf[1000];
const char* const tab = "\t";
// open the input file
ifstream fin;
fin.open("schedule.txt");
clock_t startTime = clock(); // start timer
if (!fin.good()) throw "I/O error";
while (fin.good())
{
// read line
string line;
getline(fin, line);
strcpy(buf, line.c_str());
if (buf[0] == 0) continue;
// parse line
const string term(token = strtok(buf, tab));
const string section(token = strtok(0, tab));
const string course((token = strtok(0, tab)) ? token : "");
const string instructor((token = strtok(0, tab)) ? token : "");
const string whenWhere( (token = strtok(0, tab)) ? token : "");
if (course.find('-') == string::npos) continue; // invalid line
const string subjectCode(course.begin(), course.begin() + course.find('-'));
subjectCourse.insert(std::make_pair(subjectCode, course)); // enter data to the map
}
fin.close();
for(multimap<string, string>::iterator i = subjectCourse.begin(); i!= subjectCourse.end(); ++i)
{
cout << " " << i->first << " course, " << i->second << " class(es).\n";
}
}
唯一的好处是代码简化(不再是容器的容器)。
如果您想要每门课程的课程数量:
multimap<string, string>::iterator it = subjectCourse.begin();
while (it != subjectCourse.end())
{
multimap<string, string>::iterator next_it = subjectCourse.upper_bound(it->first);
cout << " " << it->first << " course as " << std::distance(it, next_it) << " class(es).\n";
it = next_it;
}
如果您想跟踪重复次数:
multimap<string, string>::iterator it = subjectCourse.begin();
while (it != subjectCourse.end())
{
multimap<string, string>::iterator next_it = it;
while ((subjectCourse.end() != next_it)
&& (*it == *next_it))
{
++next_it;
}
cout << " " << it->first << " course, " << it->second << " classes: " << std::distance(it, next_it) << " occurences.\n";
}