2017-10-12 15 views
-2

私は値を入力するようにユーザーに促すプログラムを持っています。ユーザーが入力する各値は、検証のためだけに存在する「その他の」ベクトルに配置されます。重複した値が入力された場合、ユーザは一意の値を入力するまでプロンプトを表示します。ベクトルへの重複エントリを防止しますか? C++

私が直面している主な問題は、コードを実行してベクターの結果を印刷する何らかの理由で、重複したエントリがあるようです。誰でも私にそれがなぜあるのか教えてもらえますか?

私のコードについては、以下を参照してください:

// 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

'のstd ::代わりset'を使用してください。 – user0042

+0

デバッガを使用してプログラムを実行したい場合があります。ヒント: '3 4 3'と入力するとどうなりますか? – Rakete1111

+5

重複を検出したら、ユーザーに再入力を依頼します。直前に入力した1つの番号に対してこの新しい番号をチェックしますが、以前に入力したすべての番号に対してはチェックしません。つまり、ユーザーが「1」を入力した後、「2」を入力し、次に「1」を入力します。あなたは重複を検出し、再入力を求めます。彼らは '2'を入力し、あなたは' 2!= 1'をチェックして、うれしく2番目の '2'をベクトルに加えます。 –

答えて

1

ユニークな要素のためのstd::setを使用してその共通ながら、あなたには、いくつかの理由のためのベクトルを返さなければなりません機能している場合、私はこのようなアプローチを使用:

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

ベクトルmy_vectorがソートされることに注意してください。

1

重複を入力すると、ユーザーは番号を再入力できます。入力した新しい番号が前に入力された複製と同じである場合にのみチェックします。ユーザーが異なるが重複した値を入力したかどうかはチェックしません。

一般に、ユーザー入力とプログラムロジックを混在させます。これをアンバンドリングすると、コードが読みやすくなり、エラーが発生しにくくなります。例えば、1は、これらの懸念を分離できる方法を示す以下の断片を参照してください。また、

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

一般的なヒント:適切なデータ構造を使用した場合も、コードの不要な行を避けるために助けることができます。重複を避けるコンテナは、たとえば、std::setです。

1

ロジックのコンポーネントをより小さな機能に分割することで、多大な手間をかけることができます。

私はここでやっていることのほとんどは整頓ですが、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); 
}