ниже описана процедура, котарая находит среднее слово с номером (n+1)div2 , но в ней есть ошибка,помогите исправить ее, она заключается в чем: она сбивается, работает некорректно в случае если за последним словом идет пробел, как избавиться от этого?
спасибо:
procedure TFrmText.BuildRFile;
const
// множество разделителей
seps = [#0..#$1F, ' ', '.', ',', '?', ':', ';', '(', ')', '/', '\'];
var
i, k : integer; // счетчики циклов
b, e : integer; // номера начала и конца слова
s : string; // рабочая строка
workList : TStrings; // рабочий список
begin
rfile.Clear;
workList := TStringList.Create;
// проходим по всем строкам в файле
for k := 0 to GlMemo.Lines.Count-1 do
begin
workList.Clear;
s := GlMemo.Lines.Strings[k];
// заполняем список словами из текущий строки
i:=1;
while i<=length(s) do
begin
// поиск первого разделителя для слова
//while (i<=length(s))and(seps(s)) do i:=i+1;
while (i<=length(s))and(s in seps) do i:=i+1;
b:=i;
// поиск последнего разделителя для слова
if i <= length(s) then
begin
while (i<=length(s)) and (not (s in seps)) do i:=i+1;
e:=i;
end;
// добавляем найденное слово
workList.Add(copy(s,b,e-b));
end;
// ищем в каждой строке слово с индексом (n+1) div 2
if workList.Count > 0 then
rfile.Add(workList.Strings[(workList.Count + 1) div 2 - 1])
else
rfile.Add('');
end;
LBox.Items.Assign(rfile);
workList.Free;
end;
процедурку одну помогите подправить:
Модераторы: Хыиуду, MOTOCoder, Medved, dr.Jekill
Раздел "Алгоритмы", тема "Разбиение строки на слова"
Искусство программирования - заставить компьютер делать все то, что вам делать лень.
Для "спасибо" есть кнопка "Спасибо" в виде звездочки внизу под ником автора поста.
Для "спасибо" есть кнопка "Спасибо" в виде звездочки внизу под ником автора поста.
-
- Сообщения: 9
- Зарегистрирован: 05 янв 2008, 23:15
по сути у меня есть процедура ж, и тут не только разбиение на слова...
Мне ее просто подправить надо... чтоб последние пробелы не считались как слово...
(сам текст задачи:Дан текстовый файл содержащий слова разделенные пробелами. Создать новый файл, каждая строка которого содержит слово исходного файла, имеющее номер (n+1)div2 где н-количество слов в соответствующей строке исходного файла)все процедуры выполнены кроме от этой - Я НЕ ЗНАЮ КАК ЕЕ ИСПРАВИТЬ!!!!!!!
Мне ее просто подправить надо... чтоб последние пробелы не считались как слово...
(сам текст задачи:Дан текстовый файл содержащий слова разделенные пробелами. Создать новый файл, каждая строка которого содержит слово исходного файла, имеющее номер (n+1)div2 где н-количество слов в соответствующей строке исходного файла)все процедуры выполнены кроме от этой - Я НЕ ЗНАЮ КАК ЕЕ ИСПРАВИТЬ!!!!!!!
Исходный вариант:
Стало быть (уже смотрим фрагмент "поиск последнего разделителя для слова") условие if i <= length(s) не выполнится, e не будет установлено (будет иметь "левое" значение - от предыдущего прохода по циклу). Тем не менее, добавление строки в workList происходит. Причем, поскольку будет e < b, то результатом copy(s,b,e-b) будет пустая строка.
Если имеем строку не имеющую слов (состоящую только из разделителей), то e будет иметь значение, оставшееся от предыдущей строки, мыть может, бОльшее длины текущей, тогда copy(s,b,e-b) вернет какую-то непусую строку, но состоящую НЕ из букв.
Самый "краевой эффект" случится, если строка, не имеющая слов (состоящую только из разделителей) окажется первой. В этом случае перед выполнением copy(s,b,e-b) e вообще еще будет не проинициализировано. Правда, говорят, что Delphi втихаря инициализирует все переменны нулем.
Резюме. Как минимум переставить добавление в список внурь if-а. На первый взгляд, этого будет достаточно.
PS. И когда вставляете исходный текст, обрамляйте его тегами
Если после поседнего слова есть разделители, то фрагмент кода "// поиск первого разделителя для слова" (он еаходится выше процитированного фрагмента) установит i в значение length(s).student1234 писал(а):Код: Выделить всё
.............. // поиск последнего разделителя для слова if i <= length(s) then begin while (i<=length(s)) and (not (s[i] in seps)) do i:=i+1; e:=i; end; // добавляем найденное слово workList.Add(copy(s,b,e-b)); .......................
Стало быть (уже смотрим фрагмент "поиск последнего разделителя для слова") условие if i <= length(s) не выполнится, e не будет установлено (будет иметь "левое" значение - от предыдущего прохода по циклу). Тем не менее, добавление строки в workList происходит. Причем, поскольку будет e < b, то результатом copy(s,b,e-b) будет пустая строка.
Если имеем строку не имеющую слов (состоящую только из разделителей), то e будет иметь значение, оставшееся от предыдущей строки, мыть может, бОльшее длины текущей, тогда copy(s,b,e-b) вернет какую-то непусую строку, но состоящую НЕ из букв.
Самый "краевой эффект" случится, если строка, не имеющая слов (состоящую только из разделителей) окажется первой. В этом случае перед выполнением copy(s,b,e-b) e вообще еще будет не проинициализировано. Правда, говорят, что Delphi втихаря инициализирует все переменны нулем.
Резюме. Как минимум переставить добавление в список внурь if-а. На первый взгляд, этого будет достаточно.
Код: Выделить всё
..............
// поиск последнего разделителя для слова
if i <= length(s) then
begin
while (i<=length(s)) and (not (s[i] in seps)) do i:=i+1;
e:=i;
// добавляем найденное слово
workList.Add(copy(s,b,e-b));
end;
.......................
Код: Выделить всё
, чтобы было удобнее его видеть.