printing stack in the incorrect order in c++ - c++

I have a function that pushes down all non zero integers to the top of my array and then reprints it in a 3x3 matrix.
the problem i am having is when i push all the non zero integers into my stack it reverses the order.
** the indexing of my array is backwards. ie, in a 3x3 matrix the coordinates (0,0) would be the bottom left **
here is the relevant code:
void State::pushDown() {
std::stack<int> tempStack;
for ( int c = 0; c < BOARDSIZE; c++ )
{
for ( int r = 0; r < BOARDSIZE ; r++ )
{
if ( grid[r][c] != 0 ) tempStack.push( grid[r][c] );
}
for ( int r = BOARDSIZE; r != 0; --r )
{
if ( !tempStack.empty() )
{
grid[r-1][c] = tempStack.top();
tempStack.pop();
}
else
{
grid[r-1][c] = 0;
}
}
}
}
State() {
for (int i = 0; i < BOARDSIZE; i++)
for (int j = 0; j < BOARDSIZE; j++)
grid[i][j] = rand() % 7;
}
void State::printBoard() {
cout << endl;
for (int i = 0; i < BOARDSIZE; i++) {
for (int j = 0; j < BOARDSIZE; j++) {
cout << " " << grid[BOARDSIZE - i - 1][j] << " ";
}
cout << endl;
}
}
int main() {
srand(time(0));
State state;
state.printBoard();
state.pushDown();
state.printBoard();
return 0;
}
here is my current output:
before push down function
045
504
226
after push down function:
006
224
545
as you can see it successfully pushes the non zero elements to the bottom of the matrix however in the process it reverses the order of the other numbers and i believe this is because of the stack.
my expected output would be the following:
before push down function
045
504
226
after push down function:
005
544
226
My question is- how can i fix my function so that the order of the elements remain the same without reversing.

Here is a demonstrative program that shows how the loops can be defined.
#include <iostream>
#include <stack>
const int BOARDSIZE = 3;
void reformat( int ( &a )[BOARDSIZE][BOARDSIZE] )
{
std::stack<int> tempStack;
for ( int c = 0; c < BOARDSIZE; c++ )
{
for ( int r = 0; r < BOARDSIZE ; r++ )
{
if ( a[r][c] != 0 ) tempStack.push( a[r][c] );
}
for ( int r = BOARDSIZE; r != 0; --r )
{
if ( !tempStack.empty() )
{
a[r-1][c] = tempStack.top();
tempStack.pop();
}
else
{
a[r-1][c] = 0;
}
}
}
}
int main()
{
int a[BOARDSIZE][BOARDSIZE] =
{
{ 0, 4, 5 },
{ 5, 0, 4 },
{ 2, 2, 6 }
};
for ( const auto &row : a )
{
for ( const auto &item : row ) std::cout << item << ' ';
std::cout << '\n';
}
std::cout << '\n';
reformat( a );
for ( const auto &row : a )
{
for ( const auto &item : row ) std::cout << item << ' ';
std::cout << '\n';
}
std::cout << '\n';
return 0;
}
Its output is
0 4 5
5 0 4
2 2 6
0 0 5
5 4 4
2 2 6
If you are outputting the array starting from its last row then use the following loops
#include <iostream>
#include <stack>
const int BOARDSIZE = 3;
void reformat( int ( &a )[BOARDSIZE][BOARDSIZE] )
{
std::stack<int> tempStack;
for ( int c = 0; c < BOARDSIZE; c++ )
{
for ( int r = 0; r < BOARDSIZE ; r++ )
{
if ( a[BOARDSIZE-r-1][c] != 0 ) tempStack.push( a[BOARDSIZE-r-1][c] );
}
for ( int r = 0; r != BOARDSIZE; ++r )
{
if ( !tempStack.empty() )
{
a[r][c] = tempStack.top();
tempStack.pop();
}
else
{
a[r][c] = 0;
}
}
}
}
int main()
{
int a[BOARDSIZE][BOARDSIZE] =
{
{ 2, 2, 6 },
{ 5, 0, 4 },
{ 0, 4, 5 }
};
for ( size_t i = 0; i < BOARDSIZE; i++ )
{
for ( const auto &item : a[BOARDSIZE - i - 1] ) std::cout << item << ' ';
std::cout << '\n';
}
std::cout << '\n';
reformat( a );
for ( size_t i = 0; i < BOARDSIZE; i++ )
{
for ( const auto &item : a[BOARDSIZE - i - 1] ) std::cout << item << ' ';
std::cout << '\n';
}
std::cout << '\n';
return 0;
}
The program output is the same as shown above
0 4 5
5 0 4
2 2 6
0 0 5
5 4 4
2 2 6
But now the array is outputted starting from its last line.

Related

Find similar numbers - array inconsistency

I'm trying to solve a simple beginner exercise, I compare two arrays and find the numbers that appear in both. The result is put into another array called result. For whatever reason the result should contain "2 44 55" but it shows "2 1 10 10". What did I do wrong?
#include <iostream>
void common_elements(int array_1[], int array_2[]){
int result[] {0};
int counter{0};
for (int i{0}; i < 10; i++){
for (int j{0}; j < 10; j++){
if (array_2[i] == array_1[j]){
result[counter] = array_1[j];
counter++;
}
}
}
if (counter == 0) {
std::cout << "There are 0 common elements";
} else {
std::cout << "There are " << counter << " common elements they are : ";
for (int k{0}; k < counter; k++){
std::cout << result[k] << " ";
}
}
}
int main(){
int data1[] {1,2,4,5,9,3,6,7,44,55};
int data2[] {11,2,44,45,49,43,46,47,55,88};
common_elements(data1,data2);
return 0;
}
I'm confused because when I std::cout the numbers during examination (two nested loops), the result is correct.
It is just containing one single element, because the compiler deduces the length to 1. This would mean the 2 is valid, all other values are "out of bound". Thanks for your help. I repaired it to
int result[10]{0};
Now it's working, thanks a lot.
Btw: It is a C++ course but it starts from the very beginning. That why this looks like C.
For starters the function should be declared at least like
std::vector<int> common_elements( const int array_1[], size_t n1,
const int array_2[], size_t n2 );
Using the magic number 10 within the function as
for (int i{0}; i < 10; i++){
does not make sense. The function can be called for arrays that have different numbers of elements.
This declaration of an array
int result[] {0};
declares an array with only one element that also does not make sense.
Also the function should not output any message. It is the caller of the function that decides whether to output a message. The function should return a sequence of common elements of two arrays.
The function can be defined the following way
#include <vector>
#include <iterator>
#include <functional>
//...
std::vector<int> common_elements( const int array_1[], size_t n1,
const int array_2[], size_t n2 )
{
std::vector<int> v;
if ( n1 != 0 && n2 != 0 )
{
if ( n2 < n1 )
{
std::swap( n1, n2 );
std::swap( array_1, array_2 );
}
for ( size_t i = 0; i < n1; i++ )
{
size_t count = 1;
for ( size_t j = 0; j < i; j++ )
{
if ( array_1[j] == array_1[i] ) ++count;
}
for ( size_t j = 0; count != 0 && j < n2; j++ )
{
if ( array_2[j] == array_1[i] )
{
--count;
}
}
if ( count == 0 ) v.push_back( array_1[i] );
}
}
return v;
}
And in main the function is called like
int data1[] {1,2,4,5,9,3,6,7,44,55};
int data2[] {11,2,44,45,49,43,46,47,55,88};
auto v = common_elements( data1, std::size( data1 ), data2, std::size( data2 ) );
if ( std::size( v ) == 0 )
{
std::cout << "There are 0 common elements";
}
else
{
std::cout << "There are " << std::size( v ) << " common elements they are : ";
for ( const auto &item : v )
{
std::cout << item << ' ';
}
std::cout << '\n';
}
Instead of the vector you could use std::map<intg, size_t>. In this case the container will contain how many times a common number is encountered in the both arrays.
Here is a demonstration program.
#include <iostream>
#include <vector>
#include <iterator>
#include <functional>
std::vector<int> common_elements( const int array_1[], size_t n1,
const int array_2[], size_t n2 )
{
std::vector<int> v;
if (n1 != 0 && n2 != 0)
{
if (n2 < n1)
{
std::swap( n1, n2 );
std::swap( array_1, array_2 );
}
for (size_t i = 0; i < n1; i++)
{
size_t count = 1;
for (size_t j = 0; j < i; j++)
{
if (array_1[j] == array_1[i]) ++count;
}
for (size_t j = 0; count != 0 && j < n2; j++)
{
if (array_2[j] == array_1[i])
{
--count;
}
}
if (count == 0) v.push_back( array_1[i] );
}
}
return v;
}
int main()
{
int data1[]{ 1,2,4,5,9,3,6,7,44,55 };
int data2[]{ 11,2,44,45,49,43,46,47,55,88 };
auto v = common_elements( data1, std::size( data1 ), data2, std::size( data2 ) );
if (std::size( v ) == 0)
{
std::cout << "There are 0 common elements";
}
else
{
std::cout << "There are " << std::size( v ) << " common elements they are : ";
for (const auto &item : v)
{
std::cout << item << ' ';
}
std::cout << '\n';
}
}
The program output is
There are 3 common elements they are : 2 44 55

Random matrix multiplication [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 5 months ago.
Improve this question
I need to create at least 2 matrix 4x4, multiplicate them and display the result, but I'm getting this thing as as result img
I'm creating matrix a[i][j] and matrix b[k][l], and trying to pass the result to a new matrix called c[i][j]
Besides that, I need to make 2 kinds of matrix multiplication, one like this, and another one like this
Can you please please please help? Code below
#include<iostream>
#include<stdlib.h>
#include<time.h>
using namespace std;
int matriz1() {
int a[4][4], i, j;
for (i = 0; i < 4; ++i)
{
for (j = 0; j < 4; ++j)
{
a[i][j] = rand() % 100 + 1;
}
}
for (i = 0; i < 4; ++i)
{
for (j = 0; j < 4; ++j)
std::cout << a[i][j] << '\t';
std::cout << '\n';
}
std::cout << '\n';
std::cout << "x" << std::endl;
std::cout << '\n';
std::cout << "Matriz 2:" << std::endl;
int b[4][4], k, l;
for (k = 0; k < 4; ++k)
{
for (l = 0; l < 4; ++l)
{
b[k][l] = rand() % 100 + 1;
}
}
for (k = 0; k < 4; ++k)
{
for (l = 0; l < 4; ++l)
std::cout << b[k][l] << '\t';
std::cout << '\n';
}
std::cout << '\n';
int c[4][4], m, n, x;
for (i = 0; i < 4; i++) {
for (j = 0; j < 4; j++) {
for (k = 0; k < 4; k++) {
c[i][j] += a[i][k] * b[k][j];
}
}
}
cout << " RESULTADO!!!!!!!!!!!!!!!!!!!!!!" << endl;
for (i = 0; i < 4; i++) {
for (j = 0; j < 4; j++) {
cout << c[i][j] << "\t";
}
cout << "\n";
}
return 0;
}
int main()
{
srand(time(0));
std::cout << "Matriz 1:" << std::endl;
std::cout << matriz1() << std::endl;
}
SOLVED IN THE COMMENTS! Stop disliking my post its my first post
You do this:
c[i][j] += a[i][k] * b[k][j];
but you never initialized c array, it contains random values, likely something like
0xCDCDCDCD (-842150451). Initialize it like this:
int c[4][4] = {}
You have repeated code, so consider to break it up in functions, e.g. you can initialize matrices as functions and output one as another. THat would make code more readable and easier to find errors.
A common "Beginner's Problem" is writing too much code. One consequence is that there are too many places where bugs and other flaws can hide.
This is in 'C', but the only 'C++' aspect of your code is using cout for output. printf() can also be used with C++.
#include <stdio.h>
#include <stdlib.h>
void fill4x4( int a[][4] ) {
for( int r = 0; r < 4; r++ )
for( int c = 0; c < 4; c++ )
a[r][c] = rand() % 100 + 1;
}
void show4x4( int a[][4] ) {
for( int r = 0; r < 4; r++ )
for( int c = 0; c < 4; c++ )
printf( "%5d%c", a[r][c], " \n"[c] );
puts( "" );
}
int showPair( int a, int b, int pos ) {
printf( "%2dx%-2d%c", a, b, " \n"[pos] );
return a * b;
}
void mult4x4( int a[][4], int b[][4], int d[][4], bool x ) {
for( int r = 0; r < 4; r++ )
for( int c = 0; c < 4; c++ )
// assign (=), not accumulate (+=)
// notice the 'exchange' of row/col access of 'b[][]'
if( x )
d[r][c] = showPair( a[r][c], b[r][c], c );
else
d[r][c] = showPair( a[r][c], b[c][r], c );
puts( "" ); show4x4( d );
}
int main()
{
srand(time(0));
int a[4][4]; fill4x4( a ); show4x4( a );
int b[4][4]; fill4x4( b ); show4x4( b );
int d[4][4];
mult4x4( a, b, d, true );
mult4x4( a, b, d, false );
return 0;
}
Copy, paste, compile and run this to see the (random) output.
EDIT: Pointed out by a question from the OP, here's a further compaction of one function that may-or-may-not be self-evident:
void mult4x4( int a[][4], int b[][4], int d[][4], bool x ) {
for( int r = 0; r < 4; r++ )
for( int c = 0; c < 4; c++ )
d[r][c] = showPair( a[r][c], x?b[r][c]:b[c][r], c );
puts( "" ); show4x4( d );
}
Further EDIT: A common problem for those with time to fill is mucking around, shrinking code that already works. Here's the result of some of that..
#include <stdio.h>
#include <stdlib.h>
char *fmt1 = "%5d%.2s";
char *fmt2 = "%2dx%-2d%.2s";
char *tail1 = " ::";
char *tail2 = " \n";
void show2x4x4( int a[][4], int b[][4] ) {
for( int r = 0, c; r < 4; r++ ) {
for( c = 0; c < 4; c++ ) printf( fmt1, a[r][c], &tail1[c+c] );
for( c = 0; c < 4; c++ ) printf( fmt1, b[r][c], &tail2[c+c] );
}
puts( "" );
}
int main() {
srand(time(0));
int r, c, v, a[4][4], b[4][4], d[4][4], e[4][4], *px, *py;
// fill 2 4x4 arrays of random ints as if both were 1x16
for( px = &a[0][0], py = &b[0][0], v = 0; v < 4 * 4; v++ ) {
int num = rand();
*px++ = num % 100; // two digits only
*py++ = num / 100 % 100;
}
show2x4x4( a, b ); // display
// show and perform the calc of the product matrices
for( r = 0; r < 4; r++ ) {
for( c = 0; c < 4; c++ ) {
printf( fmt2, a[r][c], b[r][c], &tail1[c+c] );
d[r][c] = a[r][c] * b[r][c];
}
for( c = 0; c < 4; c++ ) { // note b[] swaps col & row
printf( fmt2, a[r][c], b[c][r], &tail2[c+c] );
e[r][c] = a[r][c] * b[c][r];
}
}
puts( "" );
show2x4x4( d, e ); // show both products
return 0;
}
Output
29 66 71 20 : 35 88 22 22
35 80 36 85 : 53 1 28 54
12 14 12 71 : 95 98 92 19
62 61 89 17 : 94 63 32 43
29x35 66x88 71x22 20x22 :29x35 66x53 71x95 20x94
35x53 80x1 36x28 85x54 :35x88 80x1 36x98 85x63
12x95 14x98 12x92 71x19 :12x22 14x28 12x92 71x32
62x94 61x63 89x32 17x43 :62x22 61x54 89x19 17x43
1015 5808 1562 440 : 1015 3498 6745 1880
1855 80 1008 4590 : 3080 80 3528 5355
1140 1372 1104 1349 : 264 392 1104 2272
5828 3843 2848 731 : 1364 3294 1691 731

Need help understanding some parts of "15 Puzzle Game" in C++ [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 5 years ago.
Improve this question
I was reading the code of "15 Puzzle Game" implemented in C++ (Link).
Code
#include <time.h>
#include <stdlib.h>
#include <vector>
#include <string>
#include <iostream>
class p15 {
public :
void play() {
bool p = true;
std::string a;
while( p ) {
createBrd();
while( !isDone() ) { drawBrd();getMove(); }
drawBrd();
std::cout << "\n\nCongratulations!\nPlay again (Y/N)?";
std::cin >> a; if( a != "Y" && a != "y" ) break;
}
}
private:
void createBrd() {
int i = 1; std::vector<int> v;
for( ; i < 16; i++ ) { brd[i - 1] = i; }
brd[15] = 0; x = y = 3;
for( i = 0; i < 1000; i++ ) {
getCandidates( v );
move( v[rand() % v.size()] );
v.clear();
}
}
void move( int d ) {
int t = x + y * 4;
switch( d ) {
case 1: y--; break;
case 2: x++; break;
case 4: y++; break;
case 8: x--;
}
brd[t] = brd[x + y * 4];
brd[x + y * 4] = 0;
}
void getCandidates( std::vector<int>& v ) {
if( x < 3 ) v.push_back( 2 ); if( x > 0 ) v.push_back( 8 );
if( y < 3 ) v.push_back( 4 ); if( y > 0 ) v.push_back( 1 );
}
void drawBrd() {
int r; std::cout << "\n\n";
for( int y = 0; y < 4; y++ ) {
std::cout << "+----+----+----+----+\n";
for( int x = 0; x < 4; x++ ) {
r = brd[x + y * 4];
std::cout << "| ";
if( r < 10 ) std::cout << " ";
if( !r ) std::cout << " ";
else std::cout << r << " ";
}
std::cout << "|\n";
}
std::cout << "+----+----+----+----+\n";
}
void getMove() {
std::vector<int> v; getCandidates( v );
std::vector<int> p; getTiles( p, v ); unsigned int i;
while( true ) {
std::cout << "\nPossible moves: ";
for( i = 0; i < p.size(); i++ ) std::cout << p[i] << " ";
int z; std::cin >> z;
for( i = 0; i < p.size(); i++ )
if( z == p[i] ) { move( v[i] ); return; }
}
}
void getTiles( std::vector<int>& p, std::vector<int>& v ) {
for( unsigned int t = 0; t < v.size(); t++ ) {
int xx = x, yy = y;
switch( v[t] ) {
case 1: yy--; break;
case 2: xx++; break;
case 4: yy++; break;
case 8: xx--;
}
p.push_back( brd[xx + yy * 4] );
}
}
bool isDone() {
for( int i = 0; i < 15; i++ ) {
if( brd[i] != i + 1 ) return false;
}
return true;
}
int brd[16], x, y;
};
int main( int argc, char* argv[] ) {
srand( ( unsigned )time( 0 ) );
p15 p; p.play(); return 0;
}
/*
Possible Output:
+----+----+----+----+
| 11 | 5 | 12 | 3 |
+----+----+----+----+
| 10 | 7 | 6 | 4 |
+----+----+----+----+
| 13 | | 2 | 1 |
+----+----+----+----+
| 15 | 14 | 8 | 9 |
+----+----+----+----+
Possible moves: 2 13 14 7
*/
While I understood most of the code, some parts seemed unclear to me:
A. Why does the for loop iterate a 1000 times? Why is the number 1000 chosen?
for( i = 0; i < 1000; i++ )
B. In the above loop, why is v.clear(); called once in every iteration?
C. What is the significance of the numbers 1, 2, 4 and 8 in the code (used in the switch blocks)?
D. How does the getCandidates() function work?
A. The board is being shuffled, so 1000 means 'a lot, but not that much that you really have to start waiting for the board being shuffled'
B. getCandidates() returns the candidates by filling them in the vector, v.clear() resets the vector for new candidates.
C. Here 1,2,4,8 just means up,down,left,right (not in particular order). This is filled in by getCandidate(). There seem to be no reason for these specific values, they could be used as bits in an byte, but that doesn't seem to be the case here.
D. getCandidate() fills up,down,left,right in a vector based on whether the empty spot is near which border.

displaying a vector of deques in columns

I'm trying to display a vector of deques (std::vector<std::deque<int>> v) like this
v.at(0).at(0) v.at(1).at(0) v.at(2).at(0) v.at(3).at(0)
v.at(0).at(1) v.at(1).at(1) v.at(2).at(1) v.at(3).at(1)
v.at(0).at(2) v.at(1).at(2) v.at(2).at(2) v.at(3).at(2)
v.at(1).at(3) v.at(3).at(3)
v.at(3).at(4)
The first part of the vector is fixed at 7, the size of the actual columns are dynamic however depending on what the user chooses to do.
I was attempting something like
int row = 0;
int column;
for (column = 0; column < v.at(row).size(); column++){
cout << "v["<< row <<"]["<< column << "]" << v.at(row).at(column) << "\t";
while (row < v.size()){
cout << endl;
row++;
}
}
I'm getting errors like
libc++abi.dylib: terminating with uncaught exception of type std::out_of_range: vector
make: *** [Pile.h] Abort trap: 6
Having one of those blah brain days. Can someone help me print this out the way I want it?
Here is a demonstrative program that shows one of approaches to the task.
#include <iostream>
#include <iomanip>
#include <vector>
#include <deque>
#include <algorithm>
int main()
{
std::vector<std::deque<int>> v =
{
{ 0, 1, 2 },
{ 0, 1, 2, 3 },
{ 0, 1, 2 },
{ 0, 1, 2, 3, 4 }
};
size_t n = std::max_element( v.begin(), v.end(),
[]( const auto &x, const auto &y )
{
return x.size() < y.size();
} )->size();
for ( size_t i = 0; i < n; i++)
{
for ( size_t j = 0; j < v.size(); j++ )
{
std::cout << std::setw( 4 );
if ( i < v[j].size() )
{
std::cout << v[j][i];
}
else
{
std::cout << "";
}
}
std::cout << std::endl;
}
return 0;
}
Its output is
0 0 0 0
1 1 1 1
2 2 2 2
3 3
4
First of all, I suggest to get the max queue size
std::size_t maxQ { 0U };
for ( auto const & q : v )
maxQ = std::max(maxQ, q.size());
Now you can write a loop over (0U, maxQ( (the loop of lines) writing elements when available and space otherwise.
for ( auto i = 0U ; i < maxQ ; ++i )
{
for ( auto j = 0U ; j < v.size() ; ++j )
if ( i < v[j].size() )
; // print v[j][i]
else
; // print space
std::cout << std::endl; // endl of line
}
I leave to you cells printing details

Counter in arrays c++

i have a really simple code right there that counts how much values you need in arrays.
for (int i = 0; i < dm; i++)
{
if (arr[i] == c)
{
counter++;
}
};
But i need to make it a little bit tricky.I need to count number of same values. Imagine i have an array {4,4,4,3,3,2,2,1,1,0,0,0} and i need to find how much "twins" there. So 3,2,1 are twins because they have only 1 exact friend.
I tried something like 2 fors and 2 counters but still have troubles. Thanks. Hope you understand what i mean by "twin". x and x are twins and y,y,y are not ( just in case)
I'd make a map that counts - for each individual number in the array - their occurrences. The code could look as follows:
#include <iostream>
#include <map>
int main()
{
const int numberOfElements = 12;
int array[numberOfElements] = { 4,4,4,3,3,2,2,1,1,0,0,0 };
std::map<int,int> counts;
for (int i=0; i < numberOfElements; i++) {
counts[array[i]]++;
}
for (auto x : counts) {
if (x.second == 2) {
cout << "pair: " << x.first << endl;
}
}
return 0;
}
If - for some reason - the range of the elements is limited, you could also use a "plain" array for counting the occurrences. If, for example, the elements are in the range of 0..4, you could use the following fragment:
const int numberOfElements = 12;
const int elementMax = 4;
int array[numberOfElements] = { 4,4,4,3,3,2,2,1,1,0,0,0 };
int counts[elementMax+1] = {};
for (int i=0; i<numberOfElements; i++) {
counts[array[i]]++;
}
for (int i=0; i <= elementMax; i++) {
if (counts[i] == 2) {
cout << "pair: " << i << endl;
}
}
And if your array is sorted, than a solution without a counter-array could look as follows:
const int numberOfElements = 12;
int array[numberOfElements] = { 4,4,4,3,3,2,2,1,1,0,0,0 };
int prev = -1;
int count = 0;
for (int i=0; i<numberOfElements; i++) {
if (array[i] == prev) {
count++;
}
else {
if (count == 2) {
cout << "pair: " << prev << endl;
}
count=1;
prev = array[i];
}
}
if (prev >= 0 && count==2) {
cout << "pair: " << prev << endl;
}
You can do that in one pass and use binary search for efficiency:
int arr[] = { 4,4,4,3,3,2,2,1,1,0,0,0 };
int twins = 0;
for( auto i = std::begin( arr ); i != std::end( arr ); ) {
auto next = std::upper_bound( i, std::end( arr ), *i, std::greater<int>() );
if( std::distance( i, next ) == 2 ) ++twins;
i = next;
}
Live example
In case there are not too many duplicates in the array std::upper_bound could be not efficient and can be easily replaced:
auto next = std::find_if( std::next( i ), std::end( arr ), [i]( int n ) { return *i != n; } );
Solution without using additional array:
int twins_counter = 0;
for (int i = 0; i < dm; i++)
{
int counter = 0; // counter for elements
for (int j = 0; j < dm; j++)
{
if (arr[i] == arr[j])
{
if( j < i )
{
break; // we have searched twin for this element already
}
counter++;
if( counter > 2 )
{
break; // we meet element third time, it isn't twin
}
}
}
if( counter == 2 )
{
twins_counter++;
}
};
For sorted (upwards or downwards) arrays one cycle is enough:
int twins_counter = 0;
int counter = 1;
for (int i = 1; i < dm; i++)
{
if( arr[i] == arr[i-1] )
{
counter++;
}
else
{
if( counter == 2 )
{
twins_counter++;
counter = 1;
}
}
}
// check last value
if( counter == 2 )
{
twins_counter++;
}