2013-12-18 69 views
0

我正在嘗試使用STL映射編寫代碼來讀取和解析文件中的行。我如何跟蹤文件中的重複項?關鍵值是術語和部分。我正在考慮將重複項放入矢量中,但我不太確定。或者有沒有更好的方法?跟蹤重複鍵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"; 
} 
+1

如果你想要的是式兩份檢測,key-to-int的單個映射就足夠了。在枚舉過程中,如果'++ mymap [key]> 1'成立,你有一個副本。 – WhozCraig

+0

你是什麼意思?所以我還需要跟蹤重複以外的所有數據的數量? – chipunpui

+0

不,我的意思是如果你關心的是重複檢測,那麼你可以放棄值持久化,只是使用一個應該映射什麼應該是唯一鍵。如果您想知道* insert *時間的重複檢測,您希望*保留*,利用['std :: map <> :: insert']的結果(http://en.cppreference.com/ w/cpp/container/map/insert),特別是包含一個迭代器到鍵控值的'std :: pair <>'和一個表示該項是否是新插入的'bool',可能更多你想採取的路徑。通過它的聲音,你有點需要*兩個*。 – WhozCraig

回答

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"; 
    } 
} 

http://ideone.com/Zrf7RO

唯一增益代碼簡化(無容器的多個容器)。

如果你想要的類每門課程的數量:

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"; 
} 

http://ideone.com/AqggCV

+0

謝謝,但我仍然需要跟蹤重複的數量。這裏有兩個關鍵值,我只看比較一個關鍵值的大多數例子。 – chipunpui

+0

@chipunpui mmmh,是,否。你必須數它們,但它們在multimap中。我已經添加了一個例子。 – Johan