Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Поиск в векторе 
:(
    Опции темы
artsb
  Дата 2.12.2007, 23:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2280
Регистрация: 17.7.2007
Где: центр Вселенной

Репутация: 39
Всего: 64



Уже, наверное, все видели эту структуру   smile :
Код

struct gr{
AnsiString name;
AnsiString www;
AnsiString inf;
};
vector<gr> grp;

Нужно организовать поиск слова или сочетания слов. Например, пользователь выбирает один из трёх вариантов в ComboBox'е (3 - количество переменных в структуре). Если выбран первый вариант, поиск будет проходить по переменным name в векторе. Но в ней может храниться предложение.

Уф-ф-ф, надеюсь понятно объяснил. smile


--------------------
Чем отличается умный человек от мудрого?
Умный - выпутается из любой ситуации.
Мудрый - просто в неё не попадёт.
PM MAIL   Вверх
Diamido
Дата 3.12.2007, 08:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 8
Регистрация: 3.8.2006
Где: Сургут

Репутация: -1
Всего: нет



Если выбрана 1-я галочка только в name идёт поиск, 1-я и 2-я в name и www

Самый тривиальный способ решения:

1. Есть функция для поиска строки в подстроке, возвращает индекс где находиться первый символ искомой строки. (не помню как она называется str* вродебы)
2. Просто пишешь процедуру которая анализирует выбраные галочки и ищет по каждой строке, если найдено хоть одно совпадение возвращает индекс записи в струкруре.
3. Потов выводишь найденую структуру куда тебе надо и продолжаешь поиск если надо. 
PM MAIL ICQ   Вверх
artsb
Дата 3.12.2007, 09:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2280
Регистрация: 17.7.2007
Где: центр Вселенной

Репутация: 39
Всего: 64



Попробую объяснить ещё раз:
В ComboBox'е юзверь выбирает один из вариантов, а в Edit вводит текст. Допустим он выбрал первый, тогда поиск должен идти по name. Как только будет найдено совпадение, поиск останавливается, а мне нужно получить индекс текущего элемента вектора.
В принципе, всё это я смогу сделать, вопрос в следующем:
Как сделать поиск если в Edit может быть введено слово или сочетание слов и в name может быть слово, а может предложение?


--------------------
Чем отличается умный человек от мудрого?
Умный - выпутается из любой ситуации.
Мудрый - просто в неё не попадёт.
PM MAIL   Вверх
volvo877
Дата 3.12.2007, 12:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2072
Регистрация: 15.11.2004

Репутация: 13
Всего: 116



artsb, возможно это решается гораздо проще, но в свое время я реализовывал подобный поиск через так называемую "Levenshtein distance" - коэффициент "похожести" двух строк... Если похожесть очень высока, то строка считается  найденной, и поиск останавливается...
PM MAIL   Вверх
xvr
Дата 3.12.2007, 15:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 48
Всего: 223



Цитата(artsb @ 3.12.2007,  09:59)
Попробую объяснить ещё раз:
В ComboBox'е юзверь выбирает один из вариантов, а в Edit вводит текст. Допустим он выбрал первый, тогда поиск должен идти по name. Как только будет найдено совпадение, поиск останавливается, а мне нужно получить индекс текущего элемента вектора.
В принципе, всё это я смогу сделать, вопрос в следующем:
Как сделать поиск если в Edit может быть введено слово или сочетание слов и в name может быть слово, а может предложение?

Делишь name и Edit на набор слов (например функцией strtok или через TStringList), затем сохраняешь их в map<AnsiString,int>, добавляя в map 1 для name и 2 для Edit. Если получится элемент с 3 - искомое пересечение найдено.
Код

map<AnsiString,int> acc;
bool add_tokens(AnsiString str, int val)
{
 for(char* p=strtok(str.c_str()," ");p;p=strtok(NULL," "))
  {
    if ( (acc[p]|=val) == 3) return true;
  }
 return false;
}

int find_by_name()
{
 for( <all names> )
  {
   acc.clear();
   add_tokens(Edit1->Text,1);
   if (add_tokens(name,2)) return <current index>;
  }
 return <not found>; 
}

Но быстрее будет вариант с set<AnsiString> куда будут складываться слова из Edit (один раз) и затем проверяться на принадлежность этому множеству слова из name


Это сообщение отредактировал(а) xvr - 3.12.2007, 15:54
PM MAIL   Вверх
artsb
Дата 3.12.2007, 19:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2280
Регистрация: 17.7.2007
Где: центр Вселенной

Репутация: 39
Всего: 64



А если так?
Код

int find(int flag)
{
int n=0;
AnsiString str;
switch (flag)
{
     case 1: str=grp.name; break;
     case 2: str=grp.www; break;
     case 3: str=grp.inf; break;
}
                    for(char* p=strtok(str," ");p;p=strtok(NULL," "))
                    {
                            if ( p == Form1->Edit1->Text) return n;
                            else n++;
                    }
return -1;
}

Так будет работать? А то я не проверял.



--------------------
Чем отличается умный человек от мудрого?
Умный - выпутается из любой ситуации.
Мудрый - просто в неё не попадёт.
PM MAIL   Вверх
xvr
Дата 3.12.2007, 19:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 48
Всего: 223



Цитата(artsb @ 3.12.2007,  19:21)
А если так?
Код

int find(int flag)
{
int n=0;
AnsiString str;
switch (flag)
{
     case 1: str=grp.name; break;
     case 2: str=grp.www; break;
     case 3: str=grp.inf; break;
}
                    for(char* p=strtok(str," ");p;p=strtok(NULL," "))
                    {
                            if ( p == Form1->Edit1->Text) return n;
                            else n++;
                    }
return -1;
}

Так будет работать? А то я не проверял.

Будет, но данные в поле ввода (Edit1) будут рассматриваться как слово, а не как набор слов. Кроме того, если в этих данных будет хоть один пробел, то ничего найдено не будет (вообще)

PM MAIL   Вверх
artsb
Дата 3.12.2007, 21:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2280
Регистрация: 17.7.2007
Где: центр Вселенной

Репутация: 39
Всего: 64



xvr ты не мог бы отредактировать мой пример так, чтобы данные в Edit1  рассматривались как набор слов, если их там несколько.
Как можно из строки удалить определённый символ? Например, из "Мама мыла раму" удалить все 'м'.


--------------------
Чем отличается умный человек от мудрого?
Умный - выпутается из любой ситуации.
Мудрый - просто в неё не попадёт.
PM MAIL   Вверх
xvr
Дата 3.12.2007, 21:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 48
Всего: 223



Цитата(artsb @ 3.12.2007,  21:37)
xvr ты не мог бы отредактировать мой пример так, чтобы данные в Edit1  рассматривались как набор слов, если их там несколько.

Мог бы


Код

int find(int flag)
{
 int n=0;
 AnsiString str;
 switch (flag)
  {
     case 1: str=grp.name; break;
     case 2: str=grp.www; break;
     case 3: str=grp.inf; break;
  }

 set<AnsiString> active_set;
 for(char* p=strtok(Form1->Edit1->Text.c_str()," ");p;p=strtok(NULL," "))
  active_set.insert(p);

 for(char* p=strtok(str.c_str()," ");p;p=strtok(NULL," "))
   {
     if ( active_set.count(p)!=0 ) return n;
     else n++;
   }
 return -1;
}

Я правда не совсем понял зачем нужен был параметр flag, и зачем ты возвращал номер совпавшего слова (он кому то нужен)?

Цитата

Как можно из строки удалить определённый символ? Например, из "Мама мыла раму" удалить все 'м'.


Код

str=AnsiReplaceStr(str,"м","");


PM MAIL   Вверх
artsb
Дата 3.12.2007, 22:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2280
Регистрация: 17.7.2007
Где: центр Вселенной

Репутация: 39
Всего: 64



Спасибо. У меня пара вопросов:

Цитата(xvr @  3.12.2007,  21:48 Найти цитируемый пост)
 set<AnsiString> active_set;
 for(char* p=strtok(Form1->Edit1->Text.c_str()," ");p;p=strtok(NULL," "))
  active_set.insert(p);

set - это же множество, в котором каждый элемент уникален. Если вдруг юзверь введёт два одинаковых слова, не будет ошибки?


Цитата(xvr @  3.12.2007,  21:48 Найти цитируемый пост)
if ( active_set.count(p)!=0 )

Не пойму, что здесь происходит. Count - это ж вроде количество? И почему ты сравниваешь с нулём? Каков результат операции?



Цитата(xvr @  3.12.2007,  21:48 Найти цитируемый пост)
Я правда не совсем понял зачем нужен был параметр flag, и зачем ты возвращал номер совпавшего слова (он кому то нужен)?

Параметр flag нужен, чтобы передать в функцию какой вариант выбрал юзверь (в ComboBox'е три строки, если выбрана первая, то flag=1).
Возвращаемое значение нужно для установки индекса в ListBox, что бы сделать строку с этим индексом активной.

За ответ на второй вопрос спасибо. Я так поня, что там 'м' меняется на ''.


--------------------
Чем отличается умный человек от мудрого?
Умный - выпутается из любой ситуации.
Мудрый - просто в неё не попадёт.
PM MAIL   Вверх
xvr
Дата 4.12.2007, 15:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 48
Всего: 223



Цитата(artsb @ 3.12.2007,  22:52)
Спасибо. У меня пара вопросов:

Цитата(xvr @  3.12.2007,  21:48 Найти цитируемый пост)
 set<AnsiString> active_set;
 for(char* p=strtok(Form1->Edit1->Text.c_str()," ");p;p=strtok(NULL," "))
  active_set.insert(p);

set - это же множество, в котором каждый элемент уникален. Если вдруг юзверь введёт два одинаковых слова, не будет ошибки?


Не будет.

Цитата

Цитата(xvr @  3.12.2007,  21:48 Найти цитируемый пост)
if ( active_set.count(p)!=0 )

Не пойму, что здесь происходит. Count - это ж вроде количество? И почему ты сравниваешь с нулём? Каков результат операции?

count возвращает количество элементов, заданных параметром, в set. Оно может быть 0 - set не содержит этого элемента, или 1 - set содержит данный элемент

Цитата

Возвращаемое значение нужно для установки индекса в ListBox, что бы сделать строку с этим индексом активной.

Возвращается номер слова в фразе, а не номер элемента в ListBox'е (он там вообще не фигурирует)

PM MAIL   Вверх
artsb
Дата 4.12.2007, 20:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2280
Регистрация: 17.7.2007
Где: центр Вселенной

Репутация: 39
Всего: 64



Всё понятно спасибо. Надо будет потом чуть-чуть доделать, ведь у меня поиск в векторе, а не в одной строке.



--------------------
Чем отличается умный человек от мудрого?
Умный - выпутается из любой ситуации.
Мудрый - просто в неё не попадёт.
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++ Builder"
Rrader

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по С++ Builder обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Настоятельно рекомендуем заглянуть в DRKB (Delphi Russian Knowledge Base) - крупнейший в рунете сборник материалов по Дельфи


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Rrader.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C++ Builder | Следующая тема »


 




[ Время генерации скрипта: 0.1516 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.