Сформировать на экране таблицу ASCII
Задание 3.01. Формирование таблицы ASCII
Сформировать на экране таблицу ASCII таким образом, чтобы в ней были представлены все отображаемые символы 866-й кодовой страницы и их числовые коды. Один из возможных вариантов заполнения экрана такой таблицей представлен на рис. 3.1.
Совет 1 (общий)
Приведенная выше таблица содержит 21 кодовую строку, и смещение начальных кодов в смежных колонках равно 21. Поэтому внешний цикл повторяется 21 раз, начинаясь с первого отображаемого кода (32 — код пробела). Так как заголовок отделен от таблицы одной пустой строкой, вывод начинается с 3-й строки (3 = 32 - 29). А дальше остается только перебирать все коды отображаемого диапазона (от 32 до 255) и выводить пары "символ-код" по фиксированному формату — одна позиция под символ, разделяющий пробел, три позиции — под числовой код и пара пробелов между колонками.
Рис. 3.1. Таблица ASCII
Программа 3_01.bas
RЕМ Вывод таблицы ASCII
CLS : PRINT TAB(31); "Таблица ASCII"
FOR I=32 TO 52: LOCATE I-29,1
FOR J=I TO 255 STEP 21
PRINT USING "! ### ";CHR$(J);J;
NEXT J
NEXT I
Программа 3_01.с
/* Вывод таблицы ASCII */
#include <stdio.h>
main() {
int i,j;
clrscr ();
gotoxy(31,1);
printf("Таблица ASCII");
for (i=32; i<=52; i++) {
gotoxy(1,i —2 9) ;
for (j=i; j<=255; j+=21)
printf("%c %3d ",j,j);
} getch();
}
Программа 3_01.pas
program ASCII; {Вывод таблицы ASCII} uses Crt; var
i,j:word; begin clrscr;
gotoxy(31,1);
write('Таблица ASCII');
for i:=32 to 52 do
begin
gotoxy(l,i-29);
j:=i;
repeat
write(chr(j) :l,j:4, ' ');
j:=j+21;
until j>255;
end;
readln;
end.
Задание 3.02. Преобразование строк к верхнему регистру
Составить подпрограмму (функцию) up (s), которая заменяет в строке s коды малых букв кодами аналогичных больших букв с учетом их расположения в таблице ASCII.
Совет 1 (общий)
По этой же таблице можно установить, что смещения в кодах между выделенными группами малых букв и их прописными эквивалентами, соответственно, равны 32, 32, 80 и 1 позициям.
Совет 2 (QBasic)
Для выделения и изменения j-гo символа строки s удобнее всего воспользоваться функцией (оператором) MID$(S,J, 1). Анализ на принадлежность одному из кодовых интервалов, подлежащему замене, целесообразно оформить в виде переключателя SELECT CASE — END SELECT. Наконец, функции ASC и CHR$ понадобятся, соответственно, для преобразования символа в код ASCII и модифицированного кода в символ эквивалентной большой буквы.
В приводимых ниже двух вариантах программы преобразование к верхнему регистру выполнено в виде подпрограммы UP и функции UP$. Чтобы не портить аргумент функции и другие глобальные переменные головной программы, в теле функции объявлены свои локальные переменные в и j.
Совет 3 (Си)
Обратите внимание на то, что локальный массив ь, объявленный в теле функции up, имеет тип unsigned char, а не char. Объясняется это тем, что проверяемые коды (а они в теле функции выступают как числа) принадлежат диапазону [0,255].
Совет 4 (Паскаль)
Обратите внимание на то, что в теле функции не понадобился промежуточный массив b, т. к. параметр а передавался не по адресу (не var a:string), а по значению. Поэтому исходная строка оказалась в стеке, и ею можно было воспользоваться в теле функции, не опасаясь порчи параметра в вызывающей программе.
Программа 3_02.bas
REM Замена малых русских букв большими
DECLARE SUB UP (A$)
PRINT "Введите строку, содержащую малые и большие буквы"
INPUT "",A$
UP A$
PRINT A$ END
SUB UP(A$)
FOR j=l TO LEN(A$)
SELECT CASE MID$(A$,j,l)
CASE "a" TO "z": MID$(A$,j,1)=CHR$(ASC(MID$(A$, j , 1) )-32)
CASE "a" TO "n": MID$(A$,j,l)=CHR$(ASC(MID$(A$,j,l))-32)
CASE "p" TO "я": MID$(A$,j,1)=CHR$(ASC(MID$(A$,j,1))-90)
CASE "e": MID$(A$,j,l)="E"
END SELECT
NEXT j
END SUB
Программа 3_02a.bas
RЕМ Замена малых русских букв большими
DECLARE FUNCTION UP$(A$)
PRINT "Введите строку, содержащую малые и большие буквы"
INPUT "",A$
B$=UP$(A$)
PRINT A$
PRINT B$
END
FUNCTION UP$(A$)
'Чтобы не испортить аргумент А$, введена локальная переменная
DIM В AS STRING
В=А$
FOR J=l TO LEN(A$)
SELECT CASE MID$(В,J,1)
CASE "a" TO "z": MID$ (B, J, 1) =CHR$ (ASC (MID$ (B, J, 1) )-32)
CASE "a" TO "n": MID$ (B, J, 1)=CHR$ (ASC (MID$ (B, J, 1) ) -32)
CASE "p" TO "я": MID$(B,J,1)=CHR$(ASC(MID$(B,J,1))-80)
CASE "e": MID$(B,J,1)="E"
END SELECT
NEXT J
UP$=B
END FUNCTION
Программа 3_02.с
/* Замена малых русских букв большими */
# include <stdio.h>
#include <conio.h>
#include <string.h>
char *up(char *a);
void main() {
char a[80],*b;
printf("\n Введите строку, содержащую малые и большие буквы\n");
gets(a);
b=up(а);
printf("\na=%s",a);
printf("\nb=%s",b);
getch (); }
char *up(char *a) {
unsigned char b[80]; int j ;
strcpy(b,a);
for(j=0; j<strlen(a); j++) {
if ( 97<=b[j] && b[j]<=122) b[j]-=32;
if (160<=b[j] && b[j]<=175) b[j]-=32;
if (224<=b[j] && b[j]<=239) b[j]-=80;
if (241==b[j]) b[j]— ; }
return b; }
Программа 3_02.pas
program UperCase;
{ Замена малых русских букв большими }
var
a,b>:string[80] ; function up(a:string):string; var
j:integer;
begin
for j:=1 to length(a) do
case a[j] of
'a1..'z': a[j] :=chr (ord (a [ j ] )-32) ;
'a'.,'n'; a[j]:=chr(ord(a[j])-32);
'р'.'я': a[j]:=chr(ord(a[j])-80);
'ё': a[j]:='Ё'; end;
up:=a; end; begin
writeln('Введите строку, содержащую малые и большие буквы ');
readln(a);
b:=uр(а);
writeln(a);
writeln(b);
readln;
end.
Задание 3.03. Сортировка-фамилий
Составить программу, которая запрашивает у пользователя 10 фамилий, сортирует их по алфавиту и выводит отсортированный список. Пока сортируемый массив мал, мы не будем обращать внимание на эффективность алгоритма сортировки. Один из следующих разделов специально будет посвящен этому достаточно сложному и важному вопросу.
Так как программа должна сортировать фамилии, то следует установить правила их набора на клавиатуре, исключающие неоднозначность результатов сравнений:
Такие правила позволят вам не обращать внимания на различие между кодами больших и малых букв, т. к. сравниваться между собой, как правило, будут буквы одного регистра, коды которых соответствуют лексикографическому порядку. Коды инициалов и символы-разделители (точки, пробелы, тире) в таблице ASCII расположены раныпе кодов малых букв и поэтому на результаты сравнений не повлияют.
Совет 1 (общий)
Для повышения наглядности результатов работы программы можно вывести на экран два списка фамилий: слева — неупорядоченный, справа — упорядоченный.
Совет 2 (QBasic)
Для перевода курсора в позицию, соответствующую очередной строке списка, надо воспользоваться оператором LOCATE row, col (row — номер строки, col — номер столбца).
Совет 3 (Си)
В программе 3_03а.с демонстрируется одна из уловок, повышающая эффективность работы любой программы сортировки достаточно длинных документов. С подобного рода приемами вы неоднократно сталкивались, но, возможно, не обращали на них внимания. Например, на панелях Norton Commander'a можно выбрать один из нескольких способов упорядочения оглавления — по именам файлов, по их расширениям, по размерам, по датам создания, в порядке появления файлов на диске. Естественно, что такого рода сортировки не производят никаких перемещений файлов на диске. Вместо этого происходят перестановки каких-то указателей в оперативной памяти.
В программе 3_03а. с для размещения фамилий использованы динамически запрашиваемые строки, на начало которых "смотрят" элементы массива указателей типа char (см. обращение к функции malloc). Вместо перестановки фамилий, расположенных не в алфавитном порядке, меняются местами соответствующие 4-байтовые указатели.
Перевод курсора в начало очередной строки списка осуществляется функцией gotoxy (col, row), последовательность параметров которой прямо противоположна соответствующему оператору QBasic.
Программа 3_03b!с построена менее замысловато. В ней использован двумерный массив для хранения фамилий, да и вывод результатов оформлен попроще.
Программа 3_03.bas
RЕМ Сортировка фамилий DIM NAMES(10)
N=10
CLS
FOR J=l TO 10
INPUT "Введи очередную фамилию - ", NAMES(J)
NEXT J CLS
PRINT "Фамилии до упорядочения : " FOR J=l TO N
LOCATE J+2,1: PRINT NAMES(J)
NEXT J
FOR J=l TO N-l
FOR K=J+1 TO N
IF NAME$(J)>NAME$(K) THEN
TMP$=NAME$(J)
NAME$(J)=NAME$(K)
NAMES(K)=TMP$
END IF
NEXT К
NEXT J
LOCATE 1,40
PRINT "Фамилии после упорядочения :"
FOR J=l TO N
LOCATE J+2,40: PRINT NAME$(J)
NEXT J
END
Программа 3_03а.с
/* Сортировка фамилий */
#include <stdio.h>
#include <alloc.h>
#include <conio.h>
#include <string.h>
main()
{
#define n_max 10
#define len_max 20
int j,k;
char tmp[len_max], *names[n_max], *p;
clrscr();
for(j=0; j< n_max; j++) {
printf("\n Введи очередную фамилию - ");
scanf("%s",tmp);
names[j]=(char *)malloc(len_max);
strcpy(names[j],tmp); }
clrscr () ;
printf("Фамилии до упорядочения :");
for(j=0; j<n_max; j++) {
gotoxyd, j+2) ;
printf("%s",names[j]); }
for(j=0; j<n_max-l; j++)
for(k=j+l; k<n_max; k++) {
if (strcmp(names[j],names[k]) > 0} {
p=names[j];
names[j]=names[k] ;
names[k]=p; } }
gotoxy(40,1);
printf("Фамилии после упорядочения :");
for(j=0; j<n_max; j++) {
gotoxy(40,j+2);
printf("%s",names[j]) ; }
getch(); }
Программа 3_03b.c
/* Сортировка фамилий */
#include <stdio.h>
#include <conio.h>
#include <string.h>
#define N 10
main () {
cnar a[N][20],tmp[20];
int i,j; Clrscr () ;
puts(" Введите 10 фамилий по одной в строке");
for(i=0; i<N; i++)
gets(&a[i][0]);
for(1=0; i<N-l; 1++)
for(j=i+l; j<N; j++)
if(strcmp(&a[i] [0], &a[j] [0])>0) {
strcpy(tmp,&a[i][0]);
strcpy(&a[i][0],&a[j][0]);
strcpy(&a[j][0],tmp); }
puts("А теперь они же по алфавиту");
for (1=0; i<N; i++)
puts(&a[i][0]);
getch(); }
Программа 3_03.pas
program sort;
{ Сортировка фамилий }
uses crt;
const
n=10; var
j,k:integer; tmp:string[20];
name:array [l..n] of string[20];
begin cirscr;
for j:=1 to n do begin
writeln('Введи очередную фамилию');
readln(name[j]); end;
clrscr;
writeln('Фамилии до упорядочения :');
for j :=1 to n do
begin
gotoxy(1,j+2);
write(name[j]);
end;
for j:=1 to n-1 do
{
for k:=j+l to n do
begin
if name[j]>name[k] then
begin
tmp:=name [j];
name[j]:=name[k];
name[k]:=tmp;
end
end;
gotoxy(40,l);
writeln('Фамилии после упорядочения :');
for j:=1 to n do
begin
gotoxy (40,j+2);
write(name[j]);
end;
readln;
end.
Задание 3.04. Подсчет числа слов в строке
Предполагая, что вводимая строка содержит не более 80-ти символов и состоит из "слов", разделенных одним или более пробелами, подсчитать количество слов в строке. Обратите внимание на критические ситуации — строка пуста, строка состоит из одних пробелов, строка содержит единственное слово, слова могут содержать единственный символ, отличный от пробела.
Совет 1 (общий)
В начале следует проверить длину введенной строки и, если она равна 0, сообщить, что число слов тоже равно 0. Затем имеет смысл проверить первый символ строки и, если он отличен от пробела, зафиксировать начало первого слова. Дальнейший анализ можно оформить в виде цикла, в котором проверяется очередной символ строки с учетом одной из двух возможных ситуаций - ему предшествовал пробел или символ, отличный от пробела. При переходе с пробела на непробел счетчик слов следует увеличить на 1. Переменная space хрэиит информацию о предшествующем символе — она равна 1 млм true, если предшествовавшим символом был пробел. Ее значение меняется на противоположное, если только один из двух смежных символов является пробелом.
Программа 3_04.bas
RЕМ Подсчет числа слов в строке
CLS
SPACE=1: WORDS=0
PRINT "Введите строку"
INPUT "",S$
LENS=LEN(S$)
IF LENS=0 THEN GOTO RET
IF LEFT$(S$,1)<>" " THEN SPACE=0: WORDS=1
FOR J=2 TO LENS
IF SPACE=1 AND MID$(S$,J,1)<>" " THEN SPACE=0: WORDS=WORDS+1
IF SPACE=0 AND MID$(S$,J,1)=" " THEN SPACE=1
NEXT J
RET:
PRINT "Число слов в строке = "; WORDS
END
Программа 3_04.с
/* Подсчет числа слов в строке */
#include <stdio.h>
#include <conio.h>
#include <string.h>
main() {
char s[81], space=l, words=0, i,len;
clrscr ();
puts("Введите строку");
gets (s) ;
len=strlen(s);
if (len=0) goto ret;
if (s[0]!=' ') {
space=0;
words=l; }
for(i=l; i<len; i++) (
if (space==l &&, s[i]! = ' ') {
space=0; words++; }
if (space==0 && s[i]==' ')space=l; } ret:
printf("\n Число слов в строке = %d",words);
getch () ; }
Программа 3_04.pas
program num_words;
{ Подсчет числа слов в строке }
label ret;
var
s:string[81];
space:boolean;
words:byte;
i,len:byte; begin
writeln('Введите строку');
readln(s);
len:=length(s);
if len=0 then goto ret;
space:=(s[1]=' ');
if not space then words:=1;
for i:=2 to len do
begin
if (not space)and(s[i]=' ') then space:=true;
if (space)and(s[i]<>' ') then
Degin
space;=false; inc(words);
end;
end;
ret:
writeln('Число слов в строке = ',words);
readln;
end.
Задание 3.05. Анализ нажатой клавиши
Составить программу, которая анализирует код нажатой клавиши и выводит его на экран. Программа должна завершать свою работу после нажатия клавиши <Esc> (код клавиши равен 27).
Совет 1 (общий)
В программе необходимо организовать бесконечный цикл, прерываемый после приема кода клавиши <Esc>. К сожалению, обработку клавиши <Enter> не удается включить в цикл обработки обычных клавиш. В операторах вывода попытка отобразить символ с кодом 13 приводит либо к возврату курсора в начало строки и затиранию ранее напечатанного текста последующим сообщением (Си, Паскаль), либо к-переводу курсора в начало следующей строки (QBasic).
Совет 2 (QBasic)
Для ввода кода нажатой клавиши целесообразно использовать функцию (служебную переменную) INKEY$. Если нажата обычная клавиша, то INKEY$ выдает один символ, код которого можно определить по значению функции ASC. При нажатии функциональной клавиши в INKEY$ попадает два символа, первый из которых имеет нулевой код, поэтому выводить на экран надо код второго символа.
Совет 3 (Си)
Для ввода кода нажатой клавиши необходимо один (обычная клавиша) или два раза (функциональная клавиша) обратиться к функции getch.
Совет 4 (Паскаль)
Для ввода кода нажатой клавиши необходимо один (обычная клавиша) или два раза (функциональная клавиша) обратиться к функции readkey.
Программа 3_05.bas
RЕМ Анализ кода нажатой клавиши CLS
GETKEY: A$=INKEY$: IF A$="" THEN GOTO GETKEY
IF ASC(A$)=27 THEN STOP
IF LEN(A$)=1 THEN
IF ASC(A$)=13 THEN
PRINT "Нажата клавиша Enter с кодом = 13": GOTO GETKEY
END IF
PRINT "Нажата обычная клавиша ' "; A$; " ' с кодом ="; ASC(A$)
ELSE
PRINT "Нажата управляющая клавиша с кодом ";ASC(RIGHT$(A$,1))
END IF
GOTO GETKEY
Программа 3_05.с
/* Анализ кода нажатой клавиши */ #include <stdio.h>
main() { unsigned char ch;
clrscr(); getkey:
ch=getch();
if(ch==27) exit(0);
if(ch==13) {
printf("\n Нажата клавиша Enter с кодом = 13");
goto getkey; }
if(ch==0) {
ch=getch();
printf("\n Нажата управляющая клавиша с кодом = %d",ch); }
else printf("\n Нажата обычная клавиша %с с кодом=%d",ch,ch);
goto getkey;
}
Программа 3_05.pas
program keyboard;
( Анализ кода нажатой клавиши }
uses Crt;
label getkey;
var
ch:char;
begin
clrscr; getkey:
ch:=readkey;
if ord(ch)=27 then exit;
if ord(ch)=13 then
begin
writeln('Нажата обычная клавиша Enter с кодом = 13');
goto getkey;
end;
if ord(ch)=0 then
begin
ch:=readkey;
writeln('Нажата управляющая клавиша с кодом = ',ord(ch));
end else
writeln('Нажата обычная клавиша "',ch,'" с кодом=',ord(ch));
goto getkey; end.
Программа 3_05a.pas
program keyboard;
{ Анализ кода нажатой клавиши }
uses Crt;
var
ch:char; begin clrscr; repeat
ch:=readkey;
if ord(ch)=13 then
writeln('Нажата обычная клавиша Enter с кодом =13') else
if ord(ch)=0 then
begin
ch:=readkey;
writeln { 'Нажата управляющая клавиша с кодом = ' ,ord(ch) } ;
end else
writeln('Нажата обычная клавиша "',ch,'" с кодом = ',ord(ch});
until ord(ch)=27;
end.
Задание 3.06. Три цвета радуги
Мнемоническая фраза " Каждый охотник желает знать, где сидят фазаны" используется для запоминания последовательности цветовых оттенков радуги — красный, оранжевый, желтый, зеленый, голубой, синий, фиолетовый. Составить программу, которая вводит три слова, представляющие разные цвета радуги, и выводит их на экран в том порядке, в каком они должны быть расположены в описанной выше цветовой гамме. Например, введены слова желтый, красный и синий. На экран их следует вывести в "правильном" порядке — красный, желтый, синий.
Совет 1 (общий)
Можно завести массив слов, соответствующих последовательности цветов радуги, и устроить цикл, проверяющий, не содержится ли очередной цвет среди введенных слов.
Программа 3_06.bas
REM Упорядочение цветов радуги
DATA "красный","оранжевый","желтый","зеленый"
DATA "голубой","синий","фиолетовый"
DIM А$ (7) , В$ (3)
FOR I=0 ТО 6: READ A$(I): NEXT I
PRINT "Введите по одному в строке 3 цвета радуги"
FOR I=0 ТО 2: INPUT B$ (I): NEXT I
PRINT "В радуге эти цвета следуют в таком порядке:"
FOR J=0 TO 6: FOR I=0 TO 2
IF A$(J)=B$(I) THEN PRINT A$(J)
NEXT I: NEXT J
END
Программа 3_06.c
/* Упорядочение цветов радуги */
#include <stdio.h>
#include <conio.h>
#include <string.h> main()
{
char a[7][11]={"красный","оранжевый",
"желтый","зеленый","голубой","синий","фиолетовый"};
char b[3][11]; int i,j;
printf("\n Введите по одному в строке 3 цвета радуги\n");
for (i=0; КЗ; i++) gets (&b[i] [0] ) ;
printf("\ nB радуге эти цвета следуют в таком порядке:\n");
for(j=0; j<7; j++) for(i=0; i<3; i++)
if(strcmp(&a[j][0],&b[i][0])==0)
puts(&a[j][0]); getch(); }
Программа 3_06.pas
program raduga;
{ Упорядочение цветов радуги }
const
a:array [1..7] of string[10]=('красный','оранжевый',
' желтый', ' зеленый', ' голубой', ' синий', ' фиолетовый') ;
var
b:array [1..3] of string[10];
i,j:byte; begin
writeln('Введите по одному в строке 3 цвета радуги');
for i:=l to 3 do readln(b[i]);
writeln('В радуге эти цвета следуют в таком порядке:');
for j:=1 to 7 do
for i:=l to 3 do
if a[j]=b[i] then writeln(a[j]);
readln;
end.
Задание 3.07. Левый и правый прижим, центрирование текста при выводе
Составить программу, которая запрашивает у пользователя текст, содержащий не более 20-ти символов, и выводит его в рамках колонки, расположенной с 10-й по 50-ю позиции с разными вариантами прижима. Для контроля правильности работы программы можно ограничиться вводом единственного символа и выдачей на экран строки, маркирующей номера колонок.
Совет 1 (QBasic)
Для смещения текста в нужную позицию строки можно воспользоваться либо функцией TAB, либо переводом курсора с помощью оператора LOCATE.
Совет 2 (Си, Паскаль)
Для перевода курсора в нужную позицию текущей строки можно воспользоваться процедурой gotoxy, у которой в качестве первого аргумента задан номер начальной колонки, а в качестве второго — значение функции wherey, соответствующее номеру текущей строки.
Программа 3_07.bas
CLS
PRINT "Введите строку, содержащую не более 20 символов"
FOR I = 1 ТО 8: PRINT "1234567890"; : NEXT I
INPUT "", A$
PRINT "Вывод, начиная с 10-й позиции :"
FOR I = 1 ТО 8: PRINT "1234567890"; : NEXT I
PRINT TAB(10); A$
PRINT "Вывод по центру между 10-й и 50-й позициями :"
FOR I = 1 ТО 8: PRINT "1234567890"; : NEXT I
PRINT TAB(10 + (50 - 10) / 2 - LEN(A$) / 2); A$
PRINT "Вывод с прижимом к 50-й позиции :"
FOR I = 1 ТО 8: PRINT "1234567890"; : NEXT I
PRINT TAB(51 - LEN(A$)); A$
END
Программа 3_07.с
#include <stdio.h>
#include <conio.h>
#include <string. h>
main()
{
char str[20], rule [] ="1234567890";
int i;
clrscr () ;
puts(" Введите строку, содержащую не более 20 символов");
for(i=0; i<8; i++)
printf("%s",rule);
gets (str) ;
puts("Вывод, начиная с 10-й позиции :");
for(i=0; i<8; i++) printf("%s",rule);
gotoxy(10,wherey()); puts (str) ;
puts("Вывод по центру между 10-й и 50-й позициями :");
for(i=0; i<8; i++) printf("%s",rule);
gotoxy(10+(50-10)/2-strlen(str)/2,wherey());
puts(str);
puts("Вывод с прижимом к 50-й позиции :");
for (i=0; i<8; i++) printf("%s", rule);
gotoxy(51-strlen(str),wherey());
puts(str);
getch(); }
Программа 3_07.pas
program text_justify;
uses Crt;
const
rule:string='1234567890'; var
s:string[20];
i:integer; begin
clrscr;
writeln('Введите строку, содержащую не более 20 символов');
for i:=0 to 7 do write(rule);
readln(s);
writeln('Вывод, начиная с 10-й позиции :');
for i:=0 to 7 do write(rule);
gotoxy(10,wherey); writeln(s);
writeln('Вывод по центру между 10-й и 50-й позициями :');
for i:=0 to 7 do write(rule);
#include <string.h>
main() {
char str[20], rule[]="1234567890";
int i ;
clrscr();
puts("Введите строку, содержащую не более 20 символов");
for(i=0; i<8; i++)
printf("%s",rule);
gets (str) ;
puts("Вывод, начиная с 10-й позиции :");
for(i=0; i<8; i++) printf("%s",rule);
gotoxy(10,wherey()); puts (str) ;
puts("Вывод по центру между 10-й и 50-й позициями :");
for (i=0; i<8; i++) printf("%s",rule);
gotoxy(10+(50-10)/2-strlen(str)/2,wherey());
puts(str); puts("Вывод с прижимом к 50-й позиции :");
for (i=0; i<8; i++)
printf("%s",rule);
gotoxy(51-strlen(str),wherey());
puts(str);
getch(); }
Программа 3_07.pas
program text justify;
uses Crt;
const
rule:string='1234567890'; var
s:string[20];
i:integer; begin
clrscr;
writeln(' Введите строку, содержащую не более 20 символов');
for i:=0 to 7 do write(rule);
readln(s);
writeln('Вывод, начиная с 10-й позиции :');
for i:=0 to 7 do write(rule);
gotoxy(10,wherey); writeln(s);
writeln('Вывод по центру между 10-й и 50-й позициями :');
for i:=0 to 7 do write(rule);
gotoxy(10+(50-10) div 2 - length(s) div 2,wherey);
writeln(s); writeln{'Вывод с прижимом к 50-й позиции :');
for i:=0 to 7 do write(rule);
gotoxy(51-length(s),wherey);
writeln(s);
readln; end.
Задание 3.08. Сравнение строк с игнорированием пробелов
Написать подпрограмму-функцию compare, имеющую своими аргументами две строки, которая сравнивает их, игнорируя пробелы между словами и разницу между кодами больших и малых букв. Функция должна возвращать следующие значения: 1, если первая строка "больше" второй; -1, если первая строка "меньше" второй; о, если обе строки равны.
Совет 1 (общий)
Самым простым по реализации является алгоритм, в котором сначала коды всех малых букв заменяются кодами их больших эквивалентов, а затем из строк удаляются пробелы. Для выполнения первой процедуры можно воспользоваться функцией up (str) — см. программу 3_02.
Программа 3_08.bas
REM Сравнение строк с игнорированием пробелов
DECLARE SUB UP(A$)
DECLARE FUNCTION COMPARE(B$, C$)
PRINT "Введите первую строку"
INPUT "",A1$
PRINT "Введите вторую строку"
INPUT "", A2$
K=COMPARE(A1$,A2$)
IF K=l THEN PRINT "Первая строка 'больше'"
IF K=-l THEN PRINT "Первая строка 'меньше'"
IF K=G THEN PRINT "Обе строки равны"
END
FUNCTION COMPARE(B$,C$) DIM B1$,C1$
UP B$: UP C$
FOR J=l TO LEN(B$)
IF MID$ (B$, J, 1)<>" " THEN B1$=B1$+MID$ (B$,J, 1 )
NEXT J
FOR J=l TO LEN(C$)
IF MID$(C$,J,1)<>" " THEN C1$=C1$+MID$(C$,J,1) NEXT J
IF B1$>C1$ THEN COMPARE=1 IF B1$=C1$ THEN COMPARE=0
IF B1$<C1$ THEN COMPARE=-1 END FUNCTION
SUB UP(A$)
FOR J=l TO LEN(A$)
SELECT CASE MID$(A$,J,1)
CASE "a" TO "z": MID$ (A$, J, 1) =CHR$ (ASC (MID$ (A$, J, 1) )-32)
CASE "a" TO "n": MID$(A$,J,1)=CHR$(ASC(MID$(A$,J,1))-32)
CASE "p" TO "я": MID$(A$,J,1)=CHR$(ASC(MID$(A$,J,1))-80)
CASE "ё": MID$(A$,J,1)="Ё" END SELECT
NEXT J
END SUB
Программа 3_08.с
/* Сравнение строк с игнорированием пробелов */
#include <stdio.h>
#include <conio.h>
#include <string.h>
char *up(char *a);
int compare(char *s1, char *s2);
void main() {
char s1[80],s2[80];
puts("Введите первую строку");
gets (s1);
puts("Введите вторую строку");
gets(s2);
switch(compare(s1,s2)) {
case 1: puts("Первая строка 'больше'");break;
case -1: puts("Первая строка 'меньше'");break;
case 0: puts("Обе строки равны");
}
getch(); }
char *up(char *a)
{
/* Замена кодов малых букв кодами больших */
static unsigned char b[80]; int j ;
strcpy (b, a) ;
for(j=0; j<strlen(a); j++) {
if(97<=b[j] && b[j]<=122) b[j]-=32;
if(160<=b[j] && b[j]<=175) b[j]-=32;
if (224<=b[j] && b[j]<=239) b[j]-=80;
if (241==b[j]) b[j]—; }
return b; }
int compare(char *s1,char *s2) {
char ssl[80],ss2[80]; char j,k;
strcpy(s1,up(s1)};
/* Замена малых букв большими */
strcpy (s2*, up (s2) );
/* с записью на то же место */
for(j=0,k=0; j<strlen(sl); j++)
if (sl[j] != ' ') ssl[k++]=sl[j];
/* Извлекаем непробелы */
ssl[k]=0x0; /* Добавили признак конца */
for(j=0,k=0;
j<strlen(s2); j++)
if(s2[j]!=' ') ss2[k++]=s2[j];
ss2[k]=0x0;
k=atrcmp(ss1.ss2) /* Cравнили преобразованные строки */
if(k>0)return 1;
if(k<0)return 1;
return 0;
}
Программа 3_08.pas
program comp_string;
{ Сравнение строк с игнорированием пробелов }
var
s1,s2:string;
function up (a:string):string; var
j:integer; begin
for j:=l to length(a) do
case a[j] of
'a'..'z': a[j] :=chr(ord(a[j])-32) ;
'a'..'n': a[j]:= chr(ord(a[j])-32} ;
'р'..'я': a[j]:= chr(ord(a[j])-80} ;
'ё': a[j]:='E'; end; up:=a; end;
function compare(s1,s2:string):integer;
var
ssl,ss2:string; j:byte;
begin
sl:=up(s1);
s2:=up(s2);
ssl:=' ';
for j:=l to length(s1) do
if sl[j]<>' ' then ssl:=ssl+sl[j];
ss2:=' ';
for j:=l to length(s2) do
if s2[j]<>' ' then ss2:=ss2+s2[j];
compare:=0;
if ssl>ss2 then compare:=1;
if ssl<ss2 then compare:=-!;
end;
begin
writeln('Введите первую строку');
readln(s1);
writeln('Введите вторую строку');
readln(s2);
case compare(s1,s2) of
1: writeln('Первая строка "больше"');
-1: writeln('Первая строка "меньше"');
0: writeln('06e строки равны');
end;
readln;
end.
Задание 3.09. Разноцветный текст
Написать программу, которая выводит на экран текст, меняя цвет букв и цвет фона.
Совет 1 (общий)
В приведенных ниже текстах программ в пределах одного экрана демонстрируются две возможности. Во-первых, выводится строка, все символы которой окрашены в разные цвета. Для этого приходится каждый символ выдавать на экран отдельным оператором, предваряя вывод переустановкой цвета переднего плана. Выбранное для этой цели слово "ПРОГРАММИРОВАНИЕ" содержит ровно 16 букв, но каждый раз при очередной смене цвета фона одна из букв отображаемого слова имеет такой же цвет и не будет видна. Во-вторых, выводится строка, все символы которой имеют одинаковый цвет, не совпадающий с цветом фона. С помощью такой программы можно поэкспериментировать в подборе приятных цветовых сочетаний.
Программа 3_09.bas
RЕМ Разноцветный текст А$ = "ПРОГРАММИРОВАНИЕ"
CLS
' Отображение разноцветных букв на допустимой фоновой гамме
FOR CF=0 TO 7
FOR CS=0 TO 15
COLOR CS,CF LOCATE CF+1,2*CF+CS+1
PRINT MID$(A$,CS+1,1)
NEXT CS
NEXT CF
'Отображение мигающих разноцветных букв
FOR CF=0 TO 7
FOR CS=0 TO 15
COLOR CS+16,CF
LOCATE CF+1,2*CF+CS+41
PRINT MID$(A$,CS+1,1)
NEXT CS
NEXT CF
Программа 3_09.с
/* Разноцветный текст */
#include <conio.h>
main() {
int i ;
textbackground(0);
clrscr () ;
for(i=0; i<24; i++) {
gotoxy(2*i+l,i+l);
textcolor(128+i);
textbackground(i+2);
cprintf("Цветовая гамма в текстовом режиме"); }
getch(); }
Программа 3_09а.с
/* Разноцветный текст */
#include <conio.h>
main() {
int i;
textbackground(0) ;
clrscr();
for(i=0; i<24; i++) {
gotoxy(2*i+l,i+1);
textattr(128+i + ((i+1) « 4));
cprintf("Цветовая гамма в текстовом режиме");
}
getch (); }
Программа 3_09.pas
program colorl;
{ Разноцветный текст }
uses crt;
var
i:integer; begin
textbackground(0); clrscr;
for i:=0 to 23 do
begin
gotoxy(2*i+l,i+l);
textcolor(128+i);
textbackground(i+l);
writeln('Тест цветовой гаммы ');
end;
readln;
end.
Задание 3.10. Преобразование обычной дроби в десятичную
Составить функцию символьного (строкового) типа, преобразующую два своих целочисленных аргумента — числитель m и знаменатель п правильной дроби (m < n < 100) в строку, представляющую запись десятичной дроби. Для бесконечной дроби период следует заключить в круглые скобки. Например:
m=3 n=5 значение функции - "0.6"
m=1 n=6 значение функции - "0.1(6)"
Совет 1 (общий)
Очевидно, что количество цифр в десятичной дроби не превосходит 100, т. к. при последовательном делении на п мы можем получить не более чем п разных остатков (от 0 до п-1). Поэтому разумно завести массив для хранения остатков и при получении очередного остатка, отличного от 0, проверять, нет ли такого же среди ранее получавшихся. Как только новый остаток совпадет с одним из предыдущих, будет обнаружен период.
Совет 2 (Си)
К сожалению, среди строковых функций Си, включенных в заголовочный файл string.h, нет процедуры вставки символа в строку. Поэтому нам придется сдвигать вправо на одну позицию часть символов от начала периода и вставлять открывающуюся скобку. Не следует забывать и о вставке признака конца строки.
Программа 3_10.bas
RЕМ Преобразование обычной дроби в десятичную
DECLARE FUNCTION FRAC2STR$(M%, N%)
CLS : DEFINT A-Z
INPUT "Введите числитель и знаменатель дроби : ",M,N
PRINT M;"/";N;"= ";FRAC2STR$(M,N)
END
DEFSNG A-Z
FUNCTION FRAC2STR$(M AS INTEGER,N AS INTEGER)
DIM S AS STRING, REST(100) AS INTEGER
DEFINT A-Z
I=3: S="0."
DO
Q=M*10\N : P=M*10 MOD N: REST(I)=P
IF P=0 THEN
FRAC2STR=S+CHR$(Q+48) EXIT FUNCTION
END IF
FOR J=3 TO 1-1
IF REST(J)=P THEN
FRAC2STR=LEFT$(S, J-l}+"("+RIGHT$(S,LEN(S)-J+l)+")"
EXIT FUNCTION
END IF
NEXT J
S=S+CHR$(Q+48): I=1+1: M=P LOOP UNTIL P=0
END FUNCTION
Программа 3_10.с
/* Преобразование обычной дроби в десятичную */
#include <stdio.h>
#include <conio.h>
char *frac_to_str(char m,char n);
main() {
char m,n;
printf("\n Введите числитель и знаменатель дроби : ");
scanf("%d %d",sm,&n) ;
printf("\n%d/%d=%s",m,n,frac_to_str(m,n));
getch();
}
/ *-----------------------------------------------* /
char *frac_to_str(char m,char n) {
int i=2,j,p,q;
char rest[100];
static char s [100]="0.";
do {
q=m*10/n; p=m*10%n; rest[i]=p;
if(p==0) { s[i]=q+48;
s[i+l]=0x0;
return s; }
for(j=2; j<i; j++)
if(rest[j]==p) {
for(p=i; p>=j; p--)
s[p+l]=s[p];
s[j]='(';
s[i+l]=')';
s [i+2]=0x0 ;
return s ; }
s[i]=q+48;
i++;
m=p; }
while (p!=0); }
Программа 3_10.pas
program drobi;
{ Преобразование обычной дроби в десятичную }
var
m, n:byte;
function frac_to_str(m,n:byte):string;
var
i,j,p,q:word;
s:string;
rest:array [1..100] of byte;
begin
s:='0.';
i:=l;
repeat
q:=m*10 div n;
p:=m*10 mod n;
rest[i]:=p;
if p=0 then begin
frac_to_str:==s+chr (q+48) ;
exit;
end;
for j:=l to i-1 do
if p=rest[j] then
begin insert(' (',s,j+2); frac_to_str:=s+')';
exit;
end;
inc(i);
s:=s+chr(q+48);
m:=p;
until p=0;
end;
begin
writeln('Введите числитель и знаменатель дроби :');
readln(m,n);
writeln(m,'/',n, ' = ', frac_to_str(m,n));
readln; end.
Задание 3.11. Перевод чисел в римскую систему счисления
Составить функцию символьного (строкового) типа, аргументом которой является натуральное число из интервала [1, 3999]. Функция должна возвращать строку с эквивалентным значением в формате римской системы счисления. Напомним, что в римской системе счисления используются большие латинские буквы — M(1000), O (500), C(100), L (50), X(10), V(5) и I(1). Если меньшая "цифра" находится левее "большей", то она вычитается (например: IV == V-I = 4, IX= X- I= 9, XL = L - X- 40). Если меньшая "цифра" расположена правее, то она прибавляется (например: VI = = V+ I= б, XI = X+ I= I I, LX = L + X = 60). Для некоторых "цифр" римская система допускает наличие до трех идущих подряд одинаковых
цифр —
I I= I + I = 2,
I I I = I + I+ I= 3,
XXX = X + X + X = 30,
ССС == C+ C+ C= 300,
MMM = M+ M+ M + 3000.
Совет 1 (общий)
Заведем два массива — символьный с наиболее характерными сочетаниями римских "цифр" и числовой с соответствующими значениями этих сочетаний. Оба массива разумно расположить в порядке убывания числовых значений (табл. 3.1).
Таблица 3.1. Расположение массива в порядке убывания числовых названий
Индекс элемента |
Символьный массив |
Числовой массив |
||
0 |
M |
1000 |
||
1 |
CM |
900 |
||
2 |
D |
500 |
||
3 |
CD |
400 |
||
4 |
С |
100 |
||
5 |
ХС |
90 |
||
6 |
L |
50 |
||
7 |
XL |
40 |
||
8 |
X |
10 |
||
9 |
IX |
9 |
||
10 |
V |
5 |
||
11 |
IV |
4 |
||
12 |
I |
1 |
||
Начинаем вычитать из переводимого числа первый элемент числового массива и вычитаем до тех пор, пока результат остается положительным. Каждый раз, когда вычитание возможно, к результирующей строке присоединяем соответствующее символьное значение. И так продолжаем экспериментировать с каждым элементом числового массива. Кстати, сумма всех элементов равна 3999, чем и объясняется ограничение на допустимый диапазон обрабатываемых чисел.
Программа 3_11.bas
RЕМ Перевод чисел в римскую систему
DECLARE FUNCTION torome$ (M%)
КЕМ Перевод арабских чисел в римскую систему счисления
DEFINT A-Z
COMMON SHARED ND()
COMMON SHARED SD$()
DATA 1,4,5,9,10,40,50., 90,100,400,500,900,1000
DIM ND(13)
FOR J=0 TO 12: READ ND(J): NEXT J
DATA I, IV, V, IX, X, XL, L, XC, C, CD, D, CM, M
DIM SD$(13)
FOR J=0 TO 12: READ SD$(J): NEXT J
INPUT "Введите целое число от 1 до 3999 : ", N
IF N<1 OR N>3999 THEN PRINT "Число вне диапазона":
END
PRINT "В римской системе счисления "; N;" = ";torome$(N)
END
FUNCTION torome$ (M)
SHARED ND(), SD$()
S$=""
FOR K=12 TO 0 STEP -1
WHILE ND(K)<=M
M=M-ND(K): S$=S$+SD$(K)
IF M=0 THEN EXIT FOR
WEND
NEXT К
torome$=S$
END FUNCTION
Программа 3_11.с
/* Перевод чисел в римскую систему счисления */
#include <stdio.h>.
#include <conio.h>
#include <string.h>
char *to_rome(int n) ;
main() {
int N;
printf("\n Введите целое число от 1 до 3999 : ");
scanf("%d",&N); if (N<0 | | N>3999) {
printf("\n Число вне диапазона");
getch();
exit(0); }
printf("\n B римской системе счисления %d = %s",N,to_rome(N));
getch();
}
/*-------------------------------*/
char *to_rome(int n) {
int k;
static char s[20]="";
int nd[13]={l,4,5,9,10,40,50,90,100,400,_500,900,1000};
char *sd[13]={"I","IV","V","IX","X","XL",
"L","XC","C","CD","D","CM","M"}; for(k=12; k>=0; k—) {
while(nd[k]<=n) {
n=n-nd[k]; strcat(s,sd[k]);
if(n==0) break;
} }
return s; }
Программа 3_11.pas
program in_rome;
{Перевод чисел в римскую систему счисления}
var
N:1..3999;
function to_rome(n:integer): string;
const
nd:array [1..13] of integer=
(1,4,5,9,10,40,50,90,100,400,500,900,1000) ;
sd:array [1..13] of string=
( 'I', 'IV, 'V, 'IХ', 'X', 'XL',
'L', 'XC', 'C','CD','D','CM', 'M');
var
k:integer;
s:string;
begin s : = " ;
for k:=13 downto 1 do
while nd[k]<=n do begin
n:=n-nd[k];
s:=s+sd[k];
if n=0 then break;
end;
to_rome:=s;
end; begin
write ('Введите целое число от 1 до 3999 : ' ).; readln(N);
writeln('B римской системе счисления ',N, ' = ', to_rome (N) ) ;
readln;
end.
Задание 3.12. Перевод чисел из римской системы счисления
Составить программу обратного преобразования из строки с записью числа в римской системе счисления в обычное число.
Программа 3_12.bas
REM Перевод чисел из римской системы счисления в арабскую
DEFINT A-Z
DATA 1,4,5,9,10,40,50,90,100,400,500,900,1000
DIM ND(13)
FOR J=0 TO 12: READ ND(J): NEXT J
DATA I,IV,V,IX,X,XL,L,XC,C,CD,D,CM,M
DIM SD$(13)
FOR J=0 TO 12: READ SD$(J): NEXT J
INPUT "Введите число в римской системе счисления : ", R$
J=l: M=0
100 :
FOR К=12 ТО 0 STEP -1
N=LEN(SD$(К))
IF MID$(R$,J,N)=SD$(К) THEN M=M+ND(K): J=J+N: GOTO 100
END IF
IF J>LEN(R$) THEN EXIT FOR
NEXT К
PRINT "В арабской системе счисления ";R$;" = ";M
END
Программа 3_12a.bas
REM Перевод чисел из римской системы счисления в арабскую
DATA 1000,900,500,400,100,90,50,40,10,9,5,4,1
DIM ND(13):
FOR J=0 TO 12: READ ND(J): NEXT J
DATA M,CM,D,CD,C,XC,L,XL,X,IX,V,IV,I
DIM SD$(13): FOR J=0 TO 12: READ SD$(J): NEXT J
INPUT "Введите число в римской системе счисления : ",R$
FOR J=l TO LEN(R$)
FOR K=0 TO 12
N=LEN(SD$(K))
IF MID$(R$,J,N)=SD$(К) THEN M=M+ND(K): J=J+1: K=K-1
END IF NEXT К NEXT J
PRINT "В арабской системе счисления ";R$;" = ";M
END
Программа 3_12.с
/* Перевод чисел из римской системы счисления в арабскую */
#include <stdio.h>
#include <conio.h>
#include <string.h>
main() {
int nd[13]={1000,900,500,400,100,90,50,40,10,9,5,4,1};
char *sd[13]={"M","CM","D","CD","C","XC","L","XL","X",
"IX","V","IV","I"}; char r[20],s[3]; int j,k,n,m=0;
printf("ХпВведите число в римской системе счисления : ");
scanf("%s", r);
for(j=0; j<strlen(r); j++)
for(k=0; k<13; k++) {
n=strlen(sd[k]);
strncpyfs, &r.[j] ,n) ;
s[n]=0;
if(strcmp(s,sd[k])==0)
{ m += nd[k]; j++; k—; } }
printf("\nB арабской системе счисления %s = %d",r,m);
getch(); }
Программа 3_12.pas
{ Перевод чисел из римской системы счисления в арабскую }
program from rome;
const
nd:array [1..13] of integer=(1000,900,500,400,100,
90,50,40,10,9,5,4,1);
sd:array [1..13] of string=('M','CM','D','CD','C',
'XC' , 'L', 'XL', 'X', 'IX1, 'V, 'IV, 'I' ) ; var
r,s:string;
j,k,n,m: integer; begin
m:=0;
write('Введите число в римской системе счисления : ');
readln(r);
J:=l;
while j<=length(r) do begin k:=l;
while k<=13 do begin
n:=length(sd[k]);
s:=copy(r,j,n);
if s=sd[k] then begin
inc(m,nd[k]); inc(j);
dec(k);
end;
inc(k);
end;
inc(j);
end;
writeln('B арабской системе счисления ',r,' = ',m);
readln;
end.
Задание 3.13. Вхождение строки с разрядкой
Строка S2 может входить в более длинную строку S1 в общепринятом смысле, когда непрерывная подпоследовательность символов строки S1совпадает с цепочкой символов S2. Однако возможна и другая ситуация, когда строка S2 входит в строку S1 с разрядкой. При этом символы S2 с равномерным шагом через 1, 2, 3 или более символов встречаются в строке S1.
Например, для строк S1="ABCBEEC" и S2="ABC" имеют место обычное (с нулевым шагом разрядки) вхождение (символы 1, 2 и 3 в строке si) и вхождение с разрядкой в 2 символа (символы 1, 4 и 7 в строке S1).
Составить программу, которая:
Задача программы — определить все возможные варианты вхождения S2 в S1.
Совет 1 (общий)
Идея поиска довольно проста. Обозначим через h шаг по индексу в строке S1, с которым выбираются символы, сравниваемые с символами S2. Для нулевой разрядки h=l, для выборки через символ h=2 и т. д. Очевидно, что начинать
сравнение надо с символа S1[I], совпадающего с первым символом S2. Однако реализация этой идеи может быть разной. Например, из строки si можно извлечь с заданной разрядкой нужное число символов и результат сравнить с S2. Более эффективно совместить эти две операции и сравнивать извлекаемый из S1 символ с очередным символом S2, прекращая выборку при первом несовпадении. Указанный подход был реализован победителем областной студенческой олимпиады В. Мартьяновым (апрель 2000 г.), на базе программы которого и построены приведенные ниже примеры. Наиболее оригинальной, на наш взгляд, является проверка условия (h=l) или (L2>1). Здесь L2—длина второй строки.
Программа 3_13.bas
RЕМ Поиск вхождения S2 в S1 с разрядкой
CLS
INPUT "Введите S1: ", Sl$: L1=LEN(S1$)
INPUT "Введите S2: ", 32$: L2=LEN(S2$)
FOR H=l TO L1
IF (H=l) OR (L2>1) THEN
FOR I=1 TO Ll-(L2-l)*H
IF MID$(S1$,I,1)=MID$(S2$,l,l) THEN
FOR J=2 TO L2,
IF MID$(S1$,I+(J-1)*H,1)<>MID$(32$,J,1) THEN GOTO ml
NEXT J
PRINT "Шаг: ";Н-1,"Позиции: ";I;
FOR К = 1 TO L2 - 1: PRINT "-"; I + К * H; : NEXT K: PRINT
К = 1 ml:
END IF
NEXT I
END IF
NEXT H
IF К = 0 THEN PRINT "Строка S2 не входит в S1"
END
Программа 3_13.с
/* Поиск вхождения S2 в S1 с разрядкой */
#include <stdio.h>
#include <conio.h>
#include <string.h> main{)
{
char s1 [80],s2[80];
int i,j,k=0,h,Ll,L2;
clrscr();
printf("Введите S1: ");
scanf("%s",s1);
Ll=strlen(s1);
printf("Введите S2: ");
scanf("%s",s2);
L2=strlen(s2);
for(h=l; h<=Ll; h++)
{
if(h==l || L2>1
}
{
for(i=0; i<Ll-(L2-l)*h; i++)
{
if (sl[i]=s2[0])
{
for(j=l; j<L2; j++)
if(si[i+j*h]!=s2[j]) goto ml;
printf("\n Шаг: %2d Позиции: %d",h-l,i+1);
for(k=l; k<L2; k++)
printf("-%d",i+i+k*h);
ml:;
}
} } }
if(k==0) printf(" Строка S2 не входит в S1");
getch () ; }
Программа 3_13.pas
program red_str;
(Поиск вхождения S2 в S1 с разрядкой}
uses crt;
var
s1,s2:string;
i,j,k,h,L1,L2:integer;
label 1;
begin
clrscr;
write('Введите S1: ');
readln (si);
Ll:=length(sl);
write('Введите S2: ');
readln (s2);
L2:=length(s2);
k:=0;
for h:=l to L1 do
if (h=l)or(L2>1) then
for i:=l to L1-(L2-1)*h do
if s1[i]=s2[l] then begin
for j:=2 to L2 do
if s1[i+(j-l)*h]os2[j] then goto 1;
write ('Шаг: ',h-l:2,' Позиции: ',i);
for k:=l to L2-1 do
write('-',i+k*h);
writeln;
k:=l;
1:
end;
if k=0 then writeln('Строка 32 не входит в S1');
readln;
end.
Заглянув в таблицу ASCII, нетрудно убедиться в том, что замене подлежат коды символов, попадающие в следующие интервалы: