|
(*~\Глагол\Отделы\Иное~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
(**) ОТДЕЛ Цепь;
(*============================================================================*
* НАЗНАЧЕНИЕ: обработка цепочек знаков (РЯД ИЗ ЗНАК или РЯД ИЗ ЦЕПЬ) *
* ПРИМЕЧАНИЯ: *
* Цепочки обычно заканчиваются знаком "0X". Их длина не может быть *
* больше МАКС(ЦЕЛ). Если выходная цепочка не помещается в ряд, *
* предназначенный для ответа, то она укорачивается до длины этого ряда. *
*============================================================================*)
ИСПОЛЬЗУЕТ
Буква,
Знак;
ВИД
Доступ-=ДОСТУП К ЦЕПЬ;
(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА Сравнить-(ц1-,ц2-:ЦЕПЬ):ЦЕЛ;
(* Возвращает результат алфавитного сравнения цепочек <ц1> и <ц2>. *)
ПЕР
р1,р2,минр,поз,отв:ЦЕЛ;
УКАЗ
р1:=РАЗМЕР(ц1);
р2:=РАЗМЕР(ц2);
ЕСЛИ р1 < р2 ТО минр:=р1 ИНАЧЕ минр:=р2 КОН;
поз:=0;
КОЛЬЦО
отв:=ВЦЕЛ(ц1[поз])-ВЦЕЛ(ц2[поз]);
ЕСЛИ (отв # 0) ИЛИ (ц1[поз] = 0X) ТО ВОЗВРАТ отв КОН;
УВЕЛИЧИТЬ(поз);
ЕСЛИ поз = минр ТО ВОЗВРАТ р1-р2 КОН
КОН;
ВОЗВРАТ 0
КОН Сравнить;
(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА ПозицияЗнака-(зн:ЗНАК; цепь-:ЦЕПЬ; поз:ЦЕЛ):ЦЕЛ;
(* Возвращает позицию первого знака <зн> в цепочке <цепь>. Поиск начинается
* с позиции <поз>. Если <зн> нет в <цепь>, то возвращает -1. *)
ПЕР
дл:ЦЕЛ;
УКАЗ
дл:=ДЛИНА(цепь);
ЕСЛИ поз < 0 ТО
поз:=0
КОН;
ПОКА (поз < дл) И (цепь[поз] # зн) ВЫП
УВЕЛИЧИТЬ(поз)
КОН;
ЕСЛИ поз >= дл ТО
поз:=-1
КОН;
ВОЗВРАТ поз
КОН ПозицияЗнака;
(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА Позиция-(обр-,цепь-:ЦЕПЬ; поз:ЦЕЛ):ЦЕЛ;
(* Возвращает позицию первого включения образца <обр> в цепочке <цепь>. Поиск
* начинается с позиции <поз>. Если <обр> нет в <цепь>, то возвращает -1. *)
ПЕР
дл,обрп,обрдл:ЦЕЛ;
УКАЗ
ЕСЛИ поз < 0 ТО
поз:=0
КОН;
дл:=ДЛИНА(цепь);
обрдл:=ДЛИНА(обр);
обрп:=0;
ПОКА (обрп < обрдл) И (поз+обрп < дл) ВЫП
ЕСЛИ цепь[поз+обрп] = обр[обрп] ТО
УВЕЛИЧИТЬ(обрп)
ИНАЧЕ
обрп:=0;
УВЕЛИЧИТЬ(поз)
КОН
КОН;
ЕСЛИ обрп # обрдл ТО
поз:=-1
КОН;
ВОЗВРАТ поз
КОН Позиция;
(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА Начало-(обр-,цепь-:ЦЕПЬ):КЛЮЧ;
(* Возвращает ВКЛ если образец <обр> является началом цепочки <цепь>. *)
ПЕР
дл,поз,обрдл:ЦЕЛ;
УКАЗ
дл:=ДЛИНА(цепь);
обрдл:=ДЛИНА(обр);
ЕСЛИ дл < обрдл ТО
ВОЗВРАТ ОТКЛ
КОН;
поз:=0;
ПОКА поз < обрдл ВЫП
ЕСЛИ цепь[поз] = обр[поз] ТО
УВЕЛИЧИТЬ(поз)
ИНАЧЕ
ВОЗВРАТ ОТКЛ
КОН
КОН;
ВОЗВРАТ ВКЛ
КОН Начало;
(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА ПохожееНачало-(обр-,цепь-:ЦЕПЬ):КЛЮЧ;
(* Возвращает ВКЛ если образец <обр> похож на начало цепочки <цепь>
* (сравнение идёт без учёта заглавных и строчных букв). *)
ПЕР
дл,поз,обрдл:ЦЕЛ;
УКАЗ
дл:=ДЛИНА(цепь);
обрдл:=ДЛИНА(обр);
ЕСЛИ дл < обрдл ТО
ВОЗВРАТ ОТКЛ
КОН;
поз:=0;
ПОКА поз < обрдл ВЫП
ЕСЛИ Буква.ВСтрочную(цепь[поз]) = Буква.ВСтрочную(обр[поз]) ТО
УВЕЛИЧИТЬ(поз)
ИНАЧЕ
ВОЗВРАТ ОТКЛ
КОН
КОН;
ВОЗВРАТ ВКЛ
КОН ПохожееНачало;
(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА Часть-(откуда-,куда+:ЦЕПЬ; откудап,дл:ЦЕЛ);
(* Переписывает часть цепочки <откуда>, начиная с позиции <откудап>, и
* длиной <дл> знаков в цепочку <куда>. *)
ПЕР
кудап,максдл:ЦЕЛ;
УКАЗ
ЕСЛИ откудап < 0 ТО
дл:=0
КОН;
максдл:=ДЛИНА(откуда)-откудап;
ЕСЛИ дл > максдл ТО
дл:=максдл
КОН;
максдл:=РАЗМЕР(куда)-1;
ЕСЛИ дл > максдл ТО
дл:=максдл
КОН;
кудап:=0;
ПОКА кудап < дл ВЫП
куда[кудап]:=откуда[откудап];
УВЕЛИЧИТЬ(кудап); УВЕЛИЧИТЬ(откудап)
КОН;
куда[кудап]:=0X
КОН Часть;
(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА Добавить-(куда+,откуда-:ЦЕПЬ);
(* Добавляет в конец цепочки <куда> цепочку <откуда>. *)
ПЕР
кудап,откудап,откудар,кудар:ЦЕЛ;
УКАЗ
кудап:=ДЛИНА(куда);
откудап:=0;
кудар:=РАЗМЕР(куда)-1;
откудар:=РАЗМЕР(откуда);
ПОКА (кудап < кудар) И (откудап < откудар) И (откуда[откудап] # 0X) ВЫП
куда[кудап]:=откуда[откудап];
УВЕЛИЧИТЬ(кудап);
УВЕЛИЧИТЬ(откудап)
КОН;
куда[кудап]:=0X
КОН Добавить;
(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА ДобавитьЗнак-(куда+:ЦЕПЬ; зн:ЗНАК);
(* Добавляет в конец цепочки <куда> знак <зн>. *)
ПЕР
кудадл:ЦЕЛ;
УКАЗ
кудадл:=ДЛИНА(куда);
ЕСЛИ кудадл+1 < РАЗМЕР(куда) ТО
куда[кудадл]:=зн;
куда[кудадл+1]:=0X
КОН
КОН ДобавитьЗнак;
(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА ДобавитьЧасть-(откуда-,куда+:ЦЕПЬ; откудап,дл:ЦЕЛ);
(* Переписывает часть цепочки <откуда>, начиная с позиции <откудап>, и
* длиной <дл> знаков в конец цепочки <куда>. *)
ПЕР
кудап,максдл:ЦЕЛ;
УКАЗ
кудап:=ДЛИНА(куда);
ЕСЛИ откудап < 0 ТО
дл:=0
КОН;
максдл:=ДЛИНА(откуда)-откудап;
ЕСЛИ дл > максдл ТО
дл:=максдл
КОН;
максдл:=РАЗМЕР(куда)-1-кудап;
ЕСЛИ дл > максдл ТО
дл:=максдл
КОН;
УВЕЛИЧИТЬ(дл,кудап);
ПОКА кудап < дл ВЫП
куда[кудап]:=откуда[откудап];
УВЕЛИЧИТЬ(кудап); УВЕЛИЧИТЬ(откудап);
КОН;
куда[кудап]:=0X
КОН ДобавитьЧасть;
(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА ВЗаглавные-(цепь+:ЦЕПЬ);
(* Переводит все буквы цепочки <цепь> в заглавные буквы. *)
ПЕР
поз:ЦЕЛ;
зн:ЗНАК;
УКАЗ
ОТ поз:=0 ДО РАЗМЕР(цепь)-1 ВЫП
зн:=цепь[поз];
ЕСЛИ зн = 0X ТО
ВОЗВРАТ
КОН;
цепь[поз]:=Буква.ВЗаглавную(зн)
КОН
КОН ВЗаглавные;
(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА ВСтрочные-(цепь+:ЦЕПЬ);
(* Переводит все буквы цепочки <цепь> в строчные буквы. *)
ПЕР
поз:ЦЕЛ;
зн:ЗНАК;
УКАЗ
ОТ поз:=0 ДО РАЗМЕР(цепь)-1 ВЫП
зн:=цепь[поз];
ЕСЛИ зн = 0X ТО
ВОЗВРАТ
КОН;
цепь[поз]:=Буква.ВСтрочную(зн)
КОН
КОН ВСтрочные;
(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА ВДос-(цепь-:ЦЕПЬ; дос+:РЯД ИЗ ЯЧЦЕЛ);
(* Переводит все знаки цепочки <цепь> в Дос знаки ряда <дос>. *)
ПЕР
знак:ЗНАК;
поз,р:ЦЕЛ;
УКАЗ
ЕСЛИ РАЗМЕР(дос) < РАЗМЕР(цепь) ТО
р:=РАЗМЕР(дос)
ИНАЧЕ
р:=РАЗМЕР(цепь)
КОН;
ОТ поз:=0 ДО р-1 ВЫП
знак:=цепь[поз];
дос[поз]:=Знак.ВДос(знак);
ЕСЛИ знак = 0X ТО
ВОЗВРАТ
КОН
КОН
КОН ВДос;
(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА ВВин-(цепь-:ЦЕПЬ; вин+:РЯД ИЗ ЯЧЦЕЛ);
(* Переводит все знаки цепочки <цепь> в Вин знаки ряда <вин>. *)
ПЕР
знак:ЗНАК;
поз,р:ЦЕЛ;
УКАЗ
ЕСЛИ РАЗМЕР(вин) < РАЗМЕР(цепь) ТО
р:=РАЗМЕР(вин)
ИНАЧЕ
р:=РАЗМЕР(цепь)
КОН;
ОТ поз:=0 ДО р-1 ВЫП
знак:=цепь[поз];
вин[поз]:=Знак.ВВин(знак);
ЕСЛИ знак = 0X ТО
ВОЗВРАТ
КОН
КОН
КОН ВВин;
(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА ИзВин-(вин-:РЯД ИЗ ЯЧЦЕЛ; цепь+:ЦЕПЬ);
(* Переводит все Вин знаки ряда <вин> в цепочку знаков. *)
ПЕР
зн:ЯЧЦЕЛ;
поз,р:ЦЕЛ;
УКАЗ
ЕСЛИ РАЗМЕР(вин) < РАЗМЕР(цепь) ТО
р:=РАЗМЕР(вин)
ИНАЧЕ
р:=РАЗМЕР(цепь)
КОН;
ОТ поз:=0 ДО р-1 ВЫП
зн:=вин[поз];
цепь[поз]:=Знак.ИзВин(зн);
ЕСЛИ зн = 0 ТО
ВОЗВРАТ
КОН
КОН
КОН ИзВин;
(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА ИзДос-(дос-:РЯД ИЗ ЯЧЦЕЛ; цепь+:ЦЕПЬ);
(* Переводит все Дос знаки ряда <дос> в цепочку знаков. *)
ПЕР
зн:ЯЧЦЕЛ;
поз,р:ЦЕЛ;
УКАЗ
ЕСЛИ РАЗМЕР(дос) < РАЗМЕР(цепь) ТО
р:=РАЗМЕР(дос)
ИНАЧЕ
р:=РАЗМЕР(цепь)
КОН;
ОТ поз:=0 ДО р-1 ВЫП
зн:=дос[поз];
цепь[поз]:=Знак.ИзДос(зн);
ЕСЛИ зн = 0 ТО
ВОЗВРАТ
КОН
КОН
КОН ИзДос;
(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА Удалить-(откуда+:ЦЕПЬ; удалп,удалдл:ЦЕЛ);
(* Удаляет <удалдл> знаков цепочки <откуда>, начиная с позиции <удалп>. *)
ПЕР
откудадл:ЦЕЛ;
УКАЗ
откудадл:=ДЛИНА(откуда);
ЕСЛИ (удалдл < 1) ИЛИ (удалп < 0) ИЛИ (удалп >= откудадл) ТО
ВОЗВРАТ
КОН;
ЕСЛИ удалдл > откудадл-удалп ТО
удалдл:=откудадл-удалп
КОН;
откудадл:=откудадл-удалдл;
ПОКА удалп < откудадл ВЫП
откуда[удалп]:=откуда[удалп+удалдл];
УВЕЛИЧИТЬ(удалп)
КОН;
откуда[удалп]:=0X
КОН Удалить;
(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА УдалитьКонПробелы-(цепь+:ЦЕПЬ);
(* Удаляет пробелы в конце цепочки <цепь>. *)
ПЕР
поз:ЦЕЛ;
УКАЗ
поз:=ДЛИНА(цепь)-1;
ПОКА (поз >= 0) И (цепь[поз]=" ") ВЫП
УМЕНЬШИТЬ(поз)
КОН;
цепь[поз+1]:=0X
КОН УдалитьКонПробелы;
(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА УдалитьНачПробелы-(цепь+:ЦЕПЬ);
(* Удаляет пробелы в начале цепочки <цепь>. *)
ПЕР
поз,р:ЦЕЛ;
УКАЗ
поз:=0;
р:=РАЗМЕР(цепь);
ПОКА (поз < р) И (цепь[поз]=" ") ВЫП
УВЕЛИЧИТЬ(поз)
КОН;
Удалить(цепь,0,поз)
КОН УдалитьНачПробелы;
(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА УдалитьПробелы-(цепь+:ЦЕПЬ);
(* Удаляет пробелы в начале и конце цепочки <цепь>. *)
УКАЗ
УдалитьНачПробелы(цепь);
УдалитьКонПробелы(цепь)
КОН УдалитьПробелы;
(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА ВставитьЗнак-(зн:ЗНАК; куда+:ЦЕПЬ; кудап:ЦЕЛ);
(* Вставляет знак <зн> в цепочку <куда> в позиции <кудап>,
* если для этого есть место. *)
ПЕР
поз,кудадл:ЦЕЛ;
УКАЗ
кудадл:=ДЛИНА(куда);
ЕСЛИ кудадл+1 < РАЗМЕР(куда) ТО
ЕСЛИ кудап < 0 ТО
кудап:=0
АЕСЛИ кудап > кудадл ТО
кудап:=кудадл
КОН;
поз:=кудадл+1;
ПОКА поз > кудап ВЫП
куда[поз]:=куда[поз-1];
УМЕНЬШИТЬ(поз)
КОН;
куда[поз]:=зн
КОН
КОН ВставитьЗнак;
(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА Вставить-(откуда-,куда+:ЦЕПЬ; кудап:ЦЕЛ);
(* Вставляет цепочку <откуда> в цепочку <куда> в позиции <кудап>.
* Копирует знаков не больше, чем умещается в <куда>. *)
ПЕР
откудап,кудадл,откудадл:ЦЕЛ;
УКАЗ
откудадл:=ДЛИНА(откуда);
кудадл:=ДЛИНА(куда);
ЕСЛИ кудадл+откудадл+1 > РАЗМЕР(куда) ТО
откудадл:=РАЗМЕР(куда)-кудадл-1
КОН;
ЕСЛИ кудап < 0 ТО
кудап:=0
АЕСЛИ кудап > кудадл ТО
кудап:=кудадл
КОН;
откудап:=кудадл;
ПОКА откудап >= кудап ВЫП
куда[откудап+откудадл]:=куда[откудап];
УМЕНЬШИТЬ(откудап)
КОН;
откудап:=0;
ПОКА откудап < откудадл ВЫП
куда[кудап+откудап]:=откуда[откудап];
УВЕЛИЧИТЬ(откудап)
КОН
КОН Вставить;
(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА ДобавитьКонПробелы-(цепь+:ЦЕПЬ; дл:ЦЕЛ);
(* Увеличивает длину цепочки <цепь> до <дл> знаков, добавляя в конец пробелы.
* Если <цепь> уже достаточной длины, то не производит никаких изменений. *)
ПЕР
поз,р:ЦЕЛ;
УКАЗ
р:=РАЗМЕР(цепь);
ЕСЛИ дл+1 > р ТО
дл:=р-1
КОН;
поз:=ДЛИНА(цепь);
ЕСЛИ поз < дл ТО
ПОКА поз < дл ВЫП
цепь[поз]:=" ";
УВЕЛИЧИТЬ(поз)
КОН;
цепь[дл]:=0X
КОН
КОН ДобавитьКонПробелы;
(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА ДобавитьНачПробелы-(цепь+:ЦЕПЬ; дл:ЦЕЛ);
(* Увеличивает длину цепочки <цепь> до <дл> знаков, добавляя в начало пробелы.
* Если <цепь> уже достаточной длины, то не производит никаких изменений. *)
ПЕР
поз,р:ЦЕЛ;
УКАЗ
р:=РАЗМЕР(цепь);
ЕСЛИ дл+1 > р ТО
дл:=р-1
КОН;
поз:=ДЛИНА(цепь);
ЕСЛИ поз < дл ТО
ПОКА поз > 0 ВЫП
цепь[дл]:=цепь[поз];
УМЕНЬШИТЬ(дл);
УМЕНЬШИТЬ(поз)
КОН;
ПОКА дл > 0 ВЫП
цепь[дл]:=" ";
УМЕНЬШИТЬ(дл)
КОН;
КОН
КОН ДобавитьНачПробелы;
КОН Цепь.
|
|