Внимательно посмотрите на свой код.В начале, q
равно 0, и оно увеличивается только тогда, когда вы найдете новые элементы, которые == x
.Так что
q = | {j: a[j]=x and 0 <= j < i} |
является частью вашего инварианта.Обратите внимание, что в вашей спецификации у вас было < n
вместо < i
.Также обратите внимание, что при завершении цикла i == n
.Так что это также будет действовать в начале.Это также будет правдой в любой момент: пока все хорошо.Что-то еще отсутствует?Да, мы также должны заявить, что
0 <= i <= n
- потому что это описывает диапазон значений i (в противном случае i
будет свободен выходить за пределы массива).
Isэто все?Да - нет другого состояния цикла, чтобы описать.Следовательно, ваш полный инвариант выглядит так:
q = | {j: a[j]=x and 0 <= j < i} | and 0 <= i <= n
При решении этих упражнений вы можете попробовать выполнить следующие 2 шага:
- попытаться описать простым текстом, чтоАлгоритм продолжается: «Я перемещаю
i
от 0 до n-1, останавливаясь на n, и в каждый момент я сохраняю в q
количество x
, которое я нашел в массиве».Все переменные, включенные в цикл, должны быть упомянуты!. - переводит этот простой текст в математику, а также следит за тем, чтобы ваше постусловие отражалось в инварианте, обычно заменяя
n
на счетчик цикла (в этом случае i
)
В качестве мысленного эксперимента попробуйте вместо этого написать инвариант с эквивалентным циклом (но итерируя от конца к началу):
{
int i = n-1, q = 0;
while (i >= 0){
if (a[i] == x)
q = q + 1;
i = i - 1;
}
Наведите курсор мыши для ответа (но сначала попытайтесь выяснить это).