Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 06.09.2011, 05:27   #1
artemavd
Старожил
 
Аватар для artemavd
 
Регистрация: 05.06.2008
Сообщений: 4,206
Вопрос Последовательность слов в тексте

Добрый день! Наличие или отсутствие какого-либо слова в тексте нет проблемы определить. А вот можно ли определить есть ли в тексте какая-либо последовательность слов? Например.

Есть текст №1:
какой-то текст слово1 слово2 тут другой текст.
Есть текст №2:
слово1 какой-то текст слово2 тут другой текст.

Смысл в том, чтобы проверить есть ли в тексте именно последовательность необходимых слов, т.е. чтобы проверка срабатывала даже если необходимые слова разделены каким-то текстом. Именно, что слово1 сначала идет, а потом слово2. Если есть такая последовательность слово1 и слово2, то выдать положительное сообщение. Если нет такой последовательности, то выдать отрицательное сообщение. Можно ли осуществить такое? Заранее спасибо за советы по делу.
Не стоит смеяться над человеком делающим шаг назад, возможно он делает разбег.
artemavd вне форума Ответить с цитированием
Старый 06.09.2011, 08:26   #2
BOBAH13
Android Developer
Старожил Подтвердите свой е-майл
 
Аватар для BOBAH13
 
Регистрация: 19.02.2007
Сообщений: 3,708
По умолчанию

Цитата:
Можно ли осуществить такое?
Да. По успешному сценарию:
1. константа слово1
2. константа слово2
3. входной текст
4. проводим поиск константы 1 (если нет слова, возврат функции false)
5. найдя индекс константы 1, инкрементируем индекс на длину константы 1
6. от полученного индекса ведем поиск константы 2 (если нет слова, возврат функции false)
7. возврат функции true

Думаю PosEx вполне должна подойти.
BOBAH13 вне форума Ответить с цитированием
Старый 06.09.2011, 08:47   #3
Utkin
Старожил
 
Аватар для Utkin
 
Регистрация: 04.02.2009
Сообщений: 17,351
По умолчанию

Я раньше занимался подобными экспериментами. В частности представлял строку как массив слов, разделителем служил пробел. Тогда задача сводится к классическим манипуляциям с элементами массива.
У меня где-то даже валялся исходник юнита, с набором функций где строка представляется как массив, стек и т.д. Удобно обрабатывать слова и предложения .
Если не заморачиваться и все по-быстрому (задача на один раз), то можно строку загнать в TStringList и выставить разделителем пробел. Тогда каждый элемент по идее будет являться словом. То есть задача опять будет сведена к операции над массивом.
Маньяк-самоучка
Utkin появился в результате деления на нуль.
Осторожно! Альтернативная логика

Последний раз редактировалось Utkin; 06.09.2011 в 08:54.
Utkin вне форума Ответить с цитированием
Старый 06.09.2011, 08:56   #4
SERG1980
Участник клуба
 
Аватар для SERG1980
 
Регистрация: 28.03.2007
Сообщений: 1,814
По умолчанию

а слово1 и слово2 один раз встечаются или могут несколько раз присутствовать в тексте
SERG1980 вне форума Ответить с цитированием
Старый 06.09.2011, 08:59   #5
Utkin
Старожил
 
Аватар для Utkin
 
Регистрация: 04.02.2009
Сообщений: 17,351
По умолчанию

Да там уже без разницы, лишь бы сохранялась последовательность.
Маньяк-самоучка
Utkin появился в результате деления на нуль.
Осторожно! Альтернативная логика
Utkin вне форума Ответить с цитированием
Старый 06.09.2011, 09:18   #6
Человек_Борща
Старожил
 
Аватар для Человек_Борща
 
Регистрация: 30.12.2009
Сообщений: 11,426
По умолчанию

Интерсная задачка=)
Я решил немного по своему, разделитель слов знак | т.к. пробелом можно и дел натворить...
Вот решил помочь:
Код:
function WordsIsPossible(aWords,aText: string): Boolean;
const
  Delim = '|'; //words delimiter
var
  s: string; //text
  WordsMass: array of string; //массив слов
  WordsPosIndexes: array of integer; //массив позиций слов
  i, i1: Integer;
  ErrLevel: Integer;
begin
  i := 0;
  ErrLevel := 0;
  s := Trim(LowerCase(aText));

  if (Length(s) = 0) then
  begin
    ShowMessage('Текст не задан!');
    Inc(ErrLevel);
    Exit;
  end;

  if (Length(Trim(AWords)) = 0) then
  begin
    ShowMessage('Слова не заданы!');
    Inc(ErrLevel);
    Exit;
  end;

  if Pos(Delim, aWords) > 0 then
  begin
    i := 0;
    repeat
      Inc(i);
      SetLength(WordsMass, i);
      WordsMass[i - 1]:=LowerCase(Trim(Copy(aWords, 1, Pos(Delim, aWords) - 1)));
      Delete(aWords, 1, Pos(Delim, aWords));
    until Pos(Delim, aWords) = 0;
    i := 0;
  end
  else
  begin
    //Если в слове 1 слово без разделителя...
    SetLength(WordsMass, 1);
    WordsMass[0] := aWords;
  end;

  i1 := 0;
  for i := Low(WordsMass) to High(WordsMass) do
  begin
    if (Length(WordsMass[i]) <= 0) then
    begin
      Break;
    end;

    Inc(i1);
    SetLength(WordsPosIndexes, i1);
    if (i = 0) then
    begin
      //Ищем первое слово
      WordsPosIndexes[i1 - 1] := Pos(WordsMass[i], s);
    end
    else
    begin
      //Ищем слово i в строке s, начиная с ппредыдущего смещения
      WordsPosIndexes[i1 - 1] := PosEx(WordsMass[i], s, WordsPosIndexes[i1 - 2]);
    end;

    if (WordsPosIndexes[i1 - 1] = 0) then
    begin
      ShowMessage('Слова "' + WordsMass[i] + '" нет в тексте... последовательность нарушена');
      Inc(ErrLevel);
      Exit;
    end;
  end;
  if (ErrLevel > 0) then
    Result := False
  else
    Result := True;
end;
Функция ищет слова Awords разделённые знаком |, в тексте aText.
При этом учитывается только нахождение всех слов aText, Если хоть одно слово не найдено, то false

P.S. PoxEx находится в StrUtils.pas
P.P.S. Помог? ;-)

Последний раз редактировалось Человек_Борща; 06.09.2011 в 09:22.
Человек_Борща вне форума Ответить с цитированием
Старый 06.09.2011, 09:42   #7
BOBAH13
Android Developer
Старожил Подтвердите свой е-майл
 
Аватар для BOBAH13
 
Регистрация: 19.02.2007
Сообщений: 3,708
По умолчанию

Цитата:
Сообщение от Человек_Борща Посмотреть сообщение
Интерсная задачка=)
Я решил немного по своему, разделитель слов знак | т.к. пробелом можно и дел натворить...
Вот решил помочь:
Код:
function WordsIsPossible(aWords,aText: string): Boolean;
const
  Delim = '|'; //words delimiter
var
  s: string; //text
  WordsMass: array of string; //массив слов
  WordsPosIndexes: array of integer; //массив позиций слов
  i, i1: Integer;
  ErrLevel: Integer;
begin
  i := 0;
  ErrLevel := 0;
  s := Trim(LowerCase(aText));

  if (Length(s) = 0) then
  begin
    ShowMessage('Текст не задан!');
    Inc(ErrLevel);
    Exit;
  end;

  if (Length(Trim(AWords)) = 0) then
  begin
    ShowMessage('Слова не заданы!');
    Inc(ErrLevel);
    Exit;
  end;

  if Pos(Delim, aWords) > 0 then
  begin
    i := 0;
    repeat
      Inc(i);
      SetLength(WordsMass, i);
      WordsMass[i - 1]:=LowerCase(Trim(Copy(aWords, 1, Pos(Delim, aWords) - 1)));
      Delete(aWords, 1, Pos(Delim, aWords));
    until Pos(Delim, aWords) = 0;
    i := 0;
  end
  else
  begin
    //Если в слове 1 слово без разделителя...
    SetLength(WordsMass, 1);
    WordsMass[0] := aWords;
  end;

  i1 := 0;
  for i := Low(WordsMass) to High(WordsMass) do
  begin
    if (Length(WordsMass[i]) <= 0) then
    begin
      Break;
    end;

    Inc(i1);
    SetLength(WordsPosIndexes, i1);
    if (i = 0) then
    begin
      //Ищем первое слово
      WordsPosIndexes[i1 - 1] := Pos(WordsMass[i], s);
    end
    else
    begin
      //Ищем слово i в строке s, начиная с ппредыдущего смещения
      WordsPosIndexes[i1 - 1] := PosEx(WordsMass[i], s, WordsPosIndexes[i1 - 2]);
    end;

    if (WordsPosIndexes[i1 - 1] = 0) then
    begin
      ShowMessage('Слова "' + WordsMass[i] + '" нет в тексте... последовательность нарушена');
      Inc(ErrLevel);
      Exit;
    end;
  end;
  if (ErrLevel > 0) then
    Result := False
  else
    Result := True;
end;
Функция ищет слова Awords разделённые знаком |, в тексте aText.
При этом учитывается только нахождение всех слов aText, Если хоть одно слово не найдено, то false

P.S. PoxEx находится в StrUtils.pas
P.P.S. Помог? ;-)
Чет намудрили вы))) там решается в пару строк, что вы. Алгоритм уже описал, или теперь нужно сразу код выдавать? время идет, все течет и меняется.
BOBAH13 вне форума Ответить с цитированием
Старый 06.09.2011, 09:46   #8
Utkin
Старожил
 
Аватар для Utkin
 
Регистрация: 04.02.2009
Сообщений: 17,351
По умолчанию

Особенно с ErrLevel
Код:
Inc(ErrLevel);
ну и еще
Код:
 if (ErrLevel > 0) then
    Result := False
  else
    Result := True;
Не судьба же сразу result:= False писать .
Маньяк-самоучка
Utkin появился в результате деления на нуль.
Осторожно! Альтернативная логика
Utkin вне форума Ответить с цитированием
Старый 06.09.2011, 09:48   #9
Человек_Борща
Старожил
 
Аватар для Человек_Борща
 
Регистрация: 30.12.2009
Сообщений: 11,426
По умолчанию

Кому как удобнее. Я просто интерпритировал ваш текст в код.
Загоняем слова разделённые знаком | в массив.
А далее ищем сначало первое слово а затем начиная с каждого предыдущего смещения искать след. слово. все=)
Хоть и громоздокое но работает..
Человек_Борща вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Паскаль. Определение количества слов в тексте. Evgesha Помощь студентам 17 12.04.2011 18:58
Текст, сколько слов в тексте? BigBen Помощь студентам 1 13.01.2011 19:40
количество слов в тексте almareta Помощь студентам 3 01.04.2010 20:59
Составить в алфавитном порядке список всех слов, встречающихся в тексте, и количество этих слов. KAPAHDAW Паскаль, Turbo Pascal, PascalABC.NET 2 17.02.2009 01:19
Поиск слов в тексте pleer Общие вопросы Delphi 5 23.09.2007 08:19