引用 | 编辑
cz910021
2013-09-15 13:26 |
楼主
▼ |
||
x0
我的程式老师给我的题目让使用者以TextBox(文字长度限定8位)输入起始值及结束值,计算此范围内的整数和,但含有数字3及3的倍数的数字除外。 例如,若要计算1~20的整数和,但3及13含有数字3,且3、6、9、12、15、18均为3的倍数,因此计算时只加总1+2+4+5+7+8+10+11+14+16+17+19+20=134。 这是我打的 Dim x, y, a As String, i, j, k As Integer : x = TextBox1.Text : y = TextBox2.Text Dim t As Boolean = False : a = 0 If x > y Then .. 访客只能看到部份内容,免费 加入会员 x0
|
引用 | 编辑
cz910021
2013-09-15 17:19 |
1楼
▲ ▼ |
更新后
Dim x, y, a As String, i, j As Integer : x = TextBox1.Text : y = TextBox2.Text Dim t As Boolean = False : a = 0 If x > y Then MsgBox("起始值需小于结束值", , "题示") End If If x <> Fix(x) Then MsgBox("请输入整数", , "题示") TextBox1.Focus() TextBox1.SelectAll() Exit Sub ElseIf (y <> Fix(y)) Then MsgBox("请输入整数", , "题示") TextBox2.Focus() TextBox2.SelectAll() Exit Sub End If For i = x To y If i Mod 3 = 0 Or InStr(i, 3) <> 0 Then t = True Else t = False End If If Not (t) Then a += Val(i) End If Next TextBox3.Text = a End Sub x0 |
引用 | 编辑
ebolaman
2013-09-21 14:00 |
2楼
▲ |
||||||||||
我用 VB.NET 来写,要转成 VB6 应该不困难
第一种优化 (Calc2): 因为 3, 6, 9, 12, 15... 3 的倍数被排除掉 因此只要把剩下的 (3n-1), (3n-2) 再排除掉 含有 3 的数字加起来,结果一样 这样子 1/3 的运算就被省下来了 第二种优化 (Calc3): 排除掉数字含有 3 除了先转字串再找有没有 3 也可以每次除以10, 看 Mod 10 是否等于 3 因为转换通常比较花时间,用纯数学的方式也可以省下不少时间 复制程式 Imports System.ComponentModel Public Class Form1 Private Structure TestsInfo Public ReadOnly start As Long Public ReadOnly last As Long Public ReadOnly expected As Long Public Sub New(ByVal start As Long, ByVal last As Long, ByVal expected As Long) Me.start = start Me.last = last Me.expected = expected End Sub End Structure Private Class BenchmarkResult Private m_index As Integer Private m_name As String Private m_ms As Double Private m_perf As Double Public Sub New(ByVal index As Integer, ByVal name As String, ByVal ms As Double) m_index = index m_name = name m_ms = ms End Sub Public Sub CalcPerf(ByVal avgElapsed As Double) m_perf = avgElapsed / m_ms End Sub Public Property Index As Integer Get Return m_index End Get Set(ByVal value As Integer) m_index = value End Set End Property Public Property Name As String Get Return m_name End Get Set(ByVal value As String) m_name = value End Set End Property Public Property Ms As Double Get Return m_ms End Get Set(ByVal value As Double) m_ms = value End Set End Property Public ReadOnly Property Performance As String Get Return String.Format("{0:f2}%", 100 * m_perf) End Get End Property End Class ' start, last, expected Private ReadOnly tests As TestsInfo() = { New TestsInfo(1, 1, 1L), New TestsInfo(1, 2, 3L), New TestsInfo(1, 3, 3L), New TestsInfo(1, 10, 37L), New TestsInfo(1, 13, 48L), New TestsInfo(1, 20, 134L), New TestsInfo(3, 3, 0), New TestsInfo(3, 4, 4L), New TestsInfo(3, 5, 9L), New TestsInfo(3, 6, 9L), New TestsInfo(3, 9, 24L), New TestsInfo(13, 13, 0), New TestsInfo(13, 23, 108L), New TestsInfo(100, 1000, 249976L), New TestsInfo(1, 100, 2872L), New TestsInfo(3, 103, 2970L), New TestsInfo(123, 456, 32130L), New TestsInfo(300, 4000, 2192728L), New TestsInfo(332, 3332, 2188728L), New TestsInfo(777, 7777, 12814264L), New TestsInfo(999, 9999, 22425984L), New TestsInfo(1, 999999, 183707816292L) } Private fnCalc As Func(Of Long, Long, Long) Private Const NUM_BENCHMARK As Integer = 50 Private Sub Button1_Click() Handles Button1.Click Dim actions As Func(Of Long, Long, Long)() = { AddressOf Calc1, AddressOf Calc2, AddressOf Calc3 }, ubActions = actions.GetUpperBound(0), benchmarkElapsed(ubActions) As Double, avgElapsed As Double = 0, lstResult As IBindingList = New BindingList(Of BenchmarkResult) Me.Text = "Benchmarking...Please wait" ' benchmark For i As Integer = 0 To ubActions fnCalc = actions(i) benchmarkElapsed(i) = Benchmark(AddressOf DoCalc, NUM_BENCHMARK) avgElapsed += benchmarkElapsed(i) Next avgElapsed /= (ubActions + 1) ' output the result For i As Integer = 0 To ubActions Dim benchmarkResult As New BenchmarkResult(i, actions(i).Method.Name, benchmarkElapsed(i)) benchmarkResult.CalcPerf(avgElapsed) lstResult.Add(benchmarkResult) Next ' configure datagridview DataGridView1.DataSource = lstResult DataGridView1.AutoResizeRows() DataGridView1.AutoResizeColumns() Me.Text = "Completed" End Sub Private Function Benchmark(ByVal fn As Action, ByVal testTimes As Integer) As Double Dim sw As New Stopwatch, times As Integer = testTimes sw.Start() While times <> 0 fn() times -= 1 End While sw.Stop() Return sw.ElapsedMilliseconds / testTimes End Function Private Sub DoCalc() Dim ret As Long For i As Integer = 0 To tests.GetUpperBound(0) Dim test As TestsInfo = tests(i) ret = fnCalc(test.start, test.last) Debug.Assert(test.expected = ret, String.Format("Wrong result, expected {0} but got {1}. " & "Index is {2}, from {3} to {4}", test.expected, ret, i, test.start, test.last) ) Next End Sub Private Function Calc1(ByVal numStart As Long, ByVal numLast As Long) As Long Dim sum As Long = 0 For i As Long = numStart To numLast Dim s As String = i.ToString() If 0 <> i Mod 3 AndAlso -1 = s.IndexOf("3"c) Then sum += i End If Next Return sum End Function Private Function Calc2(ByVal numStart As Long, ByVal numLast As Long) As Long Dim sum As Long = 0, start As Long, last As Long For i As Long = 1 To 2 start = ((numStart - 1 + i) \ 3 + 1) * 3 - i last = ((numLast + i) \ 3) * 3 - i For j As Long = start To last Step 3 Dim s As String = j.ToString() If -1 = s.IndexOf("3"c) Then sum += j End If Next Next Return sum End Function Private Function Calc3(ByVal numStart As Long, ByVal numLast As Long) As Long Dim sum As Long = 0 For i As Long = 1 To 2 Dim start As Long = ((numStart - 1 + i) \ 3 + 1) * 3 - i, last As Long = ((numLast + i) \ 3) * 3 - i For j As Long = start To last Step 3 Dim k As Long = j Do If 3 = k Mod 10 Then Exit Do End If k \= 10 Loop While 0 <> k If 0 = k Then sum += j End If Next Next Return sum End Function End Class 程式建构说明: Visual Studio 建 VB Windows Application 拉一个 Button (Button1) 和 DataGridView (DataGridView1) Form1 程式码改成以上程式码 程式代码说明: tests 是作为验证正确性用, fnCalc 是函数的位址,传给 DoCalc 使用 Benchmark 会跑 DoCalc NUM_BENCHMARK 次然后传回平均花费时间 编译环境在 Debug 结果: Calc3 大概快了 2 倍 编译环境在 Release 结果: (可以勾选 Project Properties -> Compile -> Advanced Compile Options -> Optimization 的两个选项达到更快的运算速度) Calc3 大概快了 6 倍
x0 |