Разбор решения. Задача 19 Урок 15. Поиск начального и конечного индексов

Разбор решения. Задача 19 Урок 15. Поиск начального и конечного индексов

Урок 15 Задача 19
Разбор одного из варинтов решения. Поиск начального и конечного индексов группы элементов в массиве.

Условие

Дан массив длиной $N$ (где $10 \leq N \lt 100 $). Найти в этом массиве отрезок длиной F (значение F вводит пользователь), такой что на нем встречаются все числа от 0 до k, где $0 \leq k \lt F $ (если отрезок такой длины F, содержащий все указанные числа, существует, в противном случае сообщите, что его не существует).

В качестве ответа (если отрезок найден) получите его начальный и конечных индекс - $m$ и $p$ ( $ 1 \leq m \lt p \leq N $, считая что массив индексируется с единицы)

Указание: Проверку массива на соответствие условиям задачи вынести в подпрограмму (процедуру, которая вычислит нужные индексы, если есть)
Подсказка: можно использовать функцию проверки отрезка в массиве из предыдущей задачи.

В условии настоятельно рекомендуется использовать функцию из решения предыдущей задачи. Пример такой функции рассмотрен в разборе решения предыдущей задачи:

Пример функции из предыдущей задачи:

function proverka (a:Arr; k: integer): boolean;
var h, j: integer;
begin
  result:= false;
  for h:= 0 to k do
  begin
    for j:= low(a) to high(a) do
      if h =a[j] then //находим сооответствующий условию элемент
        break;
    if (h=k) and (h=a[j]) then
      result:=true;
    else
      break;  //случай, когда одно из чисел от 0 до k не найдено
  end;
end;

Отличие этой задачи в том, что:

  1. проверяется не весь массив сразу, а участок заданной величины;
  2. необходимо указать номера первого и последнего элементов этого участка.

Для решения первой проблемы добавляется ещё один внешний цикл, который будет смещать "окно". Для решения второй проблемы, в основном коде задаются значения для m и p и передаются в функцию по ссылке. Функция возвращает изменённые (неизменённые) значения m и p.

type Arr=array [1..10] of integer;
var i, k, min, max,m,p, F:integer;
a: Arr;

function proverka (a:Arr; k: integer; var m,p:integer): boolean;
var h, j: integer;

begin
  result:= false;
  while p<high(a) do
  begin
    for h:= 0 to k do
    begin
      for j:= m to p do
        if h =a[j] then //находим сооответствующий условию элемент
          break;
      if (h=k) and (h=a[j]) then {если все числа до k включительно 
                                                найдены.
                                 Условие (h=a[j]) необходимо на случай, 
                                когда все числа до k найдены, и h=k,
                                но ни один элемент не равен k}
        result:=true
      else if h<>a[j] then  {если на проверяемом участке одного 
                                       из h нет,}
        break;  //сохраняется result=false
    end;
    if result=false then  //Если на этом отрезке не найдено... 
    begin
      m+=1;  //...смещается на один элемент вправо
      p+=1;
    end
    else  //Если все числа нашлись, цикл прерывается
      break;
  end;
end;

begin
  k:=3;
  F:=7;
  m:=1;
  p:=m+(F-1);

  randomize();
  min:=0;
  max:=4;
  for i:=low(a) to high(a) do
  begin
    a[i]:= min+random(max-min+1);
    write(a[i],' ');
  end;

  if not proverka(a, k,m,p) then  //m и p преданы по ссылке: 
                     //их значения должны измениться во внешнем коде
    writeln('net takogo otrezka')
  else
    writeln('m=',m,' p=',p);
  readln();
end.