0

I want to have a function that returns the sum of different (non duplicate) values from an array: if I have {3, 3, 1, 5}, I want to have sum of 3 + 1 + 5 = 9.

My attempt was:

int sumdiff(int* t, int size){
    int sum=0;
    for (int i=0; i<=size;i++){
        for(int j=i; j<=size;j++){
            if(t[i]!=t[j])
            sum=sum+t[i];
        }
    }
    return sum;
}

int main()
{
    int t[4]={3, 3, 1, 5};
    cout << sumdiff(t, 4);
}

It returns 25 and I think I know why, but I do not know how to improve it. What should I change?

4
  • Please, explain your "why" (you said you think you know why it's not working) in the question. Also, format your code to be more readable. Commented Nov 22, 2016 at 9:21
  • (1) You're getting out of the bound of the array; (2) You're comparing the index but not the value of the element for duplication check. Commented Nov 22, 2016 at 9:23
  • You have undefined behavior, out of bounds access of the array Commented Nov 22, 2016 at 9:23
  • Now i think i am comparing the values. Commented Nov 22, 2016 at 9:26

6 Answers 6

2

Put all the items in a set, then count them.

Sets are data structures that hold only one element of each value (i.e., each of their elements is unique; if you try to add the same value more than once, only one instance will be count).

You can take a look in this interesting question about the most elegant way of doing that for ints.

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

9 Comments

Maybe expand your answer a little bit?
I would appreciate.
Wow, that was super quick, Mike :)
I have elaborated it a bit, HTH.
But could it be done in a way similar to what i wanted to do?
|
1

First of all, your loop should be for (int i=0; i<size;i++). Your actual code is accessing out of the bounds of the array.

Then, if you don't want to use STL containers and algorithms (but you should), you can modify your code as follows:

int sumdiff(int* t, int size){
    int sum=0;
    for (int i=0; i<size;i++){

        // check if the value was previously added

        bool should_sum = true;

        for(int j=0; should_sum && j<i;j++){
            if(t[i]==t[j])
                should_sum = false;
        }

        if(should_sum)
            sum=sum+t[i];
    }
    return sum;
}

int main()
{
    int t[4]={3, 3, 1, 5};
    cout << sumdiff(t, 4);
}

2 Comments

One more question why j<i ?
To go until the element before element at index i
0

You could:

  • Store your array contents into an std::unordered_set first. By doing so, you'd essentially get rid of the duplicates automatically.
  • Then call std::accumulate to compute the sum
  • Comments

    0

    **wasthishelpful's answer was exactly what i was talking about. I saw his post after i posted mine.

    So, you're trying to check the duplicate number using your inner loop. However, your outer loop will loop 4 times no matter what which gives you wrong result. Try,

    • Do only checking in inner loop. (use a flag to record if false)
    • Do your sum outside of inner loop. (do the sum when flag is true)

    Comments

    0

    Here is another solution using std::accumulate, but it iterates over the original elements in the call to std::accumulate, and builds the set and keeps a running total as each number in the array is encountered:

    #include <iostream>
    #include <numeric>
    #include <set>
    
    int main()
    {
        int t[4] = { 3, 3, 1, 5 };
        std::set<int> mySet;
        int mySum = std::accumulate(std::begin(t), std::end(t), 0, 
             [&](int n, int n2){return n += mySet.insert(n2).second?n2:0;});
        std::cout << "The sum is: " << mySum << std::endl;
        return 0;
    }
    

    The way it works is that std::insert() will return a pair tbat determines if the item was inserted. The second of the pair is a bool that denotes whether the item was inserted in the set. We only add onto the total if the insertion is successful, otherwise we add 0.

    Live Example

    1 Comment

    const std::set<int> mySet{std::begin(t), std::end(t)}; const int mySum = std::accumulate(std::begin(t), std::end(t), 0); seems more natural/simpler.
    0

    Insert array elements into a set and use the std::accumulate function:

    #include <iostream>
    #include <numeric>
    #include <set>
    
    int main()
    {
        int t[4] = { 3, 3, 1, 5 };
        std::set<int> mySet(std::begin(t), std::end(t));
        int mySum = std::accumulate(mySet.begin(), mySet.end(), 0);
        std::cout << "The sum is: " << mySum << std::endl;
        return 0;
    }
    

    Comments

    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.