Стандартные задачи школьного курса оиивт

 

       Язык Паскаль позволяет обрабатывать не только числа, но и символы, слова, тексты. (Как это не парадоксально звучит, сегодня электронно-вычислительные машины заняты по большей части обработкой нечисловой информации!) В то же время, смысл человеческих слов, конечно, не доступен компьютеру, так что под строковой величиной (словом) в системе Turbo-Pascal понимается любой набор символов алфавита, взятый в апострофы.

       Например, 'а', 'А', 'азбука’, 'абвг', 'w', 'W', 'way', 'abcdef', 'a1', '1', '1+1=', '123 456' - строковые константы. (Пробел такой же символ, как и все остальные!)

       Более того, часто необходимым оказывается слово, не содержащее ни одного символа. Такое слово задается так двумя апострофами подряд и называется пустым.

       В разделе описания переменных строковые величины описываются с помощью служебного слова STRING, например:

       VAR Z:STRING[25];

                               T:STRING[15];

                               Y:STRING[20];   .

       (Число, указанное в квадратных скобках после служебного слова STRING, в известной мере определяет количество символов в значении строковой переменной. Так, значением слова Z может быть слово, содержащее не более 25 символов, а в слове Т не может быть более 15 букв, соответственно в Y - 20.)

       Количество символов в слове часто называется длиной слова. Для вычисления длины слова (скажем X) в Паскале пользуются функцией LENGTH(Х), возвращающей количество символов в строковой переменной X. Например, length('солнце')=6, а в результате выполнения последовательности операторов

       X:='SUN'; Y:=length(X)

значение переменной Y станет равным трем.

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

       Функция COPY(S,Pos,Len) ("вырезка") применяется для получения подстроки длиной Len символов строки S, причем подстрока "вырезается", начиная с позиции Pos.

       Простейший пример, иллюстрирующий применение функций COPY и LENGTH, выглядит так.

 

       Задача 2.1.1. Составьте программу, выясняющую, совпадают ли первая и последняя буквы слова X.

       program z211 (input, output);

       var x:string[10];

       begin

       writeln(Введите слово ‘);readln(x);

       if copy(x,1,1)=copy(x,length(x),1)

         then writeln('первая и последняя буквы совпадают')

         else writeln('первая и последняя буквы не совпадают')

       end.

       Функция CONCAT(S1,S2,...,SN) возвращает строку, полученную слиянием (конкатенацией) строк S1, S2,..., SN.

       Пример.

       program p211 (input, output);

       var x,y,z: string[10];

       begin

       readln(x); readln(y);

       z:=concat(x,y); writeln('z=',z)

       end.

       Running

       конь

       як

       z=коньяк

 

       Решение следующей задачи иллюстрирует применение трех названных выше функций.

       Задача 2.1.2. Составьте программу циклической перестановки букв слова X, при которой последняя буква становится первой, 1-я - 2-й, i-я - i+1-й.

       Комментарий. Элементарный анализ условия задачи показывает, что программа ее решения должна преобразовывать слово СТОЛ в слово ЛСТО, ЛАМПА - АЛАМП и т.д. Легко также увидеть, что подобное преобразование можно осуществить, "отрезав" последнюю букву слова X и "приклеив" ее в начало. Именно такой подход реализуется в следующей программе.

       program z212 (input, output);

       var x:string[10];

       begin

       writeln(‘Введите слово’);readln(x);

       x:=concat(copy(x,length(x),1),copy(x,1,length(x)-1));

       writeln(x)

       end.

 

       Функция POS(SubStr,S) используется в процессе поиска номера символа, начиная с которого подстрока SubStr, входит в строку S.

       Пример.

       program p212 (input, output);

       var x,y:string[10];

             n:integer;

       begin

       readln(x); readln(y);

       n:=pos(x,y); writeln('n=',n)

       end.

       Running                    Комментарий. 12345

       яр                                      маляр

       маляр                                         яр

       n=4

       Кроме указанных выше функций при обработке строковых величин можно пользоваться такими стандартными процедурами.

 

       Процедура DELETE в общем виде записывается так:

       DELETE(S,Pos,Len),

и при ее выполнении из строки S, начиная с позиции Pos, удаляется подстрока длиною Len символов (см. задачу 2.1.3).

       Задача 2.1.3. Составьте программу, удаляющую первый символ слова X.

       program z213 (input, output);

       var x:string[10];

       begin

       writeln(‘Введите слово’);readln(x);

       delete(x,1,1);

       writeln('x=',x)

       end.

       Running

       маляр

       x=аляр

 

       Процедура INSERT, записываемая в общем виде следующим образом:

       INSERT(S1,S2,Pos),

позволяет вставить строку S1 в строку S2, начиная с позиции Pos. При этом, если Pos>Length(S2), то результатом выполнения процедуры будет слияние строк S1 и S2 и присваивание полученного значения переменной S2.

       Так, в результате выполнения фрагмента программы:

       S1:='обеда'; S2:='по'; insert(S1,S2,3)

переменная S2 примет значение 'победа'.

       Перечисленных выше процедур и функций, предназначенных для обработки строковых величин, оказывается вполне достаточно при решении многих стандартных задач школьного курса информатики, о которых пойдет речь ниже.

 

       Задача 2.1.4. Составьте программу удваивающую каждую букву слова X.

       Комментарий. Очевидно, что программа решения данной задачи слово ХОД должна преобразовывать в слово ХХООДД, ЛЕС - ЛЛЕЕСС и т.д. В том случае, когда вводимое с клавиатуры слово состоит ровно из одного символа, также легко видеть, что оператор X:=X+X по существу является решением нашей задачи. Нетрудно понять и то, что значением выражения

       copy(X,i,1)+copy(X,i,1)

является удвоенная i-ая буква слова X. Таким образом, перебирая каждую букву слова X, возможно с помощью оператора

       Y:=Y+copy(X,i,1)+copy(X,i,1)

получить требуемое слово. Именно эта идея и реализована в приведенной программе.

 

       program z214 (input, output);

       var x,y:string [30];

             i:integer;

       begin

       writeln('Введите слово '); readln(x);

       y:='';

       for i:=1 to length(x) do

         y:=y+copy(x,i,1)+copy(x,i,1);

       x:=y; writeln('преобразованное слово ',x)

       end.

 

       Задача 2.1.5. Составьте программу обращения слова X (программу, пребразующую слово X в слово, записанное теми же буквами, но в обратном порядке).

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

       program z215_1 (input,output);

       var x,y:string[30];

             i:integer;

       begin

       writeln('Введите слово '); readln(x);

       y:='';

       for i:=1 to length(x) do

       y:=copy(x,i,1)+y;

{Замена оператора y:=copy(x,i,1)+y на оператор y:=y+copy(x,i,1) приводит к тому, что в результате выполнения программы y становится равным x. От перемены мест слагаемых результат конкатенации меняется!}

       x:=y; writeln ('Обращенное слово ',x)

       end.

 

       Что же касается второго варианта решения рассматриваемой задачи, то приводимая ниже программа помимо всего прочего является удачной иллюстрацией применения оператора FOR/DOWNTO:

 

       program z215_2 (input,output);

       var x,y:string[30];

            i:integer;

       begin

       writeln('Введите слово '); readln(x);

       y:='';

       for i:=length(x) downto 1 do

         y:=y+copy(x,i,1);

       x:=y; writeln ('Обращенное слово ',x)

       end.

 

       Нетрудно заметить, что в программах z214, z215_1, z215_2 мы вводили промежуточную переменную, сводя тем самым исходную задачу преобразования вводимого с клавиатуры слова к задаче образования нового слова, удовлетворяющего тем или иным условием. Этот прием широко используется при решении различных задач, связанных с обработкой строковых величин, например, и такого типа:

 

       Задача 2.1.6. Составьте программу, вычеркивающую из слова X все буквы "a".

       Комментарий. Идея, реализованная в приводимой ниже программе может быть кратко сформулирована так: из исходного слова x в промежуточное слово y поочередно дописываются все буквы слова x за исключением букв "а" (после чего слово x заменяется на окончательное значение промежуточной величины y).

       program z216 (input,output);

       var x,y:string[45];

             i:integer;

       begin

       writeln('Введите слово ');

       readln(x);

       y:='';

       for i:=1 to length(x) do

         if copy(x,i,1)<>'a'

           then y:=y+copy(x,i,1);

       x:=y; writeln('Измененное слово - ',x)

       end.

 

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

 

       Задача 2.1.7. Составьте программу, вычеркивающую из слова X буквы "a", стоящие на нечетных местах.

        program z217 (input,output);

       var x,y:string[45];

             i:integer;

       begin

       writeln('Введите слово ');

       readln(x);

       y:='';

       for i:=1 to length(x) do

         if (copy(x,i,1)<>'a') or (i mod 2=0)

           then y:=y+copy(x,i,1);

       x:=y; writeln('Измененное слово: ',x)

       end.

 

       Разумеется, при решении ряда задач обработки строковых величин, воспользовавшись процедурами INSERT, DELETE, можно попытаться обойтись без введения промежуточной переменной - именно это и делается в первом варианте (программа z218_1) решения приводимой ниже задачи о замене букв. Однако, как показывает практика, названный прием достаточно универсален, и потому мы также сочли необходимым привести второй вариант (программа z218_2) решения названной задачи, которая формулируется так.

 

       Задача 2.1.8. Составьте программу, меняющую в слове Х все буквы "а" на буквы "б".

       Вариант 1.

       program z218_1 (input,output);

       var x:string[45];

           i:integer;

       begin

       writeln('Введите слово ');

       readln(x);

       for i:=1 to length(x) do

         if copy(x,i,1)='a'

           then

             begin

               delete(x,i,1);

               insert('б',x,i)

             end;

       writeln('Измененное слово: ',x)

       end.

 

       Вариант 2.

       program z218_2 (input,output);

       var x,y:string[30];

             i:integer;

       begin

       write('Введите слово ');

       readln(x);

       y:='';

       for i:=1 to length(x) do

         if copy (x,i,1)='a'

           then y:=y+'б'

           else y:=y+copy(x,i,1);

       x:=y; writeln('Измененное слово ',x)

       end.

 

       При решении задач, приводящихся далее, как и в предыдущих, также используются распространенные приемы программирования.

 

       Задача 2.1.9. Составьте программу подсчета количества букв "а" в слове Х.

       Комментарий. Задачи, в которых так или иначе требуется организовать подсчет (какого-угодно рода), весьма нередки в программировании, поэтому приведем популярное изложение идеи, что используется при составлении таких программ.

       Вообразите себе, что в Вашем распоряжении имеется человек, абсолютно не умеющий считать, а Вы, тем не менее должны проинструктировать его так, чтобы с его помощью получить решение, скажем, такой задачи: "Сколько человек воспользовалось автобусом 1-го маршрута на остановке "О" в течение рабочего дня". Ясно, что в этом случае можно вручить этому человеку пустой ящик, кучу камешков, и объяснить ему, что как только он увидит пассажира, входящего в автобус 1-го маршрута, ему следует бросать по одному камешку в ящик. После этого останется сосчитать количество камешков в ящике.

       Описанная процедура и реализована в программе z219, в которой роль ящика играет переменная p, а команда p:=p+1 выступает эквивалентом бросанию камешка в ведро.

       program z219 (input,output);

       var x:string[45];

          i,p:integer;

       begin

       write('Введите слово ');

       readln(x);

       p:=0;

       for i:=1 to length(x) do

         if copy(x,i,1)='a'

           then p:=p+1;

       writeln('Количество букв в слове Х - ',p)

       end.

 

       Следующая задача - модификация только что рассмотренной.

       Задача 2.1.10. Составьте программу вычисления суммы мест, на которых в слове X стоит буква "а".

 

       program z2110 (input,output);

       var x,y:string[30];

           s,i:integer;

       begin

       write('Введите слово ');

        readln(x);

       s:=0;

       for i:=1 to length(x) do

         if copy (x,i,1)='a'

           then s:=s+i;

       if s=0

         then writeln ('В слове нет букв "а"')

         else writeln ('Сумма мест равна ',s)

       end.

 

       Три варианта решения рассматриваемой ниже задачи хорошо иллюстрируют разнообразие возможных подходов, используемых в программировании.

       Задача 2.1.11. Составьте программу, выясняющую, имеется ли в слове X буква "a".

       Вариант 1.

       Комментарий. Приводимая здесь программа может быть легко получена сведением исходной задачи к задаче о подсчете числа букв "а" в слове Х, так как, очевидно, что если количество букв "а" в слове Х равно нулю, то буквы "а" в слове Х нет, в противном случае буква "а" в слове Х имеется.

 

       program z2111_1 (input,output);

       var x,y:string[30];

           p,i:integer;

       begin

       write('Введите слово ');

       readln(x);

       p:=0;

       for i:=1 to length(x) do

         if copy (x,i,1)='a'

           then p:=p+1;

       if p>0

         then writeln ('Имеется "а"')

         else writeln ('Букв "а" в слове нет')

       end.

 

       Вариант 2.

       Комментарий. Идея, реализованная в этом варианте программы, широко эксплуатируется в программировании и заключается в том, что при ответе на вопрос "да или нет?" (в нашему случае - "есть ли в слове буква 'а'?") изначально в зависимости от условия задачи фиксируется тот или иной ответ (в нашем случае - "в слове нет букв 'а'"), а затем осуществляется проверка истинности этого ответа. Если зафиксированный ответ оказывается ложным, то он меняется на противоположный (в рассматриваемом случае - "имеется буква "а").

 

       program z2111_2 (input,output);

       var x,z:string[30];

             i:integer;

       begin

       write('Введите слово ');

       readln(x);

       {изначально фиксируется ответ}

       z:='нет букв "а"';

       for i:=1 to length(x) do

         if copy (x,i,1)='a'

       {ответ меняется на противоположный}

           then z:='имеется буква "а"';

       writeln(z)

       end.

       Вариант 3.

       Комментарий. Третий вариант решения исходной задачи представляет собой модификацию программы z2111_2, в соответствии с которой проверка наличия в слове X буквы "а" производится лишь до тех пор, пока не будет найдена первая по порядку буква "а" (в предыдущем варианте вне зависимости ни от чего каждая буква слова сравнивается с "а"). Легко видеть, что окончание проверки после того, как в слове Х найдена первая по порядку буква "а", достигается за счет использования оператора безусловного перехода для выхода из цикла.

 

       program z2111_3 (input,output);

       label 1;

       var x,z:string[30];

             i:integer;

       begin

       write('Введите слово ');

       readln(x);

       z:='нет букв "а"';

       for i:=1 to length(x) do

       if copy (x,i,1)='a'

          then

              begin

                z:='имеется буква "а"';

                goto 1

              end;

       1:write(z)

       end.

 

       В рассмотренной программе мы впервые использовали "плохой" оператор goto - "плохой" в том смысле, что его частое применение в программах считается дурным тоном среди профессиональных программистов. Тем не менее, этот оператор очень часто оказывается полезен, и потому приведем его общий вид:

GOTO <имя метки>,

где имя метки должно быть указано в разделе описания меток, начинающегося служебным словом label (аналогично тому, как это сделано в программе z211_3).

 

       Последние три задачи этого параграфа - примеры, иллюстрирующие возможные сочетания тех или иных приемов программирования при решении задач на обработку строковых величин.

 

       Задача 2.1.12. Составьте программу, определяющую, какая из букв "а" или "б" встречается в слове Х раньше.

       program z2112 (input,output);

       label 1;

       var x, z: string[30];

              i: integer;

       begin

       write('Введите слово ');

       readln(x);

       z:='нет ни "а", ни "б"';

       for i:=1 to length(x) do

       if (copy (x,i,1)='а') or (copy (x,i,1)='б')

          then

            begin

              z:=copy (x,i,1)+' - встречается раньше';

              goto 1

            end;

       1: writeln(z);

       end.

 

       Задача 2.1.13. Составьте программу, проверяющую, есть ли в слове Х буква "р", и меняющую первую из них на букву "о", в случае если таковая имеется.

       program z2113 (input,output);

       var x,y:string[30];

          i,fl:integer;

       begin

       write('Введите слово '); readln(x);

       fl:=0; {нет букв "p"}

       y:='';

       for i:=1 to length(x) do

       if (copy (x,i,1)='p') and (fl:=0)

          then

            begin

              y:=y+'o';

              fl:=1 {есть буква "p"}

            end

          else y:=y+copy (x,i,1)

       if fl=0

        then writeln('букв "р" в слове нет')

         else begin

                   x:=y; writeln('измененное слово ',x)

                end;

       end.

       Задача 2.1.14. Составьте программу, проверяющую, есть ли в слове Х две одинаковые буквы.

       program z2114 (input,output);

       var x,fl:string[30];

          i,j:integer;

       begin

       write('Введите слово '); readln(x);

       fl:='нет двух одинаковых букв';

       for i:=1 to length(x) do

           for j:=1 to length(x) do

               if (copy (x,i,1)=copy (x,j,1)) and (i<>j)

                 then fl:='есть две одинаковые буквы';

       writeln(fl)

       end.

 


Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: