2017-10-12 5 views
-2

J'ai un programme qui invite un utilisateur à entrer une valeur. Chaque valeur que l'utilisateur entre est placée dans un vecteur 'autre' qui n'est là que pour la validation. Si une valeur en double a été saisie, l'utilisateur recevra une invite jusqu'à ce qu'il saisisse une valeur unique.Empêcher l'entrée en double dans le vecteur? C++

Le principal problème auquel je suis confronté est que, pour une raison quelconque, lors de l'exécution du code et l'impression des résultats du vecteur, il semble y avoir une entrée en double. Quelqu'un pourrait-il me dire pourquoi?

Voir ci-dessous pour mon code:

// prompt to continue 
cout << "Would you like to continue? [Y]es, [N]o: "; 
cin >> toContinue; 

while (toContinue == 'Y') 
{ 
    bool isDuplicate = 0; 

    // prompt for product no. 
    cout << "Please enter product number: "; 
    cin >> productB; 

    // Validation check for duplicate entries 
    for (size_t i = 0; i < other.size(); i++) 
    { 
     if (productB == other[i]) 
      isDuplicate = 1; 

     while (isDuplicate == 1) 
     { 
      cout << "You have already entered this product number!" << endl; 
      cout << "Please enter correct product number: "; 
      cin >> productB; 

      if (productB != other[i]) 
       other.push_back(productB); 

      isDuplicate = 0; 
     } 
    } 
    // prompt to continue 
    cout << "Would you like to continue? [Y]es, [N]o: "; 
    cin >> toContinue; 
} 
+7

Utilisez plutôt 'std :: set' à la place. – user0042

+0

Vous voudrez peut-être passer par votre programme avec un débogueur. Astuce: Que se passe-t-il lorsque je saisis «3 4 3»? – Rakete1111

+5

Après avoir détecté un doublon, vous demandez à l'utilisateur d'entrer de nouveau. Vous vérifiez ce nouveau numéro par rapport à un numéro entré immédiatement avant, mais pas à tous les numéros précédemment entrés. Ainsi, l'utilisateur entre "1", puis "2", puis "1". Vous détectez le doublon et demandez à entrer de nouveau. Ils entrent '2', vous vérifiez seulement que' 2! = 1' et ajoutez heureusement le second '2' au vecteur. –

Répondre

1

Alors que son courant d'utiliser std::set pour des éléments uniques, si vous doit retourner un vecteur pour certaines raisons, je cette approche:

std::set<int> my_set; 

my_set.insert(1); 
my_set.insert(2); 
my_set.insert(1); 

// ... insert more 

std::vector<int> my_vector(my_set.size()); 
std::copy(my_set.begin(), my_set.end(), my_vector.begin()); 

assert(my_vector.size()==2); 

Notez que le vecteur my_vector sera trié.

1

Une fois que vous avez entré un doublon, vous laissez l'utilisateur entrer à nouveau un nombre; alors vous vérifiez seulement si le nouveau nombre entré est le même que le double entré avant; mais vous ne vérifiez pas si l'utilisateur a entré une valeur différente mais toujours en double.

Généralement, vous mélangez l'entrée utilisateur avec la logique du programme; Le dégroupage rend le code plus lisible et moins sujette aux erreurs. Voir, par exemple, les fragments suivants montrant comment on pourrait séparer ces préoccupations:

bool isContained(const vector<int> &v, int value) { 
    // your code to check for duplicates goes here 
} 

int main() { 

    ... 

    while (toContinue == 'Y') { 

     // prompt for product no. 
     cout << "Please enter product number: "; 
     cin >> productB; 

     if (isContained(other, productB)) { 
     cout << "You have already entered this product number!" << endl; 
     } 
     else { 
     other.push_back(productB); 
     } 

     // prompt to continue 
     cout << "Would you like to continue? [Y]es, [N]o: "; 
     cin >> toContinue; 
    } 
} 

également une indication générale: en utilisant des structures de données appropriées peuvent également aider à éviter les lignes inutiles de codes; Un conteneur évitant les doublons, par exemple, est std::set.

1

Vous pouvez vous aider énormément en décomposant les composants de votre logique en fonctions plus petites.

La plupart de ce que j'ai fait ici est en ordre, mais notez l'encapsulation de la fonction contains.

#include <vector> 
#include <iostream> 
#include <algorithm> 

using namespace std; 

bool contains(std::vector<int> const& vals, int val) 
{ 
    return std::count(std::begin(vals), std::end(vals), val) != 0; 
} 

bool shouldContinue() 
{ 
    char toContinue; 
    cout << "Would you like to continue? [Y]es, [N]o: "; 
    cin >> toContinue; 
    return toContinue == 'Y'; 
} 

int getProduct(bool again) 
{ 
    int productB; 
    if (again) 
    { 
     cout << "You have already entered this product number!" << endl; 
    } 
    cout << "Please enter correct product number: "; 
    cin >> productB; 
    return productB; 
} 

void printProducts(std::vector<int> const& vals) 
{ 
    std::cout << "You have selected:"; 
    const char* sep = " "; 
    for(int p : vals) 
    { 
     std::cout << sep << p; 
     sep = ", "; 
    } 
    std::cout << std::endl; 
} 


int main() 
{ 
    std::vector<int> other; 

    while (shouldContinue()) 
    { 
     int productB = getProduct(false); 
     while(contains(other, productB)) 
     { 
      productB = getProduct(true); 
     } 
     other.push_back(productB); 
    } 

    printProducts(other); 
}