2016-12-05 45 views
1

代碼的目的是基本上刪除無用數組中的文本文件中存在的單詞。我有這個非常奇怪的問題,代碼不會刪除'等待上架'這個短語中的'the'這個詞,但是其他所有測試用例(很多)都會通過。有任何想法嗎?一個特定的測試用例不會通過測試

int main(){ 
    string useless[20] = { "an", "the" , "of", "to", "and", "but", "nor", "or", "some", "any", "very", "in", "on", "at", "before", "after", "into", "over", "through", "along"}; 

    ifstream fin("input.txt"); 
    if(fin.fail()){ 
     cout << "Input failed to open" << endl; 
     exit(-1); 
    } 

    string line; 
    getline(fin, line); 
    getline(fin, line); 
    getline(fin, line); 
    getline(fin, line); 

    ofstream fout("output.txt"); 

    while(getline(fin, line)){ 
     vector<string> vec; 
     istringstream iss(line); 
     while (iss) { 
      string word; 
      iss >> word; 
      transform(word.begin(), word.end(), word.begin(), ::tolower); 
      vec.push_back(word); 
     } 

     for(int i = 0; i < vec.size(); i++){ 
      for(int j = 0; j < 20; j++){ 
       if(vec[i] == useless[j]){ 
        vec.erase(remove(vec.begin(), vec.end(), vec[i]), vec.end()); 
       } 
      } 
      fout << vec[i] << " "; 
     } 
     fout << endl; 
    } 
} 
+2

歡迎來到Stack Overflow!這聽起來像你可能需要學習如何使用調試器來遍歷代碼。使用一個好的調試器,您可以逐行執行您的程序,並查看它與您期望的偏離的位置。如果你打算做任何編程,這是一個重要的工具。進一步閱讀:[如何調試小程序](https://ericlippert.com/2014/03/05/how-to-debug-small-programs/)。 –

+0

是的,是的,我可以看到一個調試器如何真正幫助我。我目前沒有使用任何IDE(只是崇高和終端),因此缺乏調試器。 –

+0

你不需要IDE來使用調試器 - 你可以在命令行中使用gdb。 –

回答

2

您在這裏

for(int i = 0; i < vec.size(); i++){ 
     for(int j = 0; j < 20; j++){ 
      if(vec[i] == useless[j]){ 
       vec.erase(remove(vec.begin(), vec.end(), vec[i]), vec.end()); 
      } 
     } 
     fout << vec[i] << " "; 
    } 
    fout << endl; 
} 

使用不正確的迭代本次迭代之前,你有下一個值向量:[上] [中] [貨架] [等着]。當i = 1時,從矢量中刪除「on」,以便您有下一個矢量[waiting] [shelf],但是i index仍然等於1,在下一次迭代中跳過「該字「,因爲最後的擦除操作會重新組織您的向量,並將」該字「移至已刪除的」開「位置。

您可以使用remove_if。例如:

vec.erase(remove_if(vec.begin(), vec.end(), [&](const string& str) 
{ 
    return std::find(begin(useless), end(useless), str) != end(useless); 
}), vec.end()); 

後,你會得到濾波矢量,沒有無用數組中的話。

順便說一句,我們可以優化。上面的算法具有下一個複雜度:O(vec_size * useless_size)。我們可以只將它優化爲O(vec_size)。 你可以使用散列集合(unordered_set)來代替數組,它可以爲元素訪問提供恆定的時間。

unordered_set<string> useless = { "an", "the" , "of", "to", "and", "but", "nor", "or", "some", "any", "very", "in", "on", "at", "before", "after", "into", "over", "through", "along" }; 
... 
vec.erase(remove_if(vec.begin(), vec.end(), [&](const string& str) 
{ 
    return useless.find(str) != useless.end(); 
}), vec.end()); 
+0

所以一個解決方案是每次刪除元素時重置迭代器?編輯:或只是減少我每次刪除元素? –

+1

我會在答案中寫出解決方案。 – arturx64

+0

這只是工作。你能解釋這是如何工作的嗎? –

相關問題