[size=12]При выполнении заданий на анализ и преобразование слов главная Проблема заключается в выделении каждого слова из исходной строки. Будем предполагать, что строка не является пустой, не содержит начальных и конечных пробелов, и слова в ней разделяются одним или несколькими пробелами. Опишем для таких строк алгоритм выделения слов, использующий стандартные функции и процедуры для работы со строками.
Ищется первый пробел в строке; начало строки, вплоть до найденного пробела, представляет собой первое слово. После обработки этого слова оно удаляется из исходной строки вместе со следующими за ним пробелами. Если после этого строка не становится пустой, то описанная процедура повторяется (в результате выделяется второе слово, и т. д.). Для правильной обработки последнего слова необходимо, чтобы оно также оканчивалось пробелом (этот пробел надо добавить к исходной строке перед началом ее обработки).
Воспользуемся описанным алгоритмом для решения задачи, в которой требуется подсчитать количество слов в строке:[/size]
Quote
uses SysUtils; // в PascalABC.NET модуль SysUtils подключать к программе не следует//
var S: string;
N, К: integer;
begin
Readln(S);;
N:=0;
while S<>'' do
begin
K:=Pos(' ',S); //Ищем очередной пробел
Inc(N); //выполнение обработку очередного слова (в данном случае увеличивается счетчик на N)
Delete(S,1,K); //Удаляем слово и следующий за ним пробел
S:=TrimLeft(S); //Удаляем оставшиеся начальные пробелы
end;
WRiteln(N);
end.
Для удаления оставшихся начальных пробелов мы использовали функцию TrimLeft. В Delfi Pascal эта функция описана в модуле SysUtils, поэтому данный модуль необходимо указать в списке uses. В PascalABC.NET для использования функции TrimLeft не требуется подключать к программе дополнительные модули.
Заметим, что алгоритм легко модифицировать так, чтобы он правильно обрабатывал строки, имеющие начальные и конечные пробелы (а также пустые строки и строки, состоящие из одних пробелов). Для этого следует изменить оператор S:=S+'' следующим образом:
S:=TrimLeft(S+' ').
В нашей задаче обработка слов сводится к выполнению единственного оператора Inc(N). Если бы нам потребовалось выделить из строки найденное слово, то это было бы легко сделать с помощью выражения Copy(S,1,K-1).
Для поиска слов в строке можно также использовать посимвольный анализ строки, который, как правило, оказывается больее эффективным. В нашем случае достаточно воспользоваться тем фактом, что каждому слову в строке, кроме первого, предшествет пробел:
uses SysUtils;
var S: string;
N, I: integer;
begin
Readln(S);
N:=0;
S:=' '+S; //Теперь пробел есть перед каждым словом
for I:=2 to Length(S)
if (S[I-1]=' ') and (S[I]<>' ') then Inc(N);
WRite(N);
end.
При решении других задач на обработку слов с помощью посимвольного анализа обычно требуется так же распознавать конец каждого слова; для этого достаточно проверять, располагается ли пробел за анализируемым символом (при этом, как и в первом варианте решения задачи перед началом обработки исходной строки необходимо добавить в её конец дополнительный пробел). Приведём "универсальный" алгоритм выделения слов из строки S, основанный на её посимвольном анализе:
S:=' '+S+' ';
for I:=2 to Length(S)-1 do
begin
if (S[I-1]=' ') and (S[I]<>' ') then N:=I;
if (S[I+1]=' ') and (S[I]<>' ') then
begin
<обработка очередного слова, равного Copy(S,N,I-N+1)>
end;
end;
Заметим, что данный вариант алгоритма выделения слов из строки будет правильно обрабатывать строки, содержанщие начальные и конечные пробелы, а также пустые строки и строки, состоящие из одних пробелов.