How to check if 3 elements of array have the same value - c++

I am trying to write a program which checks if 3 (or more) elements of an array are the same.
I have written a code which works almost perfectly, but it gets stuck when there are 3 pairs of equal elements and I'm not sure how to fix it.
#include <iostream>
#include <algorithm>
using namespace std;
int main() {
int n, a[10],skirt=0;
cin >> n;
for(int i = 0; i < n; i++)
{
cin >> a[i];
}
for(int i = 0; i < n; i++)
{
for(int j = i + 1; j < n; j++)
{
if(a[i] == a[j])
{
skirt++;
}
}
}
cout<<skirt<<endl;
if(skirt>=3)
{
cout << "TAIP" << endl;
}
else
{
cout << "NE" << endl;
}
}
When I input
6
3 3 2 2 1 1 i
get "TAIP" but I need to get "NE".

You can use the following algorithm: first sort the array. Then iterate each adjacent pair. If they are equal, then increment counter, if not then reset counter to 1. If counter is 3, return true. If loop does not return true, then return false.

Add the following condition in the outer for loop
for(int i = 0; i < n - 2 && skirt != 3; i++)
^^^^^^^^^^^^^^^^^^^^^^^
{
skirt = 1;
^^^^^^^^^
for(int j = i + 1; j < n; j++)
{
if(a[i] == a[j])
{
skirt++;
}
}
}
Of course before the loop you should check whether n is not less than 3. For example
if ( not ( n < 3 ) )
{
for(int i = 0; i < n - 2 && skirt != 3; i++)
{
skirt = 1;
for(int j = i + 1; j < n; j++)
{
if(a[i] == a[j])
{
skirt++;
}
}
}
}
Here is a demonstrative program
#include <iostream>
using namespace std;
int main()
{
int a[] = { 6, 3, 3, 2, 2, 1, 1 };
int n = 7;
int skirt = 0;
if ( not ( n < 3 ) )
{
for(int i = 0; i < n - 2 && skirt != 3; i++)
{
skirt = 1;
for(int j = i + 1; j < n; j++)
{
if ( a[i] == a[j] )
{
skirt++;
}
}
}
}
cout << skirt << endl;
if ( skirt == 3 )
{
cout << "TAIP" << endl;
}
else
{
cout << "NE" << endl;
}
return 0;
}
Its output is
1
NE
because the array does not have 3 equal elements.

Reset skirt to 0 every time you increase i if it is less than 3, or break out the loop otherwise.

Another way to do this is using a std::map, which keeps a count of the number of times a given value occurs in your array. You would stop looking as soon as you have a number that has three occurrences.
Here's a 'minimalist' code version:
#include <iostream>
#include <map>
using std::cin; // Many folks (especially here on SO) don't like using the all-embracing
using std::cout; // ... statement, "using namespace std;". So, these 3 lines only 'use'
using std::endl; // ... what you actually need to!
int main() {
int n, a[10], skirt = 0;
std::map<int, int> gots;
cin >> n;
for (int i = 0; i < n; i++) {
cin >> a[i];
}
for (int i = 0; i < n && skirt < 3; i++) {
skirt = 1;
if (gots.find(a[i]) != gots.end()) skirt = gots[a[i]] + 1;
gots.insert_or_assign(a[i], skirt);
}
cout << (skirt >= 3 ? "TAIP" : "NE") << endl;
return 0;
}
I'm not saying this is any better (or worse) than the other answers - just another way of approaching the problem, and making use of what the Standard Library has to offer. Also, with this approach, you could easily modify the code to count how many numbers occur three or more times, or any number of time.
Feel free to ask for further clarification and/or explanation.

Related

print duplicate elements in array

I want to find duplicate elements in a dynamic array. In most cases it works, but how can it work for this case. I'm finding duplicate elements in a given array. But there is one problem that my duplicate elements can repeat too. How can I solve that part.
#include <iostream>
int main() {
unsigned n;
std::cin >> n;
int count = 0;
int* dynArr = new int[n];
for (int i = 0; i < n; i++) {
std::cin >> dynArr[i];
}
for(int i = 0; i < n; i++){
for(int j = i + 1; j < n; j++){
if(dynArr[j] == dynArr[i]){
std::cout<<dynArr[j]<<" ";
break;
}
}
}
}
I have a problem with this part. When I'm inputting a my array length 6, and elements {1,1,2,1,2,2}.
I got (1,1,2,2).
But I need to get only 1,2.
input 6
1 1 2 1 2 2
output 1 1 2 2
but must be
output 1 2
Here's a simple and fast solution.
std::map<int,size_t> element_count;
for(int i = 0; i < n; i++){
if ( ++element_count[dynArr[i]] == 2 ){
// Only report on the second occurrance
std::cout<<dynArr[j]<<" ";
}
}
const int listSize = 5;
int list1[listSize] = {0,0,1,1,3};
bool dupList[listSize] = {false};
for (int index = 0; index < listSize; index++) {
int val = list1[index];
for (int i = 0; i < listSize; i++) {
if (i != index) {
if (list1[i] == val) {
dupList[index] = true;
}
}
}
}
int printList[listSize];
int addNum = 0;
for (int index = 0; index < listSize; index++) {
if (dupList[index] == true) {
bool run = true;
int print = list1[index];
for (int i = 0; i < listSize; i++) {
if (printList[i] == print) {
run = false;
}
}
if (run == true) {
std::cout << print << " ";
printList[addNum] = print;
addNum++;
}
}
}
Note this code will NOT run quickly at all only use it if the operation does not need to get run very many times but it will only display the single numbers that are duplicates. It will defernatly need to get optimised more
You can simply get it done using two std::set<int>s.
#include <set>
#include <iostream>
int main() {
unsigned n;
std::cin >> n;
int count = 0;
std::set<int> all;
std::set<int> redundant;
for (int i = 0; i < n; i++) {
int input = 0;
std::cin >> input;
// You cant enter the entry because its present. This will return a std::pair<,> with the second value false.
if (!all.insert(input).second)
redundant.insert(input); // We store this in another set so we dont duplicate the redundant entries.
}
for (auto itr = redundant.begin(); itr != redundant.end(); itr++)
std::cout << *itr << " ";
}

Push to vector only one element, without repeating

I have a code where i should introduce 3 numbers and an multi-dimensional array. I should print all numbers from array that are divisors with 3 numbers from start..
Here's my code:
#include <vector>
#include <iostream>
using namespace std;
int main() {
int r, p, k, nr, n, m, counter=0, temp;
vector <int> numbers;
cout << "Enter value of r, p, k: ";
cin >> r >> p >> k;
cout << "Enter the number of rows and columns: ";
cin >> n >> m;
int T[n][m];
cout << "Enter values: ";
for(int i = 0; i < n; i++) {
for(int j = 0; j < m; j++) {
cin >> T[i][j];
}
}
for(int i = 0; i < n; i++) {
for(int j = 0; j < m; j++) {
for(int a = 0; a < 1; a++) {
numbers.push_back(T[i][j]);
counter++;
}
}
}
for(int f = 0; f < counter; f++) {
if(r%numbers[f]==0 && p%numbers[f]==0 && k%numbers[f]==0) {
cout << numbers[f] << ' ';
}
}
return 0;
}
So, my question is.. how to push in vector numbers that repeats only 1 time.. I mean if in array are 2 the same number, dont print both of them but just one of them.
Thanks in advance.
Use a set: http://en.cppreference.com/w/cpp/container/set
A set does not allow duplicates. For example, if you insert the number 5 more than once, there will still only be one 5 in the set.
First #include<set>.
Then replace vector <int> numbers; with set<int> numbers;
Then replace
for(int i = 0; i < n; i++) {
for(int j = 0; j < m; j++) {
for(int a = 0; a < 1; a++) {
numbers.push_back(T[i][j]);
counter++;
}
}
}
with
for(int i = 0; i < n; i++)
for(int j = 0; j < m; j++)
numbers.insert(T[i][j]);
Then replace
for(int f = 0; f < counter; f++) {
if(r%numbers[f]==0 && p%numbers[f]==0 && k%numbers[f]==0) {
cout << numbers[f] << ' ';
}
}
with
for (auto i = numbers.cbegin(); i != numbers.cend(); ++i)
if(r % *i == 0 && p % *i == 0 && k % *i == 0)
cout << *i << ' ';
That should do it. You can eliminate the counter variable from the program because numbers.size() gives you the number of objects in the set. Also, your temp variable is not used, so eliminate that as well. Also, note that set is an ordered container, so printing it like this will print the numbers in ascending order.
(Also note that the length of an array such as int arr[3]; must be known at compile time to be strictly valid C++. Here 3 is a literal and so is known at compile time. Asking the user to input the length of the array means that it is not known at compile time.)
After you fill your vector, you can first sort all elements in it and than call std::unique, to remove all duplicates from it.
Try to look references for std::unique and std::sort

This Code is giving the wrong output can't figure out where I made a mistake

The code should display the number of times maximum number in the array has occurred so for the following input (3,2,1,3) the output should be '2' as '3' is the maximum number and occurs twice. I wanted to use functions, I know there is an easier way to solve it but i just want to know the problem in my code:-
#include<iostream>
using namespace std;
int frequency(int n, int a[]) {
int j=0,max,count=0;
max = a[j];
while(j<n){
if(a[j+1]> max){
max = a[j+1];
}
j++;
}
int seen[n];
for(int i = 0; i < n; i++)
seen[i] = 0;
for(int i = 0; i < n;i++) {
if(seen[i] == 0) {
int count = 0;
for(int j = i; j < n;j++)
if(a[j] == a[i] && a[j] == max)
count += 1;
seen[j] = 1;
}
}
return count;
}
int main() {
int i,n;
cin >> n;
int a[n];
for(i = 0; i < n; i++){
cin >> a[i];
}
int result = frequency(n, a);
cout << result << endl;
return 0;
}
For starters the C++ Standard does not support Variable Length Arrays. So instead of an array you should use some container as for example std::vector<int>.
Moreover the program has undefined behavior because at least in this loop
while(j<n){
if(a[j+1]> max){
max = a[j+1];
}
j++;
}
there is an attempt to access memory beyond the array in the expression a[j+1].
And at last the function always returns 0 because the variable count in the outermost scope of the function is set to zero and is never changed.
A general approach can be written using iterators.
For example
#include <iostream>
#include <iterator>
#include <vector>
template <typename InputIterator>
size_t count_maximum_value( InputIterator first, InputIterator last )
{
size_t count = 0;
if ( first != last )
{
++count;
typename std::iterator_traits<InputIterator>::value_type max = *first;
while ( ++first != last )
{
if ( max < *first )
{
max = *first;
count = 1;
}
else if ( not ( *first < max ) )
{
++count;
}
}
}
return count;
}
int main()
{
size_t n = 0;
std::cout << "Enter the number of integers: ";
std::cin >> n;
if ( n )
{
std::vector<int> v( n );
std::cout << "Enter " << n << " integers: ";
for ( size_t i = 0; i < n; i++ ) std::cin >> v[i];
std::cout << "The maximum value is encountered "
<< count_maximum_value( v.begin(), v.end() )
<< " time(s)"
<< std::endl;
}
return 0;
}
The program output might look the following way
Enter the number of integers: 4
Enter 4 integers: 3 2 1 3
The maximum value is encountered 2 time(s)
You are comparing a[j+1] with max. I suggest you use a[j]. You seem to be skipping the first number in your input.
Start with count = 1 instead of count = 0 and delete the redeclaration of count in the loop.
You're starting with 0, then you add 1 when you find the second entry that matches it. That's why you're off by one.
Check the comments
#include<iostream>
using namespace std;
int frequency(int n, int a[]) {
int j=0,max,count=0;
max = a[j];
while(j<n){
if(a[j]> max){ // 1. j+1 crosses lenth of array
max = a[j];
}
j++;
}
int seen[n];
for(int i = 0; i < n; i++)
seen[i] = 0;
for(int i = 0; i < n;i++) {
if(seen[i] == 0) {
//int count = 0; //2. re declaration and you are not returning this
//for(int j = i; j < n;j++) //3. No need of extra loop it make count extra because you are starting at j=i
//if(a[j] == a[i] && a[j] == max)
if(a[i] == max)
count += 1;
seen[j] = 1;
}
}
return count;
}
int main() {
int i,n;
cin >> n;
int a[n];
for(i = 0; i < n; i++){
cin >> a[i];
}
int result = frequency(n, a);
cout << result << endl;
return 0;
}

Incorrect Result from Selection Sort Algorithm

#include <iostream>
using namespace std;
// Selection Sort function.
// Parameter 'a' is the size of the array.
void ss(int AR[] , int a) {
int small;
for (int i = 0 ; i <a ; i++) {
small = AR[i];
for (int j = i+1 ; j <a ; j++) {
if (AR[j]< small) {
int k = AR[j];
AR[j] = AR[i];
AR[i] = k;
}
}
}
}
int main() {
cout << "Enter the size of Your Aray";
int a;
cin >> a;
int AR[a];
cout << endl;
for (int i = 0; i < a; i++) {
cin >> AR[i];
cout << endl;
}
ss(AR, a);
cout << "The Sorted Array is";
for (int i=0; i < a; i++) {
cout << AR[i] << " ";
cout << endl;
}
}
When I enter the following:
15
6
13
22
23
52
2
The result returned is:
2
13
6
15
22
23
52
What is the bug preventing the list from being sorted numerically as expected?
The function can look like
void ss ( int a[], size_t n )
{
for ( size_t i = 0 ; i < n ; i++ )
{
size _t small = i;
for ( size_t j = i + 1; j < n ; j++ )
{
if ( a[j] < a[small] ) small = j;
}
if ( i != small )
{
int tmp = a[small];
a[small] = a[i];
a[i] = tmp;
}
}
}
It doesn't seem to be the SelectionSort I know. in the algorithm I know during every loop I look for the smallest element in the right subarray and than exchange it with the "pivot" element of the loop. Here's the algorithm
void selectionSort(int* a, int dim)
{
int posMin , aux;
for(int i = 0; i < dim - 1; ++i)
{
posMin = i;
for(int j = i + 1; j < dim; ++j)
{
if(a[j] < a[posMin])
posMin = j;
}
aux = a[i];
a[i] = a[posMin];
a[posMin] = aux;
}
}
and it seems that you change every smaller element you find, but also change the position of the "pivot". I hope the answer is clear.
Everything is ok in the original function, only that the small variable need to be refreshed when two vector elements will be switched.
Also in if statement set the small variable to the new value of AR[i].

Piece of code doesn't give the answer I need. Suggested edits?

This code is supposed to check the input array for five consecutive '1's if found, it is supposed to add a '0' at the end as a parity bit for a simple parity bit checker.
This is the code.
#include <conio.h>
#include <stdio.h>
#include <iostream>
using namespace std;
int main() {
int n, a[30], b[5] = {1, 1, 1, 1, 1}, temp = 0, count = 0;
cout << "Enter the size of input bits :";
cin >> n;
cout << endl;
cout << "Enter the input bits :";
for (int i = 0; i < n; i++) {
cin >> a[i];
}
for (int i = n; i >= 0; i--) {
if (i >= 4) {
temp = i;
for (int j = 0; j < 5; j++) {
if (a[temp] == b[j]) {
temp++;
count++;
}
}
}
}
if (count == 4) {
n = n + 1;
a[n] = 0;
}
cout << endl << endl;
for (int i = 0; i < n; i++) {
cout << a[i];
}
getch();
return 0;
}
Here is a simple logic of what you want to achieve.. let's say input array is a, it's length is n:
int counter = 0;
for(int i=0; i<n; i++) {
if(a[i] == 1)
counter++;
else
counter = 0; //need to start looking for 1's again because consecutive stream is broken
if(counter == 5) {
a[i+1] = 0; //found 5 consecutive 1's so next bit will be 0
i++; //don't need to check the next bit which is already 0
counter = 0; //resetting counter
}
}
The above code will change the array [2,3,1,1,1,1,1,3,4,5] to -> [2,3,1,1,1,1,1,0,4,5]
If you want to insert 0 at the end of the array then simply change a[i+1] = 0 to a[n+1] = 0 and remove i++;
You also need to make sure that n is not greater than the size of array.
I'll go line by line from the beginning:
change for(int i=n; i>=0; i--) to for (int i = n-1; i >= 0; i--) (n-sized array in C++ has cells in the range of [0, n-1])
change if(i>=4) to if (n >= 5)
place temp++ after if(a[temp]==b[j]){}, not inside of it.
add
if (count == 5) break;
else count = 0;
just after for(int j = 0; j < 5; j++) loop
change
if(count==4)
{
n=n+1;
a[n]=0;
}
to
if(count == 5){
a[n] = 0;
n = n+1;
}
Once again! n-sized array holds n elements on positions 0 to n-1
Of course sequence makes a difference above!
You can also write it as if (count == 5) a[n++] = 0;
And that would be all.