Студопедия КАТЕГОРИИ: АвтоАвтоматизацияАрхитектураАстрономияАудитБиологияБухгалтерияВоенное делоГенетикаГеографияГеологияГосударствоДомЖурналистика и СМИИзобретательствоИностранные языкиИнформатикаИскусствоИсторияКомпьютерыКулинарияКультураЛексикологияЛитератураЛогикаМаркетингМатематикаМашиностроениеМедицинаМенеджментМеталлы и СваркаМеханикаМузыкаНаселениеОбразованиеОхрана безопасности жизниОхрана ТрудаПедагогикаПолитикаПравоПриборостроениеПрограммированиеПроизводствоПромышленностьПсихологияРадиоРегилияСвязьСоциологияСпортСтандартизацияСтроительствоТехнологииТорговляТуризмФизикаФизиологияФилософияФинансыХимияХозяйствоЦеннообразованиеЧерчениеЭкологияЭконометрикаЭкономикаЭлектроникаЮриспунденкция |
Задания для самостоятельной работы
Begin Readln(S); Writeln('S=',S); SignPal:=false; k2:=0; Cond:=true; While Cond do Begin k1:=NotSpace(S,k2+1); If k1=0 then Cond:=false Else Begin k2:=Space(S,k1+1); Ifk2=0 then Begin k2:=length(S)+1; Cond:=false; End; Sb1:=Copy(S,k1,k2-k1); Sb2:=Sb1; i:=1; j:=k2-k1; Whilei<j do Begin ch:=Sb2[i]; Sb2[i]:=Sb2[j]; Sb2[j]:=ch; Inc(i); Dec(j); End; If Sb1=Sb2 then SignPal:=true; For i:=1 to k2-k1 do S[k1+i-1]:=Sb2[i]; End; End; Writeln('S=',S); If SignPal then Writeln('В строке есть слова-палиндромы') Else Writeln('В строке нет слов-палиндромов'); End.
В программе производится последовательное выделение слов текста путем определения границ k1 и k2, где k1 - первая буква слова (первый непробел), k2 - первый пробел после конца слова. Найденное слово, ограниченное значениями переменных k1 и k2, копируется в буферные строки Sb1 и Sb2. Буквы в слове Sb2 переставляются в обратном порядке. Если теперь Sb1 = Sb2, то это означает, что данное слово является палиндромом. Перестановка букв выполнена в строке Sb2, но не в строке S. Поэтому символы строки Sb2 переписываются обратно в строку S. ¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾
5.2. Обменять местами первое и второе слова текста.
В программе Task502 с помощью функций Space и NotSpace определяются начало и конец первого (k1, k2) и второго (k3, k4) слов. Обработка строки выполняется, если в ней имеется не менее двух слов. Решение задачи представлено в двух вариантах.
Последовательность обработки для варианта 1: - удаление из строки S подстроки от начала первого до конца второго слова; - вставка, начиная с позиции k1, второго слова; - вставка пробелов между первым и вторым словами; - вставка второго слова. Вставляемые подстроки копируются из буферной строки SBuf, в которую предварительно была переписана исходная строка S.
Последовательность обработки для варианта 2: - присваивание буферной строке SBuf пустого значения; - добавление к строке SBuf пробелов перед первым словом строки S; - добавление второго слова; - добавление пробелов между первым и вторым словами; - добавление первого слова; - добавление символов строки S, расположенных после ее второго слова; - присваивание строке S значения строки SBuf.
В а р и а н т 1 . Program Task502; Label 10,20; Var i,j, k1,k2, { начало и конец первого слова } k3,k4 : byte; { начало и конец второго слова } S,SBuf : string; Begin Readln(S); Writeln('S=',S); If length(S)=0 then Writeln('Строка пустая ') Else Begin k1:=NotSpace(S,1); Ifk1=0 then Writeln('В строке только пробелы ') Else Begin k2:=Space(S,k1+1); If k2=0 then Writeln('В строке одно слово ') Else Begin k3:=NotSpace(S,k2+1); Ifk3=0 then Writeln('В строке одно слово l = ',l) Else Begin k4:=Space(S,k3+1); If k4=0 then k4:=length(S)+1; SBuf:=S; Delete(S,k1,k4-k1); Insert(Copy(SBuf,k3,k4-k3),S,k1); Insert(Copy(SBuf,k2,k3-k2),S,k1+k4-k3); Insert(Copy(SBuf,k1,k2-k1),S,k1+k4-k2); End; End; End; End; Writeln('S=',S); End.
В а р и а н т 2 . Определение k1, k2, k3, k4 SBuf:=''; SBuf:=SBuf+Copy(S,1,k1-1); SBuf:=SBuf+Copy(S,k3,k4-k3); SBuf:=SBuf+Copy(S,k2,k3-k2); SBuf:=SBuf+Copy(S,k1,k2-k1); SBuf:=SBuf+Copy(S,k4,length(S)-k4+1); S:=SBuf;
¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾
5.3. В строке содержится выражение, состоящее из букв, цифр, знаков операций и круглых скобок. Если количество открывающих скобок не равно количеству закрывающих, то избыточные внешние скобки удалить из текста.
Внешние открывающие скобки отсчитываются в выражении слева направо, закрывающие - справа налево. В программе Task503 вначале определяются количество открывающих k1 и количество закрывающих k2 скобок. После этого в зависимости от их соотношения в цикле Whileпроизводится удаление избыточных открывающих (при k1 > k2) или закрывающих (при k1<k2) скобок. Цикл Whileработает до тех пор, пока разность dk = ½k1-k2½ не станет нулевой.
ProgramTask503; Var i, k1, { кол-во открывающих скобок } k2, { кол-во закрывающих скобок } dk : byte; { dk = abs(k2-k1) } S : string; Begin Readln(S); Writeln('S=',S); k1:=0; k2:=0; For i:=1 to length(S) do IfS[i]='(' then Inc(k1) Else IfS[i]=')' then Inc(k2); dk:=abs(k2-k1); If k1>k2 then Begin i:=1; { Удаление избыточных } While dk>0 do { открывающих скобок } If S[i]='(' then Begin Delete(S,i,1); Dec(dk) End Else Inc(i); End Else If k1<k2 then Begin i:=length(S); { Удаление избыточных } While dk>0 do { закрывающих скобок } Begin If S[i]=')' then Begin Delete(S,i,1); Dec(dk) End; Dec(i); End; End; Writeln('k1 = ',k1,' k2 = ',k2,' S=',S); End. ¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾
5.4. Для записи слов используются только большие буквы латинского алфавита. Преобразовать строку, заменив каждую букву ее двухзначным номером в алфавите. Для пробела использовать значение '00'. Например, для строки 'HTREK ESAB UYTR' получим '0820180511000005190102000021252018' .
В строке-константе Alf записаны пробел и большие буквы латинского алфавита. В цикле Forдля каждого очередного символа строки S с помощью функции Pos определяется его позиция k в строке Alf. Тогда численное значение символа, записываемое в строку S1, равно k-1. Если это значение имеет лишь одну цифру, то перед нею дописывается символ '0'.
Program Task504; Const Alf = ' ABCDEFGHIJKLMNOPQRSTUVWXYZ'; Var i,k : byte; S,S1 : string; Sb : string[2]; Begin Readln(S); Writeln('S=',S); S1:=''; Fori:=1 to length(S) do Begin k:=Pos(S[i],Alf)-1; Str(k,Sb); If k<10 then Sb:='0'+Sb; S1:=S1+Sb; End; Writeln('S1=',S1); End. ¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾
5.5. В строке записан список целых шестнадцатеричных чисел, разделенных между собой запятыми. Некоторые из этих чисел имеют знаки "+" или "-". Удалить из текста незначащие нули. Например,для текста "5A787,+00DF890,0000672,-98,-003B,000,+89ADF00,+0,+011" получим "5A787,+DF890,672,-98,-3B,0,+89ADF00,+0,+11".
Для определения положения запятой в программе Task505 используется функция Comma. Ее выходное значение, присваиваемое переменной k2, - это конечная граница числа. Тогда начало следующего числа определяется значением k2+1 . Исходный список шестнадцатеричных чисел содержится в строке S, в строку S1 выделяется из S очередное число, в строке S2 "складируются" обработанные шестнадцатеричные числа. При обработке числа, записанного в строку S1, вначале определяется позиция k его первой цифры: k = 2, если число имеет знак, в противном случае k = 1. После этого в цикле While удаляются нулевые цифры числа до тех пор, пока в позицию k не будет установлена ненулевая цифра. Дополнительное условие length(S1) > k, проверяемое в цикле While, означает, что в числе должна оставаться хотя бы одна цифра (или знак и цифра). Это используется для того, чтобы в нулевом значении (например, в форме '0000') не были удалены все нули.
Program Task505; Var i,k,k1,k2 : byte; Cond : boolean; S,S1,S2 : string; { --------------------------------------------------- } Function Comma(k:byte):byte; { Поиск ближайшей запятой, начиная с позиции k } Var i : byte; Begin Comma:=0; For i:=k to length(S) do If S[i]=',' then Begin Comma:=i; Exit End; End{ Comma }; { --------------------------------------------------- } Begin Readln(S); Writeln('S=',S); Cond:=true; k2:=0; S2:=''; WhileCond do Begin k1:=k2+1; k2:=Comma(k1+1); If k2=0 then Begin k2:=length(S)+1; Cond:=false; End; S1:=Copy(S,k1,k2-k1); k:=1; If (S1[1]='+') or (S1[1]='-') then k:=2; While (S1[k]='0') and(length(S1)>k) do Delete(S1,k,1); S2:=S2+S1+','; End; Delete(S2,length(S2),1); S:=S2; Writeln('S=',S); End. ¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾
5.6. Разделителями между словами текста являются: пробел, запятая, точка, двоеточие, точка с запятой, вопросительный и восклицательный знаки. Каждый из разделителей может быть окружен слева и справа одним или несколькими пробелами. Отредактировать текст следующим образом: - в начале строки установить три пробела; - удалить пробелы в конце строки; - удалить пробелы, имеющиеся перед любым из разделителей (в том числе и пробелом); - после каждого разделителя, кроме пробела, установить лишь один пробел.
Строка-константа Separs содержит список разделителей, причем первым из них является пробел. Последовательность обработки исходной строки S : - если после пробела следует любой другой разделитель, в том числе пробел, то пробел удаляется; - если после разделителя, не являющегося пробелом (Pos(S[i], Separs) > 1), нет пробела, то производится вставка пробела после этого разделителя. После выполнения первого этапа ни в начале, ни в конце строки не может быть более одного пробела. Дальнейшие действия: - если в конце строки имеется пробел, то он удаляется; - если в начале строки нет пробела, то в первую позицию строки вставляется пробел; - в начало строки дописываются два пробела.
Program Task506; Const Separs = ' ,.:;?!'; Var i : byte; S : string; Begin Readln(S); Writeln('S=',S); i:=1; { Удаление избыточных } While i<length(S) do { пробелов } If (S[i]=' ') and(Pos(S[i+1],Separs)>0) then Delete(S,i,1) Else Inc(i); i:=length(S)-1; While i>=1 do { Вставка пробела } Begin { после разделителя } If(Pos(S[i],Separs)>1) and (S[i+1]<>' ') then Insert(' ',S,i+1); Dec(i); End; IfS[length(S)]=' ' then { Удаление пробела } Delete(S,length(S),1); { в конце строки } If S[1]<>' ' then { Установка трех } S:=' '+S; { пробелов в начале } S:=' '+S; Writeln('S=',S); { строки } End. ¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾
5.7. Определить, имеются ли в тексте слова с повторяющимися символами.
Проверка наличия повторяющихся символов в очередном слове, скопированном в строку S1, производится функцией RepeatCharacter. Если повторение символов в каком-либо слове обнаружено, то дальнейшая обработка строки S не выполняется.
Program Task507; Label 10; Var k1,k2 : byte; Cond,Result : boolean; S,S1 : string; { ------------------------------- } Function RepeatCharacter:boolean; { Проверка наличия повторяющихся символов в слове } Var i,j : byte; Begin RepeatCharacter:=false; For i:=1 tolength(S1)-1 do For j:=i+1 tolength(S1) do If S1[i]=S1[j] then Begin RepeatCharacter:=true; Exit End; End{ RepeatCharacter }; { ------------------------------- } Begin Readln(S); Writeln('S=',S); k2:=0; Result:=false; Cond:=true; While Cond do Begin k1:=NotSpace(k2+1); If k1=0 then Cond:=false Else Begin k2:=Space(k1+1); Ifk2=0 then Begin k2:=length(S)+1; Cond:=false End; S1:=Copy(S,k1,k2-k1); Result:=RepeatCharacter; If Result then Goto 10; End; End; 10: If Result then Writeln('В тексте имеются слова с повт.символами') Else Writeln('В тексте нет слов с повт.символами'); End. ¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾
5.8. В строке записан строчными буквами текст на русском языке. Определить количество слов, содержащих удвоенные гласные.
Список гласных содержится в строке-константе Vocal. Проверку наличия двух подряд стоящих одинаковых гласных выполняет функция DoubleVocal. Если выходное значение этой функции равно true, то производится добавление единицы в счетчик Count.
Program Task508; Const Vocal = 'аеиоуыэюя'; Var k1,k2,Count : byte; Cond : boolean; S,S1 : string; { ------------------------------- } Function DoubleVocal:boolean; { Проверка удвоения гласных в слове } Var i,p : byte; Begin DoubleVocal:=false; Fori:=1 to length(S1)-1 do Begin p:=Pos(S1[i],Vocal); If (p>0) and(S1[i]=S1[i+1]) then Begin DoubleVocal:=true; Exit End; End; End{ DoubleVocal }; { ------------------------------- } Begin Read(S); Writeln('S=',S); Count:=0; k2:=0; Cond:=true; While Cond do Begin k1:=NotSpace(k2+1); If k1=0 then Cond:=false Else Begin k2:=Space(k1+1); If k2=0 then Begin k2:=length(S)+1; Cond:=false End; S1:=Copy(S,k1,k2-k1); If DoubleVocal then Inc(Count); End; End; Writeln('Count=',Count); End. ¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾
5.9. В строке записан некоторый текст, в состав которого входят слова и целые десятичные числа без знака. Заменить каждое число суммой его цифр. В результирующей строке оставить между словами по одному пробелу, в начале и в конце строки пробелы удалить.
Список десятичных цифр записан в строке-константе Digit. Если в очередном слове первый символ S[k1] - цифра, то производится обработка этого слова как числа. Для этого после переписи его в строку S1 осуществляется с помощью процедуры DigitsSumma суммирование цифр и формирование символьной записи нового числа в строке S2. Если длина строки S2 меньше, чем строки S1, то строка S2 дополняется соответствующим количеством пробелов. После этого исходное число удаляется из строки S, а новое число вставляется в эту строку. На последнем этапе работы программы производится удаление избыточных пробелов в соответствии с условием задачи. Если очередное число состоит из одной цифры, то замена такого числа в строке S не производится.
Program Task509; Const Digit = '0123456789'; Var i,k1,k2,p : byte; Cond : boolean; S,S1,S2 : string; { --------------------------------------------------- } ProcedureDigitsSumma; { Определение суммы цифр числа } Var i,Dig : byte; Code,Sum : integer; Begin Sum:=0; For i:=1 tolength(S1) do Begin Val(S1[i],Dig,Code); Sum:=Sum+Dig; End; Str(Sum,S2); If length(S2)<length(S1) then For i:=1 to length(S1)-length(S2) do S2:=S2+' '; End{ DigitsSumma }; { --------------------------------------------------- } Begin Readln(S); Writeln('S=',S); k2:=0; Cond:=true; WhileCond do Begin k1:=NotSpace(S,k2+1); If k1=0 then Cond:=false Else Begin k2:=Space(S,k1+1); If k2=0 then Begin k2:=length(S)+1; Cond:=false End; p:=Pos(S[k1],Digit); If p>0 then Begin S1:=Copy(S,k1,k2-k1); Iflength(S1)>1 then Begin DigitsSumma; Delete(S,k1,k2-k1); Insert(S2,S,k1); End; End; End; End; i:=1; Whilei<length(S) do If (S[i]=' ') and (S[i+1]=' ') then Delete(S,i,1) Else Inc(i); If S[1]=' ' then Delete(S,1,1); If S[length(S)]=' ' then Delete(S,length(S),1); Writeln('S=',S); End. ¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾
5.10. В строке записан текст на русском языке. В составе текста могут быть целые десятичные числа без знака. Для записи слов используются как прописные, так и строчные буквы. Определить количество слов, в которых все буквы различные.
После выделения слова (не числа) производится преобразование малых букв в большие. Поскольку в слове используются не латинские буквы, то такое преобразование не может быть выполнено с помощью функции UpCase. Для этого в программе Task510 используется строка-константа с перечнем малых букв алфавита и символьный массив с перечнем больших букв (строку-константу нельзя индексировать). Если в слове нет повторяющихся букв, то выходное значение функции DifLetters будет равным true; в этом случае производится добавление единицы в счетчик слов Count.
ProgramTask510; Const Digits = '0123456789'; Var k1,k2,Count : byte; Cond : boolean; S,S1 : string; { --------------------------------------------------- } Function DifLetters:boolean; { true, если в слове S1 нет повторяющихся букв } Const Alf = 'абвгдежзийклмнопрстуфхцчшщэыъьюя'; AlfAr : array[1..32] of char =('А','Б','В','Г','Д','Е', 'Ж','З','И','Й','К','Л','М','Н','О','П','Р','С','Т','У', 'Ф','Х','Ц','Ч','Ш','Щ','Э','Ы','Ъ','Ь','Ю','Я'); Var i,j,k,ls : byte; Begin DifLetters:=true; ls:=length(S1); For i:=1 to ls do { преобразование строчных } Begin { букв в прописные } k:=Pos(S[i],Alf); Ifk>0 then S[i]:=AlfAr[k]; End; For i:=1 to ls-1 do { проверка наличия } For j:=i+1 tols do { повторяющихся букв } If S1[i]=S1[j] then Begin DifLetters:=false; Exit End; End { DifLetters }; { --------------------------------------------------- } Begin Readln(S); Writeln('S=',S); k2:=0; Cond:=true; Count:=0; While Cond do Begin k1:=NotSpace(S,k2+1); Ifk1=0 then Cond:=false Else Begin k2:=Space(S,k1+1); If k2=0 then Begin k2:=length(S)+1; Cond:=false End; S1:=Copy(S,k1,k2-k1); If (Pos(S1[1],Digits)=0) and DifLetters then Inc(Count); End; End; Writeln('Count=',Count); End. ¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾
5.11. В строке записан строчными буквами текст на русском языке. Определить значение и порядковый номер слова, содержащего максимальное количество согласных. Учесть, что в частном случае в состав слова могут входить цифры.
В программе Task511 используется список согласных, записанный в строке-константе Consonants. Определение количества согласных в очередном слове, переписанном из строки S в строку S1, производит функция NumCons. Результатом работы программы является печать порядкового номера слова pmax и количества содержащихся в нем согласных ConsMax.
Program Task511; Const Consonants = 'бвгджзклмнпрстфхцчшщ'; Var k1,k2, p, { порядковый номер слова } pmax, { пор.номер слова с макс.кол-вом согласных } Cons, { кол-во согласных в слове } ConsMax : byte; { макс.кол-во согласных в слове } Cond : boolean; S,S1 : string; { ------------------------------- } Function NumCons:byte; { Определение кол-ва согласных в слове S1 } Var i,k,p : byte; Begin k:=0; For i:=1 tolength(S1) do Begin p:=Pos(S1[i],Consonants); If p>0 then Inc(k); End; NumCons:=k; End { NumCons }; { ------------------------------- } Begin Read(S); Writeln('S=',S); k2:=0; p:=0; pmax:=0; Cond:=true; ConsMax:=0; While Cond do Begin k1:=NotSpace(S,k2+1); Ifk1=0 then Cond:=false Else Begin k2:=Space(S,k1+1); Ifk2=0 then Begin k2:=length(S)+1; Cond:=false End; Inc(p); S1:=Copy(S,k1,k2-k1); Cons:=NumCons; If Cons>ConsMax then Begin pmax:=p; ConsMax:=Cons; End; End; End; Writeln('ConsMax=',ConsMax,' pmax=',pmax); End. ¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾
5.12. В строке записан список идентификаторов и целых десятичных чисел. Элементы списка разделены между собой запятыми. Определить порядковый номер элемента, являющегося идентификатором с максимальным количеством цифр.
Как известно, идентификатор - это последовательность букв и цифр, начинающаяся с буквы. Поэтому для его индикации в программе Task512 производится проверка первого символа очередного слова S1, выделенного из исходной строки S. В задаче не требуется определять, какая именно цифра содержится в числе или в идентификаторе, здесь достаточно произвести проверку, является ли заданный символ цифрой или не цифрой. Поэтому для такой проверки вместо строки-константы используется множество-константа Digits. Непосредственный подсчет количества цифр в идентификаторе выполняет функция DigitsNumber.
Program Task512; Const Digits = ['0'..'9']; Var k1,k2, Dig, { кол-во цифр в идентификаторе } DigMax, { макс.кол-во цифр } OrdNumber, { порядковый номер ид-ра } OrdMax : byte; { номер ид-ра с макс.кол-вом цифр } Cond : boolean; S,S1,Smax : string; { --------------------------------------------------- } Function DigitsNumber:byte; { Определение количества цифр в идентификаторе } Var i,k,ls : byte; Begin k:=0; ls:=length(S1); For i:=1 to ls do IfS1[i] in Digits then Inc(k); DigitsNumber:=k; End { DigitsNumber }; { --------------------------------------------------- } Begin Readln(S); Writeln('S=',S); Digmax:=0; OrdNumber:=0; Cond:=true; k2:=0; While Cond do Begin k1:=NotSpace(S,k2+1); If k1=0 then Cond:=false Else Begin k2:=Space(S,k1+1); If k2=0 then Begin k2:=length(S)+1; Cond:=false End; Inc(OrdNumber); S1:=Copy(S,k1,k2-k1); If not(S1[1] inDigits) then Begin Dig:=DigitsNumber; IfDig>DigMax then Begin DigMax:=Dig; OrdMax:=OrdNumber; End; End; End; End; Writeln('DigMax=',DigMax,' OrdMax=',OrdMax); End. ¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾
5.13. В строке записан строчными буквами текст на русском языке. Определить количество слов, содержащих свыше двух подряд идущих согласных букв.
Программа Task513 во многом аналогична программе Task511, но вместо подсчета количества согласных проверяется, имеются ли в слове три подряд идущие согласные, для чего используется функция Cons3.
ProgramTask513; Const Consonants = 'бвгджзклмнпрстфхцчшщ'; Var k1,k2,NumWords : byte; Cond : boolean; S,S1 : string; { --------------------------------------------------- } Function Cons3:boolean; { Проверка наличия в слове трех последовательных согласных } Var i,p1,p2,p3 : byte; Begin Cons3:=false; For i:=1 to length(S1)-2 do Begin p1:=Pos(S1[i],Consonants); p2:=Pos(S1[i+1],Consonants); p3:=Pos(S1[i+2],Consonants); If (p1>0) and (p2>0) and (p3>0) then Begin Cons3:=true; Exit End; End; End { Cons3 }; { --------------------------------------------------- } Begin Readln(S); Writeln('S=',S); k2:=0; NumWords:=0; Cond:=true; While Cond do Begin k1:=NotSpace(S,k2+1); If k1=0 then Cond:=false Else Begin k2:=Space(S,k1+1); If k2=0 then Begin k2:=length(S)+1; Cond:=false End; S1:=Copy(S,k1,k2-k1); If Cons3 then Inc(NumWords); End; End; Writeln('NumWords=',NumWords); End. ¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾
5.14. Задан произвольный массив неповторяющихся натуральных чисел. Записать эти числа в строке, используя диапазоны. В диапазон включать группу, содержащую не менее трех чисел. Числа в строке должны быть упорядочены по возрастанию. Элементы строки разделять одним пробелом. Например, для массива X = (15,88,36,12,14,89,37,13,8,87,11,90,91,35,77,44,10,7,86) получим: S = '7 8 10..15 35..37 44 77 86..91' .
В программе Task514 обрабатывается массив, сгруппированный по возрастанию. В связи с этим на начальном этапе работы программы с помощью процедуры Buble, реализующей метод "пузырька", производится группировка исходного массива X. Накапливание диапазонного списка чисел в символьном виде осуществляется в строке S, которой первоначально присваивается пустое значение. Для выделения из массива X отрезка натурального ряда чисел, т.е. группы чисел, в которой разница между смежными элементами равна 1, используются переменные k1 и k2: k1 указывает индекс первого числа очередной группы (начало группы), k2 определяет конец группы (индекс ближайшего числа, не принадлежащего группе). Для определения конца группы (значения переменной k2) используется функция SignEnd. Тогда начало следующей группы k1 принимается равным k2 (для первой группы k1 = 1). Если для очередной группы имеет место k2 - k1 > 2, то это означает, что числа x[k1] и x[k2-1] являются границами диапазона. Тогда после преобразования их к символьному виду при записи в строку S между указанными числами включается подстрока '..' , в противном случае они разделяются в строке S пробелом.
Program Task514; Const Nmax = 200; Type Ar = array[1..Nmax] of word; Var k1,k2,n : byte; Cond : boolean; X : Ar; S,S1 : string; { --------------------------------------------------- } Procedure Buble; { Группировка массива по возрастанию } Var i,m : byte; R : word; Cond : boolean; Begin Cond:=true; m:=n-1; While Cond do Begin Cond:=false; For i:=1 to m do Ifx[i]>x[i+1] then Begin R:=x[i]; x[i]:=x[i+1]; x[i+1]:=R; Cond:=true; End; Dec(m); End; End { Buble }; { --------------------------------------------------- } Function SignEnd(k:byte):byte; { Поиск конца диапазона, начиная с элемента x[k] } Var i : byte; Begin SignEnd:=0; For i:=k+1 ton do If x[i]-x[i-1]>1 then Begin SignEnd:=i; Exit End; End { SignEnd }; { --------------------------------------------------- } Begin В в о д и п е ч а т ь n, X Buble; S:=''; k2:=1; Cond:=true; While Cond do Begin k1:=k2; k2:=SignEnd(k1); Ifk2=0 then Begin k2:=n+1; Cond:=false; End; Ifk2-k1>2 then Begin Str(x[k1],S1); S:=S+S1+'..'; Str(x[k2-1],S1); S:=S+S1+' '; End Else Begin Str(x[k1],S1); S:=S+S1+' '; End; End; Writeln('S = ',S); End. ¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾
5.15. В строке записан текст телеграммы. В качестве разделителей слов используются пробел, запятая и точка. Запятая обозначается символами 'зпт', точка - символами 'тчк'. С клавиатуры вводится цена одного слова в копейках. Определить стоимость телеграммы (запятая "зпт" и точка "тчк" словами не считаются). Ответ отпечатать в виде "m грн k коп".
Выделение слов в строке S, как и ранее, производится с помощью функций Space и NotSpace. Если значение очередного слова не равно 'тчк' или 'зпт', то к счетчику слов n добавляется единица. Стоимость телеграммы Cost - это произведение значения n на цену одного слова Price. Целочисленная часть от деления Cost на 100 - это количество гривней, остаток от деления на 100 - количество копеек.
ProgramTask515; Var k1,k2, n, { количество слов } Price : byte; { цена одного слова, коп. } Cost : word; { стоимость телеграммы, коп. } Cond : boolean; S,S1,S2 : string; Begin Readln(S); Read(Price); k2:=0; Cond:=true; n:=0; WhileCond do Begin k1:=NotSpace(S,k2+1); If k1=0 then Cond:=false Else Begin k2:=Space(S,k1+1); If k2=0 then Begin k2:=length(S)+1; Cond:=false; End; S1:=Copy(S,k1,k2-k1); End; If(S1<>'тчк') and(S1<>'зпт') then Inc(n); End; Cost:=n*Price; S1:='Стоимость телеграммы '; Str(Cost div100,S2); S1:=S1+S2+' грн '; Str(Cost mod 100,S2); S1:=S1+S2+' коп '; Writeln('S1 = ',S1); End. ¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾
5.16. Расстояние между двумя словами равной длины - это количество позиций, в которых различаются эти слова. Для заданной строки текста указать номера и значения слов с максимальным расстоянием между ними.
По условию задачи требуется сравнивать все пары слов: 1 - 2 1 - 3 1 - 4 1 - 5 1 - n 2 - 3 2 - 4 2 - 5 2 - n 3 - 4 3 - 5 3 - n ....................... (n - 1) - n В общем случае для пары (i - j), где i, j - номера слов в строке, переменные i и j должны изменяться в следующих диапазонах: i = 1 .. (n-1), j = i+1 .. n . В программе Task516 для перебора слов используются два цикла: во внешнем цикле, управляемом булевской переменной Cond1, выбирается первое слово, во внутреннем, управляемом переменной Cond2, - второе слово сравниваемой пары слов. Вычисление расстояния между словами, скопированными в строки Sb1 и Sb2, производится, если количество символов в сравниваемых словах одинаково, т.е. одинаковы длины строк Sb1 и Sb2. В программе учтено, что количество слов n заранее неизвестно.
ProgramTask516; Var S, { исходная строка } Sb1max,Sb2max, { слова с макс.расстоянием между ними } Sb1,Sb2 : string; { буф.строки для анализируемых слов } i, { параметр цикла } k1,k2, { левая и правая границы первого слова } k3,k4, { левая и правая границы второго слова } n1,n2, { текущие номера слов } np1,np2, { номера слов с макс.расстоянием } d,dmax : byte; { текущее и макс.расст-я между словами } Res, { признак наличия слов одинак.длины } Cond1, { переменная для упр-я внешним циклом } Cond2 : boolean;{ то же для внутреннего цикла } Begin Readln(S); dmax:=0; Res:=false; n1:=0; k2:=0; Cond1:=true; While Cond1 do { Выделение первого } Begin { из пары сравниваемых } k1:=NotSpace(k2+1); { слов } If k1=0 then Cond1:=false Else Begin k2:=Space(k1+1); If k2=0 then Cond1:=false Else Begin Inc(n1); Sb1:=Copy(S,k1,k2-k1); Fori:=1 to length(Sb1) do Sb1[i]:=UpCase(Sb1[i]); k4:=k2+1; Cond2:=true; n2:=n1; WhileCond2 do { Выделение второго } Begin { из пары сравниваемых } k3:=NotSpace(k4+1); { слов } If k3=0 then Cond2:=false Else Begin k4:=Space(k3+1); Ifk4=0 then Begin k4:=length(S)+1; Cond2:=false; End; Inc(n2); Sb2:=Copy(S,k3,k4-k3); If length(Sb1)=length(Sb2) then Begin Res:=true; d:=0; Fori:=1 to length(Sb2) do Sb2[i]:=UpCase(Sb2[i]); For i:=1 to length(Sb1) do IfSb1[i]<>Sb2[i] then Inc(d); Ifd>dmax then Begin dmax:=d; np1:=n1; np2:=n2; Sb1max:=Sb1; Sb2max:=Sb2; End; End; End; End; End; End; End; If not Res then Writeln('В строке нет слов одинаковой длины') Else Begin Writeln('dmax = ',dmax); Writeln('np1 = ',np1,' Sb1max = ',Sb1max); Writeln('np2 = ',np2,' Sb2max = ',Sb2max); End; End. ¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾
5.17. Сгруппировать слова в тексте в порядке уменьшения их длин, разделив между собой одним пробелом. Например, для исходного текста aa bbbbbb uuu rrrrrrrr ttttttttt e vvvv nnnnnnnnnnn ss получим nnnnnnnnnnn ttttttttt rrrrrrrr bbbbbb vvvv uuu aa ss e .
Слово минимальной длины содержит один символ. С учетом пробелов между словами максимальное количество слов в строке может быть 128. В программе Task517 при последовательном просмотре строки S формируется массив записей Params, i-ая компонента которого содержит два элемента: начальную позицию k1 i-го слова и его длину l. После формирования массива Params с n компонентами производится его группировка по убыванию параметра l. После этого в соответствии с условием задачи создается новая строка.
Program Task517; Const Nmax = 128; Type ParamType = record k1,l : byte; end; ParamAr = array[1..Nmax] of ParamType; Var S,S1 : string; i,k1,k2,l,n : byte; Cond : boolean; ch : char; Param : ParamType; Params : ParamAr; { --------------------------------------------------- } Procedure Buble; { Группировка массива Params по убыванию длины слова l } Var i,m : byte; Cond : boolean; Begin Cond:=true; m:=n-1; While Cond do Begin Cond:=false; For i:=1 to m do IfParams[i].l<Params[i+1].l then Begin Param:=Params[i]; Params[i]:=Params[i+1]; Params[i+1]:=Param; Cond:=true; End; Dec(m); End; End{ Buble }; { --------------------------------------------------- } Begin Readln(S); Writeln('S=',S); n:=0; k2:=0; Cond:=true; While Cond do Begin k1:=NotSpace(S,k2+1); Ifk1=0 then Cond:=false Else Begin k2:=Space(S,k1+1); { Запись в массив } Ifk2=0 then { Params нач.позиции } Begin { и длины каждого слова } k2:=length(S)+1; Cond:=false; End; l:=k2-k1; Inc(n); Param.k1:=k1; Param.l:=l; Params[n]:=Param; End; End; Buble; S1:=''; { Перепись в строку S1 } Fori:=1 ton do { слов исходного текста } Begin { в порядке уменьшения } k1:=Params[i].k1; l:=Params[i].l; { их длин } S1:=S1+Copy(S,k1,l)+' '; End; Delete(S1,length(S1),1); S:=S1; Writeln('S=',S); End. ¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾
5.18. Даны две строки, содержащие цифры двух длинных целых десятичных чисел. Найти сумму этих чисел.
Алгоритм решения задачи 5.18 аналогичен алгоритму, реализованному в программе 3.09 по отношению к числовым массивам цифр, но его реализация в программе Task518 трансформирована для символьного представления цифр.
Program Task518; Const Digits = '0123456789'; Var i,l1,l2,ls,dl,Dig1,Dig2, DigSum,p : byte; Cond : boolean; S1,S2,Sum : string; Sb : string[1]; Begin Readln(S1); Readln(S2); l1:=length(S1); l2:=length(S2); dl:=abs(l2-l1); If l1>l2 then For i:=1 todl do S2:='0'+S2; If l1<l2 then For i:=1 todl do S1:='0'+S1; If l1>l2 then ls:=l1 Else ls:=l2; Sum:=''; p:=0; For i:=ls downto 1 do Begin Dig1:=Pos(S1[i],Digits)-1; Dig2:=Pos(S2[i],Digits)-1; DigSum:=Dig1+Dig2+p; If DigSum>=10 then Begin DigSum:=DigSum-10; p:=1; End Else p:=0; Str(DigSum,Sb); Sum:=Sb+Sum; End; If p=1 then Sum:='1'+Sum; Writeln('Sum = ',Sum); End. ¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾
5.19. Даны две строки, содержащие цифры двух длинных целых десятичных чисел. Найти разность этих чисел.
Алгоритм решения задачи 5.19 аналогичен алгоритму, реализованному в программе 3.10 по отношению к числовым массивам цифр, но его реализация трансформирована для символьного представления цифр.
Program Task519; Label 10; Const Digits = '0123456789'; DigAr : array[1..10] of char = ('0','1','2','3','4','5','6','7','8','9'); Var i,j,l1,l2,ls,dl,k,k1, Dig1,Dig2,DigSub : byte; CondMinus,Cond : boolean; S1,S2,Sub : string; Sb : string[1]; Begin Readln(S1); Readln(S2); l1:=length(S1); l2:=length(S2); dl:=abs(l2-l1); If l1>l2 then For i:=1 todl do S2:='0'+S2; If l1<l2 then For i:=1 todl do S1:='0'+S1; If l1>l2 then ls:=l1 Else ls:=l2; CondMinus:=false; If S1[1]<S2[1] then Begin Sub:=S1; S1:=S2; S2:=Sub; CondMinus:=true; End; Sub:=''; For i:=ls downto 1 do Begin Dig1:=Pos(S1[i],Digits)-1; Dig2:=Pos(S2[i],Digits)-1; If Dig1<Dig2 then Begin Forj:=i-1 downto 1 do IfS1[j]>'0' then Begin k1:=Pos(S1[j],Digits); S1[j]:=DigAr[k1-1]; For k:=j+1 to i-1 do S1[k]:='9'; Dig1:=Dig1+10; Goto 10; End; 10: End; DigSub:=Dig1-Dig2; Str(DigSub,Sb); Sub:=Sb+Sub; End; IfCondMinus then Sub:='-'+Sub; Writeln('Sub = ',Sub); End. ¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾
Задания для самостоятельной работы 5.20. По отношению к строке с объявленной длиной символов требуется: - если текущая длина строки меньше значения , то добавить в конце строки пробелов; - сдвинуть последнее слово к концу строки; - в начале строки установить три пробела; - выравнять промежутки между словами так, чтобы количества пробелов между ними были равными или отличались между собой не более чем на единицу. 5.21. В строке записаны слова и целые десятичные числа. Для записи слов используются большие и малые русские буквы. Длина слова не превышает £ 16 букв. Cформировать словарь слов и отпечатать его в алфавитном порядке. 5.22. Удалить из текста слова с четными порядковыми номерами, а в остальных словах переставить буквы в обратном порядке. 5.23. Слова, состоящие не более чем из двух букв, слить вместе в последовательности, противоположной их расположению в тексте, одновременно удалив их из текста. Сформированное таким образом новое слово записать в начале строки, отделив от остальной ее части одним пробелом, если в начале строки не было пробела. 5.24. В каждом слове текста удалить минимальное количество символов так, чтобы в преобразованном слове не было повторяющихся символов. 5.25. В строке записана произвольная последовательность символов . Конечный фрагмент строки (1 £ £ ) может быть симметричным. Добавить к строке минимальное количество символов так, чтобы последовательность стала палиндромом. 5.26. В строке записаны слова исходного текста, в отдельной строке - одно из слов, которое может быть в строке (количество букв в не превышает 10). В словах исходного текста могут быть ошибки, в частности, могут быть переставлены две соседние буквы. Проверить текст в строке и, если в нем имеется слово с наличием указанной ошибки, то необходимо скорректировать это слово. 5.27. То же, что 5.27, но в качестве возможной ошибки рассматривать пропуск одной буквы. 5.28. То же, что 5.27, но в качестве возможной ошибки рассматривать замену одной буквы. 5.29. Символами строки являются большие и малые латинские буквы. Удалить из состава строки последовательности 'abcd', в составе которых могут быть как большие, так и малые буквы. 5.30. Строка содержит произвольные символы таблицы ASCII. Удалить из строки все цифры и повторить дважды каждый символ, кроме пробела, не являющийся цифрой. Просмотр строки осуществлять один раз. 5.31. Строка имеет объявленную длину символов. Заменить в тексте строки слова "child" словами "children". Если при этом длина строки превысит символов, избыточные слова разместить в новой строке, не используя знак переноса части слова. Буферную строку не использовать. 5.32. В строке записано арифметическое выражение, состоящее из идентификаторов, целых десятичных чисел, знаков операций и круглых скобок. Внутренними скобками считается такая пара '(' и ')', внутри которой нет других скобок. Требуется удалить из строки содержимое внутренних скобок (вместе со скобками). Учесть, что в строке может быть несколько пар внутренних скобок. 5.33. В строке содержится список десятичных чисел, содержащих целую и дробную части, разделенные точкой. Элементы списка разделены запятыми. Если в дробной части числа свыше двух цифр, округлить ее до двух цифр, сократив соответственно длину строки. 5.34. В строке содержится список десятичных чисел, содержащих целую и дробную части, разделенные точкой. Элементы списка разделены запятыми. Требуется удалить незначащие нули в целой и дробной частях, если они имеются. Если при этом полностью удаляется дробная часть, то удалению подлежит также разделяющая их точка. В частности, число '19.998' после округления должно принять вид '20.00'. 5.35. Если в строке имеются последовательности, состоящие из более чем трех одинаковых символов, то заменить каждую такую последовательность подстрокой , где - признак повторения, - двухзначное число, определяющее количество повторений, - повторяющийся символ. В качестве признака повторений взять неиспользуемый в тексте символ #14. Составить две процедуры, выполняющие соответственно сжатие и восстановление текста. 5.36. Заданы две строки и . Удалить из строки символы, содержащиеся в строке . 5.37. Строка содержит произвольные символы таблицы ASCII. Найти наиболее длинную последовательность цифр и удалить ее из строки. 5.38. Определить, имеется ли в тексте хотя бы одно слово, которое является перестановкой букв другого слова этого же текста (например, "рост" и "сорт"). Отпечатать номера и значения такой пары слов. 5.39. В словах текста используются лишь большие и малые латинские буквы. Определить количества буквосочетаний из двух букв (aa, ab, ac и т.д.). Отпечатать 10 буквосочетаний с максимальной частотой (по убыванию частоты). Указание. Рекомендуется объявить матрицу A типа array['a'..'z','a'..'z'] of byte, обнулив ее элементы на начальном этапе работы программы. Тогда, выделив из слова очередную пару букв, например 'ps', необходимо лишь добавить единицу к элементу a['p','s']. 5.40. В строке записаны слова и целые положительные числа, не превышающие значения 3000. Заменить каждое число его представлением в римской системе счисления. 5.41. Кроме слов, в строке содержатся числа, записанные в римской системе счисления. Признаком такого числа является то, что все его символы - большие латинские буквы I, V, X, L, C, D, M. Заменить каждое такое число его десятичным представлением. 5.42. В строке малыми латинскими буквами записаны слова, разделяющиеся запятыми. Первые буквы некоторых слов могут совпадать. Указать минимальное количество первых букв, по которым можно различить слова из заданного списка. 5.43. Ученики зашифровывают свои записки, записывая все слова наоборот и расставляя их в предложении в обратном порядке. В строке содержится несколько предложений, при этом точка установлена справа от первого слова. Составить программу, позволяющую адресату прочесть записку без ручной дешифрации. 5.44. В строке записано выражение, состоящее из идентификаторов, знаков арифметических операций и круглых скобок. Между элементами выражения могут быть пробелы. При записи выражения возможны следующие ошибки: - несоответствие количества открывающих и закрывающих скобок; - закрывающая скобка расположена до открывающей; - отсутствуют содержательные символы между скобками, т.е. символы, отличные от пробела и знаков операций. Определить наличие каждого типа ошибки и, если это возможно, ее местоположение. При обнаружении любой ошибки дальнейшая проверка строки прекращается. |
||
Последнее изменение этой страницы: 2018-06-01; просмотров: 135. stydopedya.ru не претендует на авторское право материалов, которые вылажены, но предоставляет бесплатный доступ к ним. В случае нарушения авторского права или персональных данных напишите сюда... |