1

I have a list of numbers and I want to increase by a unit the value of tot only if the element of the list is different from every element before it.

Basically I'm counting how many element the list has, if we don't consider the duplicates.

My code increases the count every time the function is different from at least 1 element.

How can i fix it?

My code:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main()
{
    int i;
    int j = 0;
    int tot = 0;
    int n = 11;
    int list[12] = {0, 8, 2, 12, 6, 0, 4, 8, 3, 2, 3, 0};
    puts("[MEMBERS COMPARED AND INDEXES]");
    for (i = 1; i < n; i++)
    {
        for (j = i - 1; j > 0; j--)
        {
            printf("\n %d %d %d %d\n", list[i], list[j], i, j);

            //printf("\n %d %d \n", i,j);
            if (list[i] != list[j])
                tot++;
        }
    }
    puts("[TOT]");
    printf("\n %d", tot);
}

The code with this sample array should produce a total of 7, but it's 42.

Complete output:

[MEMBERS COMPARED AND INDEXES]

2 8 2 1

12 2 3 2

12 8 3 1

6 12 4 3

6 2 4 2

6 8 4 1

0 6 5 4

0 12 5 3

0 2 5 2

0 8 5 1

4 0 6 5

4 6 6 4

4 12 6 3

4 2 6 2

4 8 6 1

8 4 7 6

8 0 7 5

8 6 7 4

8 12 7 3

8 2 7 2

8 8 7 1

3 8 8 7

3 4 8 6

3 0 8 5

3 6 8 4

3 12 8 3

3 2 8 2

3 8 8 1

2 3 9 8

2 8 9 7

2 4 9 6

2 0 9 5

2 6 9 4

2 12 9 3

2 2 9 2

2 8 9 1

3 2 10 9

3 3 10 8

3 8 10 7

3 4 10 6

3 0 10 5

3 6 10 4

3 12 10 3

3 2 10 2

3 8 10 1

[TOT]

42

7
  • Please make sure your code can be compiled. Show the complete output you get and the complete expected output. Commented Feb 25, 2021 at 17:15
  • There are many possibilities. One that could be fitted to your current code with comparatively few changes would be to increment tot unconditionally on each outer-loop iteration, and then decrement it again via the inner loop in the event that you find a match. Be sure also to break from the inner loop after finding one match, else multiple matches will mess up your count. Commented Feb 25, 2021 at 17:20
  • Presumably you should initialise int tot = 0; Commented Feb 25, 2021 at 17:25
  • i adjustedd a few things and added the output Commented Feb 25, 2021 at 17:26
  • the problem is that the function increase tot everytimy i find ONE match, but i want it to increase tot only if it matches with every number before the one i am considering Commented Feb 25, 2021 at 17:29

3 Answers 3

1

You're on the right track, going back in the array to see if the current value already exists, if not, count it as unique, otherwise move on.

The problem is that you are counting every different value before, regardless if it was alread counted, or if it is unique, this, of course, will give you a much larger total, you need to count unique values only once, something like this:

Live demo

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>

int main()
{
    int tot = 0;
    bool exists;
    int list[] = {0, 8, 2, 12, 6, 0, 4, 8, 3, 2, 3, 0}; // size can be omited

    for (size_t i = 0; i < sizeof list / sizeof list[0]; i++)
    {
        exists = false; //flag to track repeated values

        //loop back to check if it is already in the array
        for (int j = i - 1; j >= 0; j--)
        {
            if (list[i] == list[j])
            {
                exists = true;
                break;
            }
        }
        if (!exists) // count if it is not already in the array
        {
            tot++;
        }
    }
    printf("Total unique values: %d", tot);
    return EXIT_SUCCESS;
}

Another solution would be to sort the array, you can use qsort or make your own sorting algorithm, this makes things easier because the repeated values are stored contiguosly.

It's hard to tell if it would be better, adding the sorting overhead and then check for duplicates might even be less efficient than this solution which is already O(N2), this will depend on the quality of the sorting algorithm.

Sign up to request clarification or add additional context in comments.

Comments

0

You need two arrays, current and target of the same size to represent the raw data and unique entities respectively. You also need a total unique variable, or you can simply write the return out in a print at the end of the function.

Unique entity function

Taking each element of current and comparing it to all elements in target will enable target to contain all unique entities. Simply finding the target size will give you the total number of unique entities found.

Alternatively, The complexity of your current attempt is O(N^2) already. Applying a sorting algorithm to work within that complexity and checking through the result for non-consecutive values will yield you the desired unique entities after being sorted. Adding a counter to that will provide you with a valid solution.

Resources/Reading

If you'd like a deeper understanding (with code examples) this explains in detail the steps you need to take.

Comments

0

The loops should start from 0 and n should be 12 (or you should do i<=n)

It would be better to define n as a constant

#dedine N 12

And then declare

int list[N] = {...

Or, as stated in the comments, you can compute the length of the array automatically

#define N (sizeof(list) / sizeof(list[0]))

You can now use N instead of your n without needing to specify the length of the list array

int list[] = { 0, 8, etc... };

Anyway, you can solve the issue with a flag variable telling whether the current element is different from all the previous.

#include <stdio.h>
#include <stdlib.h>
#include<string.h>

#define N (sizeof(list) / sizeof(list[0]))

int main()
{
    int i, j, flag;
    int tot = 0;
    int list[] = {0, 8, 2, 12, 6, 0,4, 8, 3, 2, 3, 0};
    
    for (i = 0; i < N; i++) {
    
        flag = 1;
        
        for (j = 0; j < i; j++) {
                    
            if (list[i] == list[j]) {
                flag = 0;
                break;
            }
        }

        if( flag ) tot++;
    }
    
    puts("[TOT]");
    printf("\n %d", tot);
}

5 Comments

Yeah sorry, I added the break in an edit, just to make the program a bit more efficient, but the if had no brackets, so the break was breaking the program apart.
Better still int list[12] = ... -> int list[]..... Then N can be computed as sizeof(list)/sizeof(int).
@EdHeal yes you can compute the length of the array, but since the OP has it hardcoded, at least let's hardcode it properly.
@SheikYerbouti No you should not hardcode it in the first place. Better to give the poster pointer the bast way of doing it. Let the compiler do the work. Makes it easier to adjust the array and not get it wrong
@EdHeal all right, I added this information to the answer, thank you.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.