引用 | 編輯
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 |