Страница 1 из 1

процедурку одну помогите подправить:

Добавлено: 07 апр 2008, 18:21
student1234
ниже описана процедура, котарая находит среднее слово с номером (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;

Re: процедурку одну помогите подправить:

Добавлено: 08 апр 2008, 10:51
Хыиуду
Раздел "Алгоритмы", тема "Разбиение строки на слова"

Re: процедурку одну помогите подправить:

Добавлено: 08 апр 2008, 23:53
student1234
по сути у меня есть процедура ж, и тут не только разбиение на слова...
Мне ее просто подправить надо... чтоб последние пробелы не считались как слово...
(сам текст задачи:Дан текстовый файл содержащий слова разделенные пробелами. Создать новый файл, каждая строка которого содержит слово исходного файла, имеющее номер (n+1)div2 где н-количество слов в соответствующей строке исходного файла)все процедуры выполнены кроме от этой - Я НЕ ЗНАЮ КАК ЕЕ ИСПРАВИТЬ!!!!!!!

.

Добавлено: 09 апр 2008, 09:55
BBB
Исходный вариант:
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));
.......................
Если после поседнего слова есть разделители, то фрагмент кода "// поиск первого разделителя для слова" (он еаходится выше процитированного фрагмента) установит i в значение length(s).
Стало быть (уже смотрим фрагмент "поиск последнего разделителя для слова") условие 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;
.......................
PS. И когда вставляете исходный текст, обрамляйте его тегами

Код: Выделить всё

, чтобы было удобнее его видеть.