Question designing a function

andrews

Well-known member
Joined
Nov 22, 2011
Messages
135
Programming Experience
5-10
I have to make a special function where performance is a must
Given a sorted array of integers, I want to know :
- the number of integers who are unique
- the sum of those numbers
I have make such a function but, I guess, without performance because I pass the array twice.
I want a function who is passing the array one time.
The function could look :

private function sumunique(byref ar() as integer,byref number as integer) as integer
......
return sum
end function

Thanks for any response
 
Last edited:
First things first, there's no reason for you to be passing the array itself ByRef. Unless you're actually going to be assigning a new array to the parameter inside the method and you want that change to affect the variable that you passed in in the first place, passing ByRef serves no purpose and you should be passing ByVal. I assume that the second parameter is how you'll be passing out the number of unique elements, in which case ByRef is appropriate. You could certainly come up with a better name for that parameter though.

As for the implementation, you might consider using a HashSet internally. You can loop through the array and Add each element to the HashSet. If Add returns True then the item did not already exist in the HasSet and it was added, so you can add that element to a running total. If Add returns False then the item was already in the HasSet so it was not added, so you wouldn't add it to your total. I imagine that you could squeeze out additional performance but this is probably good enough for most cases and it's very simple.

Keep in mind also that For loops will actually perform a little better than equivalent For Each loops.
 
Thanks very much for the answer but I would see the specific solution that I asked (if it exists ?) and not other solutions who are not so performant.
Regards
 
Sorry, it is not the solution that I mean.
Maybe I have not good explained but by unique I mean that the integer may not appear twice.
f,e
2
3
3
4
5
5
5
6
number = 3, sum = 12
One can use dictionary but the pass is twice.
I hope that but using the array with 1 pass is possible.
Who can find this?
Regards,
 
Ah, I see what you mean now. You want to sum all the values that only appear once in the array. I thought that you wanted to sum one instance of all numbers in the array. So, in your example, 3 and 5 both appear more than once so they are excluded completely and you end up summing 2, 4 and 6, correct? That's definitely more complex and I'll have to think on it.
 
Add unique array values

Try something like this. I wrote it in a Console app with list of unique numbers after sorting the array. Is this what you're looking for? You can translate it into a Windows app using MessageBox.Show() instead of Console.Writeline.

VB.NET:
Module Module1

    Sub Main()
        Dim sum As Integer
        Dim myarray() As Integer = {4, 8, 2, 3, 3, 5, 4, 8, 8, 4, 9, 2, 2, 7, 5, 3, 5, 4, 9}
        Array.Sort(myarray)
        sum = mysum(myarray)
        Console.WriteLine("Sum of unique numbers is " & sum)
        Console.ReadLine()
    End Sub

    Function mysum(myarray() As Integer) As Integer
        Dim sum As Integer = myarray(0)
        Console.Write(sum & "  ")
        For x As Integer = 1 To myarray.Length - 1
            If myarray(x) <> myarray(x - 1) Then
                Console.Write(myarray(x) & "  ")
                sum += myarray(x)
            End If
        Next x
        Return sum
    End Function

End Module
 
Try something like this. I wrote it in a Console app with list of unique numbers after sorting the array. Is this what you're looking for? You can translate it into a Windows app using MessageBox.Show() instead of Console.Writeline.

VB.NET:
Module Module1

    Sub Main()
        Dim sum As Integer
        Dim myarray() As Integer = {4, 8, 2, 3, 3, 5, 4, 8, 8, 4, 9, 2, 2, 7, 5, 3, 5, 4, 9}
        Array.Sort(myarray)
        sum = mysum(myarray)
        Console.WriteLine("Sum of unique numbers is " & sum)
        Console.ReadLine()
    End Sub

    Function mysum(myarray() As Integer) As Integer
        Dim sum As Integer = myarray(0)
        Console.Write(sum & "  ")
        For x As Integer = 1 To myarray.Length - 1
            If myarray(x) <> myarray(x - 1) Then
                Console.Write(myarray(x) & "  ")
                sum += myarray(x)
            End If
        Next x
        Return sum
    End Function

End Module

Ah yes, I forgot that the array was said to be sorted. That makes it rather easy, doesn't it. D'oh!
 
Hi,

I was about to post an incorrect example of what I thought you were after until jmcilhinney responded and finally figured out what is was you were actually after.

Here is another way to complete what you are looking for. As to performance I will leave to to you to work out which works faster.

VB.NET:
Public Class Form1
  Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
    Dim NumberArray() As Integer = {2, 3, 3, 3, 4, 5, 5, 5, 6}
    MsgBox(SummeriseUniuqueIntegersFromArray(NumberArray))
  End Sub
 
  Private Function SummeriseUniuqueIntegersFromArray(ByVal NumberArray() As Integer) As Integer
    Dim GroupNumbers = (From No In NumberArray Select No Group By No Into G = Group, TotalNumbers = Count())
    Dim SumUniqueNumbers = (From GN In GroupNumbers Where GN.TotalNumbers = 1 Select GN.No).Sum
    Return SumUniqueNumbers
  End Function
End Class
By the way all credit, if you want to apply any credit, needs to go to jmcilhinney since without his diligence none of us would have got what you actually meant.

Good luck,

Ian
 
Thanks for the response.
Sorry, but none of the examples are satisfying.
I think that the first example gives wrong results and the second, I have not tested, but I am sure that there is no performance.
If I may repeat, I want not just a solution (I have one) but a performant solution (one pass for the array)
Regards
 
Solitaire's example does pass through the array once, so you have what you asked for. Maybe instead of saying the same thing over and over you might consider showing us the solution you already have so that we can at least see the solution you're after, if not the implementation. God forbid you should provide us with all the relevant information.
 
Hi,

concerning solitaire

f.e.

ar(0) = 0
ar(1) = 1
ar(2) = 1
ar(3) = 3
ar(4) = 3
ar(5) = 6
ar(6) = 7
ar(7) = 8
ar(8) = 9
ar(9) = 9
ar(10) = 9
I receive only sum = 34 but I must have sum = 21 and number = 3

Like I said my solution is not performant because I pass two times through the lenght of the array (I use dictionary)
What I want (I don't know if it is possible) is a solution who gives the answers in one pass through the array.
That is obviously the most performant.
Regards
 
Back
Top