То, что не меняется в алгоритме
k :=0
for i ←1 to n
c←a[i]
k←k+1
это алгоритм, чтобы узнать количество элементов
1 ответ
Технически, да, k <= i
является инвариантом, но не очень полезным. Причина, по которой мы используем инварианты, заключается в том, что мы можем использовать их для проверки состояния после цикла. С вашим инвариантом вы можете доказать, что k <= n
держит после цикла. Хотя это очень верно, это не поможет вам попытаться доказать, что на самом деле делает цикл.
Так какой вид инварианта будет полезен? Мы хотим доказать это k
равно количеству элементов, которые оба в a
а также b
, Так как мы перебираем элементы в a
хорошим выбором будет: k
равно количеству элементов до a[i]
которые также находятся в b
,
Теперь нам нужно доказать, что этот инвариант имеет место. Я сделаю это немного отрывочно, так что вы все еще можете оформить это.
Сначала нам нужно показать, что k = 0
количество элементов перед a[1]
которые также находятся в b
, Там нет таких элементов, поэтому k = 0
верно.
Теперь, учитывая, что ki
это количество элементов до a[i]
которые также находятся в b
нам нужно доказать, что инвариант выполняется для i+1
, Есть два варианта: либо a[i+1]
в b
, или нет.
- Если
a[i+1]
вb
, то количество элементов доa[i + 1]
которые находятся вb
на единицу больше, чем количество элементов доa[i]
которые находятся вb
, Используя наш инвариант, мы должны показать, чтоki+1 = ki + 1
, - Если
a[i+1]
не вb
, то количество элементов доa[i + 1]
которые находятся вb
равно количеству элементов доa[i]
которые находятся вb
, Используя наш инвариант, мы должны показать, чтоki+1 = ki
,
Я оставлю это на ваше усмотрение, чтобы доказать это.