0

Hello so the catch of this problem is you shouldn't use another array or function and do not change the elements of the given array or sort them and we don't know the interval of the elements and side note i shouldn't show the numbers twice

for example if we have a[10]={1,2,1,3,1,5,2,4,3,1} it should print out :

1 --- 4

2 --- 2

3 --- 2

4 --- 1

5 --- 1

I wrote a code for finding the repeating numbers using two for loops but i dont know how to stop it from repeating the same answer and how to make it show the counter

here is the code:

#include<iostream>
using namespace std;

int main()
{
    int arr[5];
    int size = sizeof(arr) / sizeof(arr[0]);
    for (int i = 0; i < 5; i++)
    {
        cout << "Enter " << i << " number:";
        cin >> arr[i];
    }
    {
        for (int i = 0; i < size; i++)
            for (int j = i + 1; j < size; j++)
                if (arr[i] == arr[j])
                    cout << " Repeating elements are " << arr[i] << " " << endl;
    }
    return 0;
}
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
Farzan_alm
  • 25
  • 4
  • 1
    `using namespace std;` is a syntax error in C: it does not follow the rules of the language. – pmg Jul 22 '20 at 17:13
  • This reads like it's from some contest/challenge/competitive coding/hacking site. Is it? If your goal is to learn C++, you won't learn anything there. In nearly all cases, like this one, the correct solution is based on a mathematical or a programming trick. If you don't know what the trick is and attempt to code a brute-force approach, the program runs slow and fails for that reason. If you're trying to learn C++, you won't learn anything from meaningless online contest sites [but only from a good C++ textbook](https://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list). – Sam Varshavchik Jul 22 '20 at 17:13
  • is there any range for the elements present in the array? – Sai Sreenivas Jul 22 '20 at 17:18
  • 1
    Also, why `int size = sizeof(arr) / sizeof(arr[0]);`? You just declared an array of size 5. So I'm guessing you already know how many elements it has – Abhay Aravinda Jul 22 '20 at 17:19
  • 2
    You're probably not allowed to use it, but [`std::map`](https://en.cppreference.com/w/cpp/container/map) crushes problems like this with little effort. `std::map freqcount;` and then `freqcount[arr[i]]++;` counts. To print frequencies, iterate with a [range-based for loop](https://en.cppreference.com/w/cpp/language/range-for). – user4581301 Jul 22 '20 at 17:19
  • nope its not clear the range of the elements too – Farzan_alm Jul 22 '20 at 17:19
  • just tried to cut the elements in half so it dont go fully till the end i got the idea from the n/2 in for loop in mod – Farzan_alm Jul 22 '20 at 17:22
  • you cannot use an other array or any memorization (map,set, list ...) ? is it for C++ or finally C ? it is easy to do in C without additional memorization of the elements – bruno Jul 22 '20 at 17:22
  • Does it contain only positive numbers? – Sai Sreenivas Jul 22 '20 at 17:23
  • yeah only positive numbers for now – Farzan_alm Jul 22 '20 at 17:24
  • Do the printed numbers have to be in sorted order (as in your wanted example output), or is it OK if they are in the order that they are included in the array? – rtoijala Jul 22 '20 at 17:25
  • you cannot change them (e.g. *const* array) or you have to let them unchanged at the end ? – bruno Jul 22 '20 at 17:25
  • yeah it doesn't matter the order of the numbers as long as it doesn't repeat the same answer twice or more – Farzan_alm Jul 22 '20 at 17:26
  • to save time why do you not give us the initial full statement ? – bruno Jul 22 '20 at 17:26
  • yeah can not change the like const – Farzan_alm Jul 22 '20 at 17:26
  • warning you understood wrong the remark about size, and your edit to do `int size = sizeof(arr);` is **catastrophic** – bruno Jul 22 '20 at 17:43

5 Answers5

4

See the code below.

I made the array a constant for brevity. You can just copy-paste in your code that reads it from the user input.

The trick is to check for each i that this is the first time that a[i] is found. If it has been found before, then it has already been counted on that previous iteration, and can be skipped now.

#include <iostream>
using namespace std;

int main()
{
    const int a[]={1,2,1,3,1,5,2,4,3,1};
    const int size = sizeof(a) / sizeof(a[0]);

    for (int i = 0; i < size; i++)
    {
        bool duplicate = false;
        for (int j = 0; j < i; j++)
        {
            if (a[i] == a[j])
            {
                duplicate = true;
                break;
            }
        }
        if (duplicate)
        {
            continue;
        }
        int count = 1;
        for (int j = i + 1; j < size; j++)
        {
            if (a[i] == a[j])
            {
                count++;
            }
        }
        cout << a[i] << " -- " << count << '\n';
    }
}
rtoijala
  • 1,200
  • 10
  • 20
  • 1
    sometimes to be lazy is better, do `const int a[]={1,2,1,3,1,5,2,4,3,1};` else why to do `const int size = sizeof(a) / sizeof(a[0]);` if you know the size is 10 ? – bruno Jul 22 '20 at 17:29
  • 1
    @bruno Good point. The hard-coded `10` was left over from copy-pasting the example array from the question. It is much better to remove it. – rtoijala Jul 22 '20 at 17:33
  • If your compiler;'s reasonably up to date you skip the the `sizeof` tango and use [`std::size`](https://en.cppreference.com/w/cpp/iterator/size). – user4581301 Jul 22 '20 at 17:39
0

Logic:

As you said there won't be negative numbers, I am making the duplicate values negative of the current value (to memorize that it's a duplicate value) and whenever I encounter a negative value I then make it simply positive (to get back to the original array).

#include <iostream>

int main()
{
    int arr[10] = {1,2,1,3,1,5,2,4,3,1}, cnt = 0, size = 10;

    for (int i = 0; i < size; i++) {
      cnt  = 1;

      if (arr[i] < 0) {
        arr[i] = -arr[i];
        continue;
      }

      for (int j = i + 1; j < size; j++) {

          if (arr[i] == arr[j]) {
            arr[j] = -arr[i];
            cnt++;
          }
        }

        std::cout <<  arr[i] << " " << cnt << '\n';
      }

    return 0;
}

output:

1 4
2 2
3 2
5 1
4 1

Note:

If changing the values in the array is allowed, making sure we will be left with the original array at the end of the program.

Sai Sreenivas
  • 1,690
  • 1
  • 7
  • 16
0

Maintain the previous smallest and look for the next smallest element in the array. Then run a loop to count it and set previous smallest to current smallest.

#include <iostream>
#include <vector>

using namespace std;

int main()
{
    int N;
    cin >> N;
    vector<int> V(N);
    for (int& e : V)
        cin >> e;

    int prev_smallest = numeric_limits<int>::min();
    int smallest = numeric_limits<int>::max();
    for (int c = 0; c < N; )
    {
        for (int j = 0; j < V.size(); ++j)
            if (prev_smallest < V[j] && V[j] < smallest)
                smallest = V[j];

        int count = 0;
        for (int j = 0; j < V.size(); ++j)
            if (V[j] == smallest)
                ++count;
        cout << smallest << ' ' << count << endl;
        prev_smallest = smallest;
        smallest = numeric_limits<int>::max();
        c += count;
    }
}
srt1104
  • 959
  • 7
  • 11
  • please `size_t j` rather than `int j` (2 times), and when you give `#include` give all of them so add `#include ` – bruno Jul 22 '20 at 17:40
  • being in C++ `for (auto v : V) if (prev_smallest < v && v < smallest) smallest = v;` and `for (auto v : V) if (v == smallest) ++count;` else if too much C for array iteration and that allow to be lazy :) – bruno Jul 22 '20 at 17:50
  • your proposal is interesting, but it does not work if the array contains `numeric_limits::min()` used in the array (which is not a problem is numbers are positive of course), it seems it works if the array contains `numeric_limits::max()` – bruno Jul 22 '20 at 17:57
  • 1
    @bruno that can be fixed easily. Run a separate loop to check if `numeric_limits::min()` exists in the array. If it does then count it and print it. Then run the above two loops. `c` will go from `N- count of(numeric_limits::min()`. – srt1104 Jul 22 '20 at 17:59
  • @lucieon yes, what about to say that editing your question ? By *pity* at least take into account my first remark, an answer must not have warning even compiling with `-Wall` if *gcc* (int/size_t) and must be compilable (missing #include) – bruno Jul 22 '20 at 18:02
  • 1
    @bruno yeah sorry about that. I was busy writing to another commenter on code review. I'm so used to see such warnings as I solve such problems that I just ignore them if there are 0 errors. Thanks for your time! I have much to learn. – srt1104 Jul 22 '20 at 18:05
0

This routine makes one pass along the array for each value counted plus one initial pass to identify the minimum and maximum value to count. Additionally, it prints values in an increasing order.

The for(;;) {} trick is equivalent to while(true) {}, that is 'iterate forever'. The loop does not actually work forever, because it breaks iterations in the last if().

void printCounts()
{
    const int a[]={1,2,1,3,1,5,2,4,3,1};
    const int size = sizeof a / sizeof a[0];

    int currentValue = a[0];
    int maxValue     = a[0];

    // find the first (minimum) and the last (maximum) value to count

    for (int i = 1; i < size; i++)
    {
        if (a[i] < currentValue)
            currentValue = a[i];
        if (a[i] > maxValue)
            maxValue = a[i];
    }

    // count items equal current value,
    // identify a next value to count,
    // print result,
    // reiterate
    for (;;)
    {
        int count = 0;
        int nextValue = maxValue;

        for (int i = 0; i < size; i++)
        {
            if (a[i] == currentValue)
                count ++;
            if (a[i] > currentValue && a[i] < nextValue)
                nextValue = a[i];
        }

        std::cout << "value:" << currentValue << "  count:" << count << std::endl;

        // all values counted ?
        if (currentValue == maxValue)
            break;

        // count nextValue
        currentValue = nextValue;
    }
}

Verified with GDB online Debugger. Results were:

value:1  count:4
value:2  count:2
value:3  count:2
value:4  count:1
value:5  count:1
CiaPan
  • 9,381
  • 2
  • 21
  • 35
0

Of course you could do the task very easy if you were allowed to use standard containers as for example std::map.

Here is a demonstration program.

#include <iostream>
#include <map>

int main() 
{
    int a[] = { 1, 2, 1, 3, 1, 5, 2, 4, 3, 1 };
    std::map<int, size_t> m;
    
    for ( const auto &item : a )
    {
        ++m[item];
    }

    for ( const auto &item : m )
    {
        std::cout << item.first << " --- " << item.second << '\n';
    }

    return 0;
}

The program output is

1 --- 4
2 --- 2
3 --- 2
4 --- 1
5 --- 1

If you are not allowed to use any standard container and may not change the array in any way and the output shall be sorted according to the values stored in the array then you can use the following (though inefficient) approach using only loops.

Here is another demonstration program.

#include <iostream>

int main() 
{
    int a[] = { 1, 2, 1, 3, 1, 5, 2, 4, 3, 1 };
     
    const size_t N = sizeof( a ) / sizeof( *a );
     
    int value;
    
    for ( size_t n = 0; n != N; )
    {
        size_t i = 0;
        
        if ( n != 0 )
        {
            while ( ( i != N ) && !( value < a[i] ) ) ++i;
        }

        size_t count = 1;
        size_t min_i = i;
        
        while ( ++i != N )
        {
            if ( ( a[i] < a[min_i] ) && ( n == 0 || value < a[i] ) )
            {
                min_i = i;
                count = 1;
            }
            else if ( a[min_i] == a[i] )
            {
                ++count;
            }
        }

        value = a[min_i];
        std::cout << value << " --- " << count << '\n';
        
        n += count;
    }
     
    return 0;
} 

The program output is the same as shown above.

1 --- 4
2 --- 2
3 --- 2
4 --- 1
5 --- 1
halfer
  • 19,824
  • 17
  • 99
  • 186
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335