Results 1 to 5 of 5

Thread: Grouping numbers with arrays

  1. #1

    Thread Starter
    New Member
    Join Date
    Sep 2012
    Posts
    3

    Angry Grouping numbers with arrays

    Hi guys!
    Stuck on a bit of homework and hoping someone here could point me in the right direction.

    This is the first question I've done (and It works fine btw!),

    basically what it's doing is generating 100 random numbers, and then dividing each number by 10 to get a 1 digit number, this number is then used to count how many numbers per group are generated (for example, numbers between 0-9,10-19,20-29...etc) and then displaying them in a list box

    Code:
     Private Sub btn_generate_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btn_generate.Click
            Dim generator As Random = New Random(DateTime.Now.Millisecond)
            Dim ageCount(0 To 99) As Short
            Dim ageGroupNo As Short
            Dim Age As Short
    
            lst_output.Items.Clear()
            lst_output.Items.Add("Age:" + vbTab + "Count:")
    
            For i = 0 To 99  - For 100 iterations
                Age = generator.Next(0, 100)  - Generate a random num between 0-99
                ageGroupNo = Age \ 10  - Divide number by 10
                ageCount(ageGroupNo) += 1  - Increment Group
            Next
    
    
            Dim groups As New List(Of String)
    
            For i = 0 To 9  - Generates group titles (0-9, 10-19...etc)
                groups.Add(CStr(i * 10) + "-" + CStr((i * 10) + 9))
            Next
    
            For i = 0 To 9  - Displays data
                lst_output.Items.Add(CStr(groups(i)) + vbTab + CStr(ageCount(i)))
            Next
    
        End Sub
    so that's all well and good, but now the challenge
    do the same thing but with 100 Decimal numbers between 1.0 and 2.75.

    Code:
    Private Sub btn_generate_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btn_generate.Click
            Dim generator As Random = New Random(DateTime.Now.Millisecond)
            Dim heightCount(0 To 99) As Decimal
            Dim heightGroupNo As Decimal
            Dim Height As Decimal
    
    
    
            lst_output.Items.Clear()
            lst_output.Items.Add("Height:" + vbTab + "Count:")
    
            For i = 0 To 99  - For 100 iterations
    Generate:
                Height = Math.Round(generator.NextDouble() * 2.75, 2)  - Random Num no greater than 2.75
    
                If Height < 1.0 Then  - Make sure number is at least 1.0
                    GoTo Generate
                End If
    
                heightGroupNo = (Height / 0.9)  - THIS is the problem part
    
                heightCount(heightGroupNo) += 1 
            Next
    
            For i = 0 To 8
                lst_output.Items.Add(CStr(heightCount(i)))
            Next
      
    
        End Sub
    I need the generated decimals to be broken into 9 groups
    Code:
    < 1.20
    1.20 - 1.39
    1.40 - 1.59
    1.60 - 1.79
    1.80 - 1.99
    2.00 - 2.19
    2.20 - 2.39
    2.40 - 2.59
    >2.60
    I've tried converting the decimals to whole numbers and then dividing by 9, but nothing seems to be getting me the desired results, I tried a select/case statement, which worked but obviously inefficient as hell,
    I know there's a better way to do it then that!

    I get the feeling I'm missing something obvious and perhaps a fresh pair of eyes tomorrow morning will do the trick, but as it stands I'm pulling my hair out :P

    thanks for your time, hope you can assist!

  2. #2
    eXtreme Programmer .paul.'s Avatar
    Join Date
    May 2007
    Location
    Chelmsford UK
    Posts
    26,415

    Re: Grouping numbers with arrays

    array indices must be integer. here's an improvement for you. be sure to read the comments.

    Code:
    Public Class Form1
    
        Private Sub btn_generate_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btn_generate.Click
            Dim generator As Random = New Random(DateTime.Now.Millisecond)
            Dim ranges(,) As Decimal = {{1D, 1.19D}, {1.2D, 1.39D}, {1.4D, 1.59D}, {1.6D, 1.79D}, {1.8D, 1.99D}, {2D, 2.19D}, {2.2D, 2.39D}, {2.4D, 2.59D}, {2.6D, 2.75D}}
            Dim heightCount(0 To 99) As Decimal
            Dim heightGroupNo As Integer
            Dim Height As Decimal
    
            lst_output.Items.Clear()
            lst_output.Items.Add("Height:" + vbTab + "Count:")
    
            For i as Integer = 0 To 99  '- For 100 iterations
    
                Do 'improvement here
                    Height = CDec(Math.Round(generator.NextDouble() * 2.75, 2))  '- Random Num no greater than 2.75
                Loop While Height < 1D
    
                heightGroupNo = getIndex(ranges, Height)  '- fixed
                If heightGroupNo = -1 Then i -= 1 : Continue For
    
                heightCount(heightGroupNo) += 1
            Next
    
            For i = 0 To 8 'fixed outputting
                lst_output.Items.Add(If(i = 0, "< 1.20", If(i = 8, "> 2.60", String.Format("{0:00} - {1}", ranges(i, 0), ranges(i, 1)))) & vbTab & CStr(heightCount(i)))
            Next
    
        End Sub
    
        Private Function getIndex(ByVal d(,) As Decimal, ByVal value As Decimal) As Integer
            For x As Integer = 0 To d.GetUpperBound(0)
                If value >= d(x, 0) And value <= d(x, 1) Then Return x
            Next
            Return -1
        End Function
    
    End Class

  3. #3
    PowerPoster stanav's Avatar
    Join Date
    Jul 2006
    Location
    Providence, RI - USA
    Posts
    9,290

    Re: Grouping numbers with arrays

    Because the differences between groups are not the same (1st group is 1.2 while other groups is only 0.2), you need to use select case or if...elseif...esle statement.
    Let us have faith that right makes might, and in that faith, let us, to the end, dare to do our duty as we understand it.
    - Abraham Lincoln -

  4. #4
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    40,104

    Re: Grouping numbers with arrays

    I'm not sure about the exact speed benefit, but what I would try would be generating random numbers between 0 and your maximum size. Basically, if you took all of your categories and multiplied by 100, you'd be converting all of your categories into integers.

    You could then make an array of Integer equal to the range of numbers you wanted to generate. Yeah, it might be 1000, or more, but so what, memory is cheap. Your loop would then look like this:

    Code:
    For x = 0 to 99
     yourArray(generator.Next(maxValue)) +=1
    Next
    Then you'd just sum up your ranges with a series of loops, one per category. The first loop would look like this:

    Code:
    Dim sum as Integer
    For x = 0 to 119
     sum += yourArray(x)
    Next
    The pieces are totally trivial, as there are no conversions and no conditionals in the whole code. The code trades memory for speed. The drawback would be that with only 100 items, a very large number of the array slots would be 0, so you'd be performing a bunch of extra += 0 statements, but you'd have to test it to see whether or not it mattered. I would expect that the first loop would cost more in time than all the others, regardless of the number of categories you used, just because of the cost of the random number generator.
    My usual boring signature: Nothing

  5. #5

    Thread Starter
    New Member
    Join Date
    Sep 2012
    Posts
    3

    Re: Grouping numbers with arrays

    Wow, brilliant guys,

    thanks a lot to all of you!, you've taught me more than you know in a single post, I really appreciate it!

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width