Ошибка, которую я не могу обнаружить, ошибочная логика? - PullRequest
0 голосов
/ 09 сентября 2011

Описание проблемы: Возьмите стопку монет вверх. Поднимите верхнюю монету и продолжите: возьмите две верхние монеты и переверните их как одну стопку (хвост, голова становится, когда перевернут, и помещают обратно на стопку хвоста, голову (две монеты переворачиваются, как будто склеены)). Теперь таким же образом переверните верхние 3 монеты и поместите обратно в стек (вы получите: хвост, хвост, голова (и если бы было 4 монеты, которые были бы хвостом, хвостом, хвостом, головой). Когда вы переворачиваете весь стек начните снова с первой монеты. Продолжайте, пока не вернетесь в стек со всеми головами.

(надеюсь, это понятно)

Кто-нибудь может понять, почему эта маленькая программа не работает? Пример для меня, где я впервые замечаю ошибку, когда счет достигает 18 со стеком 6 монет.

Я поместил кнопку в таблицу и вызвал FlippingCoins ...

Sub FlippingCoins()
Call theStackOfCoins
Call theFlipping
End Sub


Sub theStackOfCoins()
Worksheets("Sheet3").Cells(1, 3).Select
Columns("A:b").Select
Selection.ClearContents
Range("a3").Select

Dim StackOfCoins As Integer
    StackOfCoins = Worksheets("Sheet3").Cells(1, 3).Value

Dim row As Integer
    row = 0

For theStack = 1 To StackOfCoins
    Worksheets("Sheet3").Cells(row + theStack, 1).Value = True
Next theStack

End Sub

Sub theFlipping()

Dim middleCoin As Integer
    middleCoin = 0
Dim passes As Integer
    passes = 0
Dim Fst As Integer
    Fst = 0
Dim Lst As Integer
    Lst = 0

Dim stack As Integer
    stack = Worksheets("Sheet3").Cells(1, 3).Value

Dim Flip_x_coins As Integer
    Flip_x_coins = 0

Dim count As Integer
    count = 0

Dim Finished As Boolean
    Finished = False

Reset:
    Flip_x_coins = 1
For Flip_x_coins = 1 To stack
    Worksheets("Sheet3").Cells(1, 4).Value = Flip_x_coins
    count = count + 1
    If Flip_x_coins = 1 Then
        Worksheets("Sheet3").Cells(1, 1).Value = Not (Worksheets("Sheet3").Cells(1, 1).Value)
    Else
        passes = Int(Flip_x_coins) / 2
        Fst = 1
        Lst = Flip_x_coins
        For pass = 1 To passes
            If Worksheets("Sheet3").Cells(Fst, 1).Value = Worksheets("Sheet3").Cells(Lst, 1).Value Then
                    Worksheets("Sheet3").Cells(Fst, 1).Value = Not (Worksheets("Sheet3").Cells(Fst, 1).Value)
                    Worksheets("Sheet3").Cells(Lst, 1).Value = Not (Worksheets("Sheet3").Cells(Lst, 1).Value)
            End If
            Fst = Fst + 1
            Lst = Flip_x_coins - 1
        Next pass
        If Flip_x_coins Mod 2 > 0 Then
            middleCoin = (Flip_x_coins + 1) / 2
            Worksheets("Sheet3").Cells(middleCoin, 1).Value = Not (Worksheets("Sheet3").Cells(middleCoin, 1).Value)
        End If
    End If
    For testComplete = 1 To stack
        If Worksheets("Sheet3").Cells(testComplete, 1).Value = False Then
            Finished = False
            Exit For
        Else
            Finished = True
        End If
    Next testComplete
    Worksheets("Sheet3").Cells(1, 2).Value = count
If Finished = True Then
    Exit For
End If
    MsgBox "Next."
    If Flip_x_coins = stack Then
        GoTo Reset
    End If
Next Flip_x_coins

End Sub

Заранее спасибо

Привет

Ответы [ 3 ]

3 голосов
/ 09 сентября 2011

В цикле For pass = 1 To passes, Lst = Flip_x_coins - 1 неверно.

Должно быть: Lst = Lst - 1

На проходе 18 с 6 монетами макрос сравнивает строки 1 и 6 с последующимиза строками 2 и 5, за которыми следуют строки 3 и 5. Очевидно, что последнее сравнение должно быть между строками 3 и 4.

Я надеюсь, что это не домашняя работа, потому что есть много других проблем с макросом.Например:

  • нет Option Explicit в начале макроса.Это позволило вам использовать три переменные, которые вы не объявили - theStack, pass, testComplete
  • неправильное округление.Учитывая, что Flip_x_coins имеет тип Integer, passes = Int(Flip_x_coins) / 2 - нонсенс.Попробуйте passes = Int(Flip_x_coins / 2) вместо
  • , используя Goto, как правило, плохая идея.Он имеет некоторое применение в VBA для обработки ошибок, но в этом случае вы можете легко использовать конструкцию Do Until finished ... Loop вместо
0 голосов
/ 09 сентября 2011
Sub Flip()

    Dim rw As Range
    Dim numCoins As Integer
    Dim iCoins As Integer, iCoin As Integer, flipCoins As Integer
    Dim v
    numCoins = 6

    Set rw = Sheet1.Range("B2").Resize(1, numCoins) 'all start as "TRUE"
    rw.Value = True

    Do
        For flipCoins = 1 To numCoins
            For iCoin = 1 To numCoins
                If iCoin <= flipCoins Then
                    v = Not rw.Cells(flipCoins - (iCoin - 1)).Value
                Else
                    v = rw.Cells(iCoin).Value
                End If
                rw.Offset(1, 0).Cells(iCoin).Value = v
            Next iCoin
            Set rw = rw.Offset(1, 0)
            rw.EntireRow.Cells(1).Value = "Flipped " & flipCoins

            If Application.CountIf(rw, "FALSE") = 0 Then
                Debug.Print "All Heads at row " & rw.Row
                Exit Do
            End If
       Next flipCoins
   Loop While rw.Row < 1000 'don't go on for ever...
End Sub
0 голосов
/ 09 сентября 2011

Я подозреваю, что

            Fst = Fst + 1
            Lst = Flip_x_coins - 1
        Next pass

должно быть

            Fst = Fst + 1
            Lst = Lst - 1
        Next pass
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...