Reversing an array

EDIT : I managed to find if the array is symmetrical. However, I'd like to have one text to output if the whole array is symmetrical not numbers. An example I have an array of 10 elements
6 7 1 5 9 9 5 1 7 6
It checks if 6 = 6 and prints yes. Then checks every other and prints if they are symmetrical 5 times (because of n = 10). I need to output "Yes" if the whole array is symmetrical not if the numbers are.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#include <iostream>
#include <fstream>
//
using namespace std;
//
const char duom[] = "d.txt";
const char rez[] = "r.txt";
//
void read(int &n, int S[])
{
    ifstream in(duom);
    in >> n;
    for(int i = 0; i != n; i++)
    {
        in >> S[i];
    }
}
//
void test(int n, int S[])
{
    ofstream out(rez);
    for(int i = 0, j = n - 1; i < j; i++, j--)
    {
        if(S[i] == S[j]) out << "TAIP" << endl;
        else out << "NE" << endl;
    }
}
//
int main()
{
    int n, S[100];
    read(n, S);
    test(n, S);
    return 0;
}
Last edited on
To check if it's symmetric, you don't need to actually reverse it.

e.g.
arr = 1 2 3 2 1
n = 5
arr[0] == arr[4]
arr[1] == arr[3]
arr[2] == arr[2] // (redundant if array is odd length, but that's OK)

e.g.
arr = 1 2 2 1
n = 4
arr[0] == arr[3]
arr[1] == arr[2]


There's a lot of things wrong, considering your code doesn't actually compile.
- Your read function looks OK, I think. though you should delete your "rez" variable if you don't use it.

- Print function: What do you want to happen here? If you want to print the elements that don't equal each other, do something like
1
2
3
for (int i = 0; i < n; i++)
    if (S[i] != reversed_S[i])
       cout << S[i] << " != " << reversed_S[i] << '\n';


- reverse_array
Line 28: You are simply calling reversed_S[i]. This call doesn't do anything. You're not changing anything. Do you see that?

I would go in this direction, instead:
1
2
3
4
5
6
7
8
9
10
bool is_symmetric(int arr[], int n)
{
    bool symm = true;
    for (int i = 0; i < n; i++)
    {
        if (arr[i] != arr[n-1 - i])
            symm = false;
    }
    return symm;
}


Edit: You edited your post, so some of this post no longer applies...
Last edited on
Yeah, I found another way. Anyway, I have another question. I want to output 1 text if the whole array is symmetrical not to check if each of the numbers are symmetrical.
Then loop through the whole array and keep track of if any character is not symmetric, with a counter or bool variable, without printing anything until the end. See my is_symmetric function.

In other words, don't print anything in the for loop itself.
Last edited on
You "have no clue"?
Your compiler should tell quite verbosely that your code has syntax errors. That means "not right".

Even if the syntax were ok, the logic may not be.

For example:
1
2
3
4
5
6
7
void reverse_array(int n, int reversed_S[])
{
    for ( int i = n - 1; i <= 0; i++ )
    {
        reversed_S[i];
    }
}

Lets say that you call that with n==7.
Loop initialization: i = 6;
Do one step if: 6<=0

Okay, the loop is skipped unless n<=1

Lets assume that you change the condition and loop does at least one iteration.
What does reversed_S[6]; do? Nothing.

What does the i++ do? On next iteration the i==7, then 8, 9, ...


Edit: You edited your post, but we should still try to learn from your mistakes ...
Last edited on
Is this an appropriate way to check ? Or using bool is always a better option ?

1
2
3
4
5
6
7
    int k = 0;
    for(int i = 0, j = n - 1; i < j; i++, j--)
    {
        if(S[i] != S[j]) k++;
    }
    if(k > 0) out << "NE";
    else out << "TAIP";
Last edited on
If it works, it works. It's understandable either way.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
#include <iostream>
#include <iterator>
#include <algorithm>
#include <string_view>

bool is_symmetrical_a( const int array[], std::size_t sz )
{
    // size of zero or one: symmetrical
    if( sz < 2 ) return true ;

    // if first element not equal to last element: not symmetrical
    if( array[0] != array[sz-1] ) return false ;

    // otherwise symmetrical if the middle sz-2 elements are symmetrical
    else return is_symmetrical_a( array+1, sz-2 ) ;
}

bool is_symmetrical_b( const int array[], std::size_t sz )
{
    const int* begin = array ; // iterator to first item
    const int* mid = array + sz/2 ; // iterator to middle

    // reverse iterator starting at the last item
    // https://en.cppreference.com/w/cpp/iterator/make_reverse_iterator
    auto rbegin = std::make_reverse_iterator(array+sz) ;

    // https://en.cppreference.com/w/cpp/algorithm/equal
    return std::equal( begin, mid, rbegin ) ;
}

bool is_symmetrical_c( const int array[], std::size_t sz )
{
    // https://en.cppreference.com/w/cpp/string/basic_string_view
    std::basic_string_view<const int> view( array, sz ); // C+17

    return std::equal( view.begin(), view.begin() + sz/2, view.rbegin() ) ;
}

int main()
{
     const int a[] { 1, 2, 3, 4, 5, 4, 3, 2, 1 } ;
     std::cout << std::boolalpha
               << is_symmetrical_a( a, std::size(a) ) << ' ' // true
               << is_symmetrical_b( a, std::size(a) ) << ' ' // true
               << is_symmetrical_c( a, std::size(a) ) << '\n' ; // true

     const int b[] { 1, 2, 3, 4, 5, 4, 3, 4, 2, 1 } ;
     std::cout << std::boolalpha
               << is_symmetrical_a( b, std::size(b) ) << ' ' // false
               << is_symmetrical_b( b, std::size(b) ) << ' ' // false
               << is_symmetrical_c( b, std::size(b) ) << '\n' ; // false
}

https://en.cppreference.com/w/cpp/string/basic_string_view
Thank you all I have another question. I need to check whether there are duplicates in an array and print their indexes. So what I did I made up index_i and index_j if I know that there's gonna be only 2 duplicates. But what if there is more than 2 ? There should be another way how to check instead of making index_(name) especially when I don't know how many there are going to be.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
#include <iostream>
#include <fstream>
//
using namespace std;
//
const char duom[] = "d.txt";
const char rez[] = "r.txt";
//
void read(int &n, int M[])
{
    ifstream in(duom);
    in >> n;
    for(int i = 0; i != n; i++)
    {
        in >> M[i];
    }
}
//
void find_same(int n, int M[])
{
    ofstream out(rez);
    int index_i = 0;
    int index_j = 0;
    int number = 0;
    for(int i = 0; i != n; i++)
    {
        for(int j = i; j != n; j++)
        {
            if(j != i)
            {
                if(M[i] == M[j])
                {
                    index_i = i;
                    index_j = j;
                    number = M[i];
                }
            }
        }
    }
    out << index_i << endl;
    out << index_j << endl;
    out << number << endl;
}
//
int main()
{
    int n, M[100];
    read(n, M);
    find_same(n, M);
    return 0;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
#include <iostream>
#include <iterator>

// return true if there is an earlier element equal to array[pos]
bool subsequent_duplicate( const int array[], std::size_t pos )
{
    for( std::size_t i = 0 ; i < pos ; ++i )
        if( array[i] == array[pos] ) return true ;

    return false ;
}

void print_duplicates( const int array[], std::size_t sz ) // brute force
{
    for( std::size_t i = 0 ; i < sz ; ++i ) // for each element in the array
    {
        if( !subsequent_duplicate( array, i ) ) // if not already printed as a duplicate
        {
            bool is_dup = false ; // not yet a duplicate

            for( std::size_t j = i+1 ; j < sz ; ++j ) // check with elements after j
            {
                if( array[i] == array[j] ) // duplicate
                {
                    if( !is_dup ) // first time this is seen as a duplicate
                    {
                        std::cout << "value " << array[i] << " duplicated at positions: " << i ;
                        is_dup = true ;
                    }

                    std::cout << ", " << j ;
                }
            }

            if(is_dup) std::cout << '\n' ;
        }
    }
}

int main()
{
    const int a[] { 10, 12, 19, 10, 15, 12, 13, 12, 10, 17, 12, 15 } ;

    for( int v : a ) std::cout << v << ' ' ;
    std::cout << '\n' ;

    print_duplicates( a, sizeof(a) / sizeof(a[0]) ) ;
}

http://coliru.stacked-crooked.com/a/9c7445dd0d786aeb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#include <iostream>
#include <vector>
#include <algorithm>
#include <utility>
using namespace std;

template<typename T> void print_duplicates( const T array[], int N )
{
   using pr = pair<T,int>;
   vector<pr> work( N );
   for ( int i = 0; i < N; i++ ) work[i] = { array[i], i };
   sort( work.begin(), work.end(), []( pr a, pr b ){ return a.first < b.first; } );
   cout << "Duplicates:\n";
   for ( int i = 1; i < N; i++ )
   {
      if ( work[i].first == work[i-1].first )
      {
         cout << work[i].first << ": " << work[i-1].second << " " << work[i].second << " ";
         for ( i++; i < N && work[i].first == work[i-1].first; i++ ) cout << work[i].second << " ";
         cout << '\n';
      }
   }
}

int main()
{
   const int a[] = { 10, 12, 19, 10, 15, 12, 13, 12, 10, 17, 12, 15 };

   for( int v : a ) cout << v << ' ';
   cout << '\n';
   print_duplicates( a, sizeof(a) / sizeof( a[0] ) );
}


10 12 19 10 15 12 13 12 10 17 12 15 
Duplicates:
10: 0 3 8 
12: 1 5 7 10 
15: 4 11 
Last edited on
Topic archived. No new replies allowed.