С клавиатуры последовательно вводятся 10 символов. Подсчитать количество введенных букв ’a’. Базовый алгоритм: подсчет количества элементов, удовлетворяющих заданному условию.
PROGRAM char2;
USES CRT;
VAR
a: char; {входная переменная, обратите внимание - a - это имя переменной, но не ее значение}
k: byte; {счетчик букв}
i: byte; {счетчик цикла}
BEGIN
clrscr;
k:=0;
writeln('Введите 10 любых букв: ');
FOR i:=1 TO 10 DO
BEGIN
readln(a);
IF a='a' THEN
k:=k+1
END;
IF K=0 THEN
writeln('символы a отсутствуют')
ELSE
writeln('кол-во символов a = ',k);
writeln('нажмите любую клавишу...');
readln;
END.
С клавиатуры последовательно вводятся символы до первого символа ’!’. Подсчитать количество символов ’;’. Обратите внимание, количество символов, которые будут введены, не известно, мы должны использовать либо конструкцию цикла WHILE, либо REPEAT.
PROGRAM CHAR3;
USES CRT;
VAR
lit: char; {входная переменная}
k: byte; {счетчик ';' знаков}
BEGIN
clrscr;
readln(lit); {в данном случае, необходимо одну операцию ввода выполнить до цикла}
k:=0;
WHILE lit <> '!' DO
BEGIN
IF lit=';' THEN
k:=k+1;
readln(lit)
END;
IF k=0 THEN
writeln('точек с запятой нет.')
ELSE
writeln('количество точек с запятой = ', k);
writeln('нажмите любую клавишу...');
readln;
END.
Строки
При обработке текста рассмотренный ранее тип данных char (литерный) не совсем удобен, т.к. позволяет в переменной хранить только один символ, желательно иметь инструмент для задания последовательностей литер. Таким инструментом являются строки — STRING.
Переменная, объявленная как переменная типа string(строка), содержит от 0 до N символов, длина строки не может превышать 255 символов.
Длину строки можно указывать в квадратных скобках рядом со служебным словом string.
Пример:
VAR
st: string[25];
Если конкретная длина строки не указана при объявлении, то размер строки устанавливается «по факту».
Тип string во многом похож на одномерный массив символов.
Однако, в отличие от массива символов, количество символов в строке может меняться от 0 до 255. К любому символу в строке можно обратиться точно так же, как к элементу массива, т.е. указав рядом с именем переменной типа string, в квадратных скобках индекс символа в строке:
st[2], т.е. 2-ой символ в строке st;
st[i] — i-тый символ в строке st;
Самый первый байт в строке имеет индекс равный 0 и содержит текущую длину строки.
Для строк применимы следующие операции:
1. Операция объединения строк (конкатенация). Обозначается эта операция знаком + (но это не сложение!)
st:= ‘abcd ‘;
st1:= ‘efk‘;
st2:=st+st1;
значение st2 — ‘abcdefk‘
2. Операции отношения: =, >=, >, <>, <, <=.
Сравнивать можно строки разной длины. Сравнение осуществляется слева направо в соответствии с ASCII кодами символов. Например, ’AB’ больше, чем ’АС’.
Тип данных String используется при обработке текстов, а это означает, что нам необходимо уметь:
1. Копировать часть строки.
2. Удалить часть строки.
3. Вставлять подстроку (т.е. часть строки) в данную строку.
4. Осуществлять поиск подстроки (т.е. часть строки) в данной строке.
Для реализации данных операций в Турбо Паскале существуют стандартные процедуры и функции.
1. Копирование части строки, функция copy (st, n, k), где st—исходная строка, n—начальная позиция, k — количество символов, которые мы будем копировать.
Пример:
var
st:=’abcdef’;
st1:=copy(st,2,3);
Значение строки st1—’bcd’.
2. Удаление части строки — процедура delete(st,n,k), где st—исходная строка, n—начальная позиция (с какого символа начинаем удалять), k—количество удаляемых символов.
Пример:
var
st:=’abcdef’; {st[0]=6;}
delete(st,2,3);
Значение строки st—’aef’.
Внимание!: При удалении части строки длина строки автоматически уменьшается, st[0]=3.
3. Вставить подстроку в данную строку — процедура insert(st1,st,n), где st1—подстрока, st—исходная строка, n—позиция символа, с которого начинается вставка.
Пример:
Пусть st—исходная строка, st1—подстрока.
st:=’?*-+/ab’;
st1:=’!%’;
insert(st1,st,2);
Значение строки st—’?!%*-+/ab’.
Можно не вводить имя переменной для подстроки, указав значение переменной явно, т.е. insert(’!%’,st,2);
4. Поиск подстроки в строке (первое вхождение).
Поиск подстроки в строке осуществляется с помощью функции pos, k:=pos(st1,st), где st1—подстрока, st—строка, k—позиция первого вхождения подстроки, либо 0, если подстрока осутствует.
Пример:
st:=
’И
В
а
н
О
в
А
л
е
к
С
А
Н
д
р
г
.
М
о
с
к
в
а’
Будем искать подстроку «г.Москва» в строке st, k:=pos(’г.Москва’,st);
Ответ: k=18.
Внимание! Повторим еще раз:
1. Значение функции pos—переменная целого типа.
2. Функция pos ищет первое вхождение подстроки в строку.
Строка типа string помимо буквенных и других символов может содержать и цифры.
Пример:
var
st, st1: string;
st:= ’123’;
st1:= ’254’
Сравните:
var
a, b: integer;
c: integer;
…
a := 123;
b := 254; c := a+b;
Представление в памяти переменной st объявленной как string, отличается от представления переменных a и b.
Числовые переменные переводятся в двоичную систему счисления и, в зависимости от типа (целого или вещественного), хранятся в памяти ЭВМ. В строке символов каждому символу соответствует свой код. Один символ занимает байт.
Сравните:
st2:=st+st1;
значение st2-’123254’
a:=123;
b:=254;
c:=a+b;
значение с=377;
Существует целый ряд задач, при решении которых необходимо уметь представить числовое данное в виде цепочки символов и, соответственно, выполнить обратное действие.
В Турбо Паскале существуют две процедуры, которые позволяют решить эти проблемы.
1. Процедура STR преобразует число любого вещественного или целого типов в строку символов.
str(a,st);
где:
a — числовая переменная;
st — строка символов.
Пример:
var
a: integer;
b: real;
st, st1: string;
....
a:=345;
str(a,st);
b:=12.6789;
str(b, st1);
значение st1=’1.2678900000E+01’ { шаблон не использовали}
str(b:2:2,st1);
значение st1=’12.67’ {шаблон использовали}
Примечание: для целых чисел также можно использовать шаблон.
2. Процедура VAL преобразует строку, содержащую цифры в число, вещественное или целое.
val(st,a,code);
где:
a — числовая переменная;
st — строка;
code — переменная целого типа, по значению которой можно определить, успешно или нет прошел перевод.
Если перевод из строки символов в число прошел успешно, значение переменной code равно 0.
var
a: integer;
b: real;
code: integer;
st: string;
st:=’345’;
val(st,a,code);
значение переменной a равно 345.
st:=’12.6789’;
val(st,b,code);
значение переменной b равно 1.2678900000E+01.
Если строка содержит символы, отличные от цифр и десятичной точки, значение переменной code равно номеру первого встреченного ошибочного символа.
Задача 1. Строка содержит только цифры. Удалить все ведущие нули. Исходная строка: 000102030, результат: 102030.
PROGRAM STRING1;
USES CRT;
VAR
st: string;
i: byte;
BEGIN
clrscr;
writeln('введите строку: ');
readln(st);
i:=length(st);
WHILE (( i > 0 ) and ( st[1] = '0' )) DO
BEGIN
delete(st, 1, 1);
i:=i-1
END;
writeln(st);
writeln('нажмите любую клавишу...');
readln;
END.
Внимание!При выполнении таких программ необходимо помнить о том, что в экстремальных ситуациях, например, когда строка содержит только нули, возможно зацикливание (т.е. не произойдет выход из тела цикла), поэтому добавляется еще одно условие: i>0.
В том случае, когда строка содержит только нули — выход из цикла произойдет при нарушении условия i>0, т.е. как только i примет значение 0. Строка после удаления всех нулей будет пустая.
Задача 2.
Строка символов st содержит только цифры — это запись целого числа в некоторой р-ной системе счисления. Выполнить перевод числа в десятичную систему счисления.
Повторим алгоритм перевода целых чисел из p-ричной системы счисления в десятичную на конкретном примере
Для этого возьмем число 326 представленное в 7-ной системе счисления и переведем его в десятичную систему счисления.
3267=
Мы видим два базовых алгоритма:
1) вычисление суммы;
2) вычисление an.
Пусть переменная S — используется для накопления суммы, переменная p — для получения очередной степени 7.
Опишем словесно алгоритм.
Переменной S присвоить нуль.
Переменной p присвоить 1.
Организуем цикл, количество повторений которого равно длине слова.
Цифры числа будем рассматривать, начиная с последней.
В цикле вычисляем 7i , умножаем на очередную цифру числа и суммируем полученные произведения.
PROGRAM STRING2;
USES CRT;
CONST
osn = 7; {основание вводимого числа}
VAR
number: string;
i, j: byte;
S, P, num, code: integer;
BEGIN
clrscr;
writeln('число: ');
readln(number);
S:=0;
FOR i:=1 TO length(number) DO
BEGIN
j := length(number);
p := 1;
WHILE ( j > i) DO
BEGIN
p := p * osn;
j := j - 1
END;
val(number[i], num, code);
S := S + p * num;
END;
writeln('Полученное число: ', S);
writeln('нажмите любую клавишу...');
readln;
END.
Приведённый алгоритм можно использовать только для перевода чисел с основанием меньшим 10.
Решите самостоятельно данную задачу для систем счисления с основаниями больше 10.
Задача 3. Строка символов содержит слова, разделенные одним или несколькими пробелами. Подсчитать количество слов в строке.
номера позиций символов
a
B
c
d
e
f
K
l
m
!
+
!
символы
Для того чтобы подсчитать количество слов в строке, необходимо каждое слово «вырезать». Для этого мы будем использовать функцию copy.
Нам необходимо ответить на следующие вопросы: 1) с какого символа мы начинаем вырезать, 2) сколько символов необходимо вырезать.
Чтобы ответить на эти вопросы нам необходимо вычислить позиции левой и правой границы слова. Используем тот факт, что слова разделены пробелами.
Начальная позиция первого слова равна 4, позиция первого пробела за словом равна 10, если из позиции пробела равной 10 вычесть начальную позицию слова, равную 6, то будет найдена длина слова. Делаем вывод, что наша задача следить за позицией пробела, просматривая все символы строки.
PROGRAM STRING3;
USES CRT;
VAR
st, substr: string;
k, l, r: byte;
BEGIN
clrscr;
writeln('Введите строку: ');
readln(st);
k:=0; {счетчик слов}
r:=1; {правая граница слова}
WHILE r <= length(st) DO
BEGIN
WHILE (st[r]= ' ') AND (r<=length(st)) DO
r:=r+1; {ищем левую границу слова, просматривая все пробелы