C++: Removing a duplicate of the user input in an array - c++

I have been trying to solve this problem since yesterday. The program should accept N numbers from the user and will place them in an array. I have done this. However, I don't seem to know how to "warn" the user that the input is a duplicate and lets the user enter again.
Here is my code:
# include <iostream>
using namespace std;
int main () {
int N, pos = -1, arr [N], i, j;
int startLoop = 1;
// the 'startLoop' variable is used so that the first user input can have the break function
bool found = false;
while (startLoop != 0) {
cout << "Enter the number of integers to be entered: ";
cin >> N;
if (N <= 4) {
cout << "Invalid. \n";
}
if (N > 4) {
cout << "\n\nEnter " << N << " unique numbers: " ;
for (i = 0; i < N; i++) {
cin >> arr [i];
for (j = 0; j < N && !found; j++) {
if (arr [j] == arr [i]) {
found = true;
cout << "Enter again: ";
}
}
break;
}
}
}

The following is the copy paste of your code:
By adding break you will jump out of the outer for loop and you cannot read n inputs.
the inner loop range is not correct since i is the total number of values read by now. i.e. if N= 10 and in third iteration you are trying to loop among 10 elements to double check if the latest number is a duplicate, while you have read 3 elements by now.
if (N > 4) {
cout << "\n\nEnter " << N << " unique numbers: " ;
for (i = 0; i < N; i++) {
cin >> arr [i];
for (j = 0; j < N && !found; j++) {
if (arr [j] == arr [i]) {
found = true;
cout << "Enter again: ";
}
}
break;
}
}
How to fix?
One approach would be to read the input in a separate loop and then try to find the duplicates and remove them.
Time Complexity will be O(n) since you need to traverse through the list twice, however you need to implement removing elements from the array efficiently without shifting all the elements
Second approach is like what you are trying to implement but it is not efficient since every time a user is adding a new elements you need to re-evaluate i numbers (in worst case n numbers when you are filling the end of array). this process should be repeated every time user insert a repeated number.
The best approach would be store all input numbers inside a hash (set) and every-time a new number is inserted check whether it is already suggested by the user or not. Time complexity of searching elements through unordered_set will be O(1)

Problems:
Your code has many several problems:
You shouldn't use VLAs (Variable Length Arrays) as they are non-standard.
Using N before initializing it is UB (Undefined Behaviour).
Your approach is not efficient as it checks on average n/2 elements n times and therefore it has a time complexity of O(n^2).
You have many unused variables and variables that should be in a more specific scope.
Solutions:
Use std::vector insted of VLAs.
Resize the vector after initializing N.
Change your approach.
Change the scope of your variables.
Additional information:
using namespace std; is considered a bad practice (More info here).
You should probably add input checking to std::cin to verify that the input is a number.
Full code:
Checking duplicates once at the end of input with std::vector (Time complexity: O(n * log(n)). Space complexity: O(n)):
#include <iostream>
#include <vector>
#include <algorithm>
bool hasDuplicates(std::vector<int> toCheck)
{
std::sort(toCheck.begin(),toCheck.end());
for(unsigned int i = 1; i < toCheck.size(); i++)
if(toCheck[i] == toCheck[i-1])
return true;
return false;
}
int main () {
std::vector<int> arr;
int N;
while (true) {
std::cout << "Enter the number of integers to be entered: ";
std::cin >> N;
if (N <= 4) {
std::cout << "Invalid: The number of integers to be entered must be bigger than 4. \n";
}
else {
arr.resize(N);
std::cout << "\n\nEnter " << N << " unique numbers: " ;
for (int i = 0; i < N; i++)
std::cin >> arr [i];
if(hasDuplicates(arr))
std::cout << "Invalid: The numbers must be unique. \n";
else
break;
}
}
}
Checking duplicates each time a number is entered with std::unordered_map (Time complexity: Amortized O(n). Space complexity: O(n)):
#include <iostream>
#include <vector>
#include <unordered_set>
int main () {
std::vector<int> arr;
std::unordered_set<int> alreadyAppeared;
int N;
std::cout << "Enter the number of integers to be entered: ";
std::cin >> N;
while (N <= 4) {
std::cout << "Invalid: The number of integers to be entered must be bigger than 4. \n";
std::cout << "Enter the number of integers to be entered: ";
std::cin >> N;
}
arr.resize(N);
std::cout << "\n\nEnter " << N << " unique numbers: \n";
for (int i = 0; i < N; i++)
{
int entering;
std::cout << "Enter unique number: ";
std::cin >> entering;
if(alreadyAppeared.find(entering) == alreadyAppeared.end())
{
alreadyAppeared.insert(entering);
arr[i] = entering;
}
else
{
std::cout << "Invalid: The numbers must be unique. \n";
i--;
}
}
}

Related

How can i prohibit duplicate input values on a 2D array?

Here is my code and I want to restrict reoccurring values when the user is trying to input the same value. It would be best if everything is only at the main function because i'm still learning about declaring more functions.
`
#include <iostream>
using namespace std;
int main() {
int num[10][10];
int times;
cout << "Please input the number of times you wish to enter a value but does not exceed to 100: ";
cin >> times;
cout << "Enter a value " << times * times << " times." << endl;
for(int i = 0; i < times; i++) {
for(int k = 0; k < times; k++) {
cout << "Please input a number on index [" << i << "][" << k << "]: ";
cin >> num[i][k];
}
}
//Displaying the inputs
cout << "Printing all values inside the array: " << endl;
for(int i = 0; i < times; i++) {
cout << endl;
for(int k = 0; k < times; k++) {
cout << "\t" << num[i][k] << " ";
}
}
return 0;
}
`
This is my expected output to be when a user tries to input a duplicate value:
Please input a number on index [0][0]: 7
Please input a number on index [0][1]: 7
Value already entered. Please try again.
Please input a number on index [0][1]:
In this context, you could have a function like this:
bool doesExist(
const int array[][10], const size_t size, const int value, int x, int y)
{
for (size_t i = 0; i < size; i++)
for (size_t j = 0; j < size; j++) {
if (x == i && y == j)
continue; // Skip the new element.
// If duplicate found
if (value == array[i][j])
return true;
}
return false;
}
It takes the array, its size, the value to be compared, and the position of the unique element inserted for the first time as arguments.
You could implement it this way:
cin >> num[i][k];
if (doesExist(num, times, num[i][k], i, k)) {
cout << "Already exists.\n";
...
}
This is not the best approach to this problem. In C++, it is recommended to apply STL containers as they provide more safety and iterators.
You just want the use not to enter duplicate values :-
First very basic you can just check all the previous values,
if it matches with the current one then you can tell the user to change the value.
You can use unordered_map, as map is (key,value) pair whenever you insert any value in map just set its corresponding value to 1, and then you can check in your map if thats value is already present in map or not if its present then you can tell the user to change, in map it will be easy to search.(code is simple)

How can I make my function only accept odd numbers into my array, and reject even numbers? C++

Let me preface this by saying I am fairly new to functions and arrays.
I have to make 3 functions: Function1 will be user input, Function2 will determine even/odd numbers, and Function3 will display the contents. I have Function1 and Function3 complete, and will post below, but I'm having a difficult time with Function2. What I have now will give the user an error message if they enter an even number, but it's messed up, and I just can't seem to figure out.
#include <iostream>
#include <iomanip>
#include <string>
using namespace std;
void getUsrInput(int num[], int size) //function for user input (function 1 of 3)
{
int n;
for (int i = 0; i < size; i++)
{
cout << "Enter five odd numbers: ";
cin >> n;
num[i] = n;
if (num[i] % 2 != 0) //if the number is odd then store it, if it is even: //function for even or odd (function 2 of 3 *doesn't work)
{
i++;
}
else
{
cout << "Invalid input. Please only enter odd numbers!" << endl; //let the user know to enter only odd numbers.
}
}
}
int main()
{
const int size = 5; //array size is 5 numbers
int num[size];
getUsrInput(num, size);
cout << "D I S P L A Y - PART C/B" << endl;
cout << "========================" << endl;
for (int i = 0; i < size; i++)
{
cout << num[i] << endl; //function for display (function 3 of 3)
}
}
for (int i = 0; i < size; i++)
increments i each time through the loop.
if (num[i] % 2 != 0) {
i++;
}
increments i each time the number is odd. So each time the user inputs an odd number, i gets incremented twice. Change the loop control to
for (int i = 0; i < size; }
so that i only gets incremented on valid input.
It' perfect for a while loop and you only count up if the insert is ok:
void getUsrInput(int num[], int size) //function for user input (function 1 of 3)
{
int n, i=0;
while( i < size )
{
cout << "Enter five odd numbers: ";
cin >> n;
if (n % 2 == 0)
cout << "Invalid input. Please only enter odd numbers!" << endl;
else
num[i++] = n; // ok then store and count up
}
}

I got infinite loop while practicing array in C++ to find reversed number

Hye, Im a beginner trying to learn C++ language. This is my code that I tried to find reverse input numbers using array. Can help me point my mistakes since I always got infinite loop.
#include <iostream>
#include <iomanip>
using namespace std;
int main()
{
const int ARRAY_SIZE=50;
int size[ARRAY_SIZE];
unsigned short int i;
cout << "You may enter up to 50 integers:\n";
cout << "\nHow many would you like to enter? ";
cin >> size[ARRAY_SIZE];
cout << "Enter your number: \n";
for (int i = 0; i < ARRAY_SIZE; i++)
{
cin >> size[i];
}
cout << "\nYour numbers reversed are:\n";
for (i = size[ARRAY_SIZE] - 1; i >= 0; i++)
cout << " size[i]" << " ";
}
Your infinite loop is because i is unsigned, so i >= 0 is always true.
Here's a C++-ified version:
#include <iostream>
#include <vector>
int main() {
std::cout << "You may enter up to 50 integers:\n";
std::cout << "\nHow many would you like to enter? ";
int count;
std::cin >> count;
// Use a std::vector which can be extended easily
std::vector<int> numbers;
for (int i = 0; i < count; ++i) {
std::cout << "Enter your number: \n";
int v;
std::cin >> v;
// Add this number to the list
numbers.push_back(v);
}
std::cout << "\nYour numbers reversed are:\n";
// Use a reverse iterator to iterate through the list backwards
for (auto i = numbers.rbegin(); i != numbers.rend(); ++i) {
// An iterator needs to be de-referenced with * to yield the value
std::cout << *i << " ";
}
std::cout << std::endl;
return 0;
}
There's many problems in your original code, but the clincher is this:
for (i = size[ARRAY_SIZE] - 1; i >= 0; i++)
cout << " size[i]" << " ";
}
Since you keep adding to i through each cycle you'll never go below zero, especially not for an unsigned short int. This should be:
for (int i = count - 1; i > 0; --i) {
std::cout << numbers[i];
}
Presuming you have a thing called numbers instead of the bizarrely named size and the array size is count, not i, as i is generally reserved for iterators and loop indexes.

sort and show the number of digits

I want to my program can sort the inputted integer and compute the number of any integer that inputted and I don't know where should write the cout of c
example
a[9]={2,3,2,6,6,3,5,2,2}
the number of 2 is 4
the number of 3 is 2
the number of 6 is 2
.
.
please fix this code
int main()
{
cout << "please enter the number of digites :" << endl;
int n;
cin>>n;
int a[n];
cout<<"enter numbers :"<<endl;
for(int i=0;i<n;i++)
cin>>a[i];
int i,j;
for(i=0;i<n-1;i++)
{
for(j=0;j<n-i-1;j++)
if(a[j]>a[j+1])
{
int temp;
temp=a[j+1];
a[j+1]=a[j];
a[j]=temp;
}
}
int c;
for(int m=0;m<n;m++)
{
if(a[m]==a[m+1])
c++;
else
c=0;
}
return 0;
}
Read through my solution, I've commented the parts I've changed. I tidied it up a little.
To answer your question: you should print the output (frequency of an integer in array) before you reset the count variable to 1. This will work because we have sorted the array, and will not have to look ahead for more occurrences of the current number.
[EDIT] I also added this above your code:
#include <iostream>
#include <vector>
using namspace std;
Full Solution
#include <iostream>
#include <vector>
using namespace std;
int main() {
// Get input
int n;
cout << "Please enter the number of digits: ";
cin>>n;
vector<int> a;
cout << "Enter " << n << " numbers: " << endl;
for(int i=0;i<n;i++) {
int temp;
cin >> temp;
a.push_back(temp);
}
// Sort input
int i,j;
for (i = 0; i < a.size(); i++) {
for(j = 0; j < a.size()-i-1; j++) {
if(a[j] > a[j+1]) {
int temp;
temp=a[j+1];
a[j+1]=a[j];
a[j]=temp;
}
}
}
// If an element is in an array
// we can not have 0 occurrences
// of that element, hence count
// must start at 1
int count = 1;
// Int to count
int current = a[0];
// Ouput if we have reset the count,
// or if it is the last iteration
bool output;
// Loop through array
for (int i = 1; i < a.size(); i++) {
output = false; // Reset output if we have printed
if (a[i] == current) {
// If current int and the element next to it are the same,
// increase the count
count++;
} else {
// If current and next are different,
// we need to show the frequency,
// and then reset count to 1
cout << current << " occurs " << count << " times" << endl;
count = 1;
current = a[i];
}
}
// Output one last time, for last int in sorted set
cout << current << " occurs " << count << " times" << endl;
return 0;
}
If this doesn't help, go and read this page, it is a solution in C, but can be adapted to C++ easily. https://codeforwin.org/2015/07/c-program-to-find-frequency-of-each-element-in-array.html This will help you understand and write the task. They take you step-by-step through the algorithm.
This is a typical use-case for a std::map. A std::map<char,int> lets you easily count the frequency of charaters (its easier to treat the user input as characters instead of converting it to numbers).
This is basically all you need:
#include <iostream>
#include <iterator>
#include <map>
int main(){
std::istream_iterator<char> it( std::cin );
std::istream_iterator<char> end_of_input;
std::map<char,int> data;
while (it != end_of_input ) data[*(it++)]++;
for (const auto& e : data) std::cout << e.first << " " << e.second << "\n";
}
This is probably a lot at once, so lets go one by one.
std::istream_iterator<char> lets you extract characters from a stream as if you are iterating a container. So the while iteratates std::cin until it reaches the end of the input. Then *(it++) increments the iterator and returns the character extracted from the stream. data[x]++ accesses the value in the map for the key x and increments its value. If there is no value in the map yet for the key, it gets default initialized to 0.
For input: 11223 it prints
1 2
2 2
3 1
Your code has some issues, not sure if I can catch them all...
You are using VLA (variable lenght arrays) here: int a[n];. This is a compiler extension and not standard c++.
You access the array out of bounds. When i == 0 then j goes up to j<n-i-1 == n-1 and then you access a[j+1] == a[n], but the last valid index into the array is n-1. Same problem in the other loop (a[m+1]).
Assuming your sorting works, the last loop almost gives you the number of elements, but not quite, to fix it you can change it to...
int current = a[0];
int counter = 1;
for(int m=1;m<n;m++) {
if(a[m] == current) {
counter++;
} else {
std::cout << current << " appears " << counter << " times" << endl;
counter=1; // note: minimum freq is 1 not 0
current = a[m];
}
}

Print number of matching sequence in the user given input for the constant input

I wrote a code to get the number of sequences occurring in the user input sequence.
This is my code. It excludes the subsequence which I wish to be tested.
I need to consider 12,23,34,123,234,1234 as sequences.
Overlapping of sequences should not be considered (12 in 123 should not be considered).
For e.g. constant number 1234
User given number 124312341211423
Output : No.of Sequence found 4
#include<iostream>
#include<string>
#include<cstring>
using namespace std;
int main()
{
string num1;
string seq;
cout << "Enter constant number: ";
cin >> num1;
cout << "Enter the sequence: ";
cin >> seq;
int count=0;
for (int t=0; t<=num1.size()-2; t++)
{
string num = num1;
for (int k = num1.size(); k>=2-t ;k--)
{
cout << num <<"\n";
if (t==2 && k<=2)
break;
//num=num.substr(t,t+k-1);
for (int j = 1; seq.find(num) != string::npos; j++)
{
seq = seq.substr(0,seq.find(num)) + " " + seq.substr(seq.find(num)+num.size());
count = count + 1;
}
num = num.substr(t,t+k-1);
}
cout<< seq << "\n";
}
cout << "No. of sequences found: " << count << "\n";
return 0;
}
Hi I tried running your code and I got it outputting 5 sequences found. I'm assuming your request is to figure out why it's not 4.
I'll make a couple recommendations:
The logic of your for-loops and forming num should be adjusted to test all substrings of num1 such that each substring is at least 2 characters in length.
Change your most-interior for-loop into a while loop, because your iterator j really isn't doing anything.
Call string::find() once per iteration of your most-interior loop. String::find() is expensive and you call it three times without changing the arguments.
Pull the declaration of num out of the for-loop so it's only declared once.
Here is the result of these recommendations in effect:
You'll notice I added a variable numStart to save the location of the beginning of num in seq, thus allowing recommendation #3 to be done.
I also moved cout << seq << "\n" into the most-interior loop so you can see the state of seq every time a sequence is found.
int main() {
string num1;
string num;
string seq;
cout << "Enter constant number: ";
cin >> num1;
cout << "Enter the sequence: ";
cin >> seq;
int count=0;
for (int t=0; t<=num1.size(); t++) {
for (int k = num1.size(); k>t+1; k--) {
num = num1.substr(t, k-t);
size_t numStart = seq.find(num);
while (numStart != string::npos) {
seq = seq.substr(0, numStart) + " " + seq.substr(numStart + num.size());
count++;
numStart = seq.find(num);
cout << seq << "\n";
}
}
}
cout << "No. of sequences found: " << count << "\n";
return 0;
}
I hope this helps!