Със сигурност знаем, че последният елемент трябва да е 11, така че вече можем да проверим за това и да улесним живота си за тестване на всички предишни елементи. Ние гарантираме, че A
е 11-терминиран, така че подходът на „елементна промяна“ (по-долу) ще бъде валиден. Обърнете внимание, че същото важи и за началото, но промяната на A
там ще затрудни индексите, така че е по-добре да се погрижим за това по-късно.
missing = [];
if A(end) ~= 11
missing = [missing; 11, length(A) + 1];
A = [A, 11];
end
След това можем да изчислим промяната dA = A(2:end) - A(1:end-1);
от един елемент към друг и да идентифицираме позициите на пропуските idx_gap = find((dA~=1) & (dA~=-11));
. Сега трябва да разширим всички липсващи индекси и очаквани стойности, като използваме ev
за очакваната стойност. ev
може да се получи от предишната стойност, както в
for k = 1 : length(idx_gap)
ev = A(idx_gap(k));
Сега броят на елементите за попълване е промяната dA
в тази позиция минус едно (защото едно означава липса на празнина). Обърнете внимание, че това може да се обвие, ако има празнина на границата между сегментите, така че използваме модула.
for n = 1 : mod(dA(idx_gap(k)) - 1, 12)
ev = mod(ev + 1, 12);
missing = [missing; ev, idx_gap(k) + 1];
end
end
Като тест разгледайте A = [5 6 7 8 9 10 3 4 5 6 7 8 9 10 11 0 1 2 3 4 6 7 8]. Това е случай, в който специалната инициализация от самото начало ще се задейства, запаметявайки вече липсващите 11 и променяйки A на [5 6 ... 7 8 11]. missing
тогава ще отстъпи
11 24 % recognizes improper termination of A.
11 7
0 7 % properly handles wrap-over here.
1 7
2 7
5 21 % recognizes single element as missing.
9 24
10 24
което трябва да е това, което очаквате. Това, което все още липсва, е началото на A
, така че нека кажем missing = [0 : A(1) - 1, 1; missing];
, за да завършим списъка.
person
s.bandara
schedule
31.10.2013
arrayfun
може да се справи с това в няколко реда. Решението обаче е доста непрозрачно (вижте моя отговор). - person chappjc   schedule 01.11.2013