2016-12-05 5 views
1

Le but du code est de supprimer fondamentalement les mots à l'intérieur du tableau inutile présents dans un fichier texte. J'ai ce problème très étrange où le code ne supprimera pas le mot 'the' dans l'expression 'waiting on the shelf', mais tous les autres cas de test (beaucoup) passés. Des idées?Un cas de test spécifique ne réussira pas le test d'une manière ou d'une autre

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

Bienvenue dans Stack Overflow! Il semble que vous deviez apprendre à utiliser un débogueur pour parcourir votre code. Avec un bon débogueur, vous pouvez exécuter votre programme ligne par ligne et voir où il dévie de ce que vous attendez. C'est un outil essentiel si vous voulez faire de la programmation. Pour en savoir plus: [Comment déboguer de petits programmes] (https://ericlippert.com/2014/03/05/how-to-debug-small-programs/). –

+0

Oui, oui je peux voir comment un débogueur m'aiderait vraiment ici. Je n'utilise actuellement aucun IDE (juste sublime et terminal) d'où l'absence d'un débogueur. –

+0

Vous n'avez pas besoin d'un IDE pour utiliser un débogueur - vous pouvez simplement utiliser gdb depuis la ligne de commande. –

Répondre

2

Vous utilisez l'itération incorrecte ici

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

Avant cette itération vous avez vecteur avec les valeurs suivantes: [attente] [sur] [le] [tablette]. Quand i == 1 vous supprimez "on" du vecteur, de sorte que vous avez le prochain vecteur [attente] [la] [étagère], mais i index toujours égal à 1, à la prochaine itération vous sautez " le "mot car la dernière opération d'effacement a réorganisé votre vecteur et déplacé" le "mot à supprimer" sur "position".

Vous pouvez utiliser remove_if. Par exemple:

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

Après que vous aurez vecteur filtré, sans paroles dans le inutile tableau. En passant, nous pouvons optimiser cela. L'algorithme ci-dessus a la complexité suivante: O (vec_size * useless_size). Nous pouvons l'optimiser à O (vec_size) seulement. Au lieu de tableau, vous pouvez utiliser la collection de hachage (unordered_set) Cela vous donne un temps constant pour l'accès aux éléments.

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

Donc une solution serait de réinitialiser l'itérateur chaque fois qu'un élément est supprimé? edit: ou décrémente-t-il chaque fois qu'un élément est supprimé? –

+1

Je vais écrire la solution dans la réponse. – arturx64

+0

Cela a juste fonctionné. Pouvez-vous expliquer comment cela fonctionne? –