2014 dxdy logo

Научный форум dxdy

Математика, Физика, Computer Science, Machine Learning, LaTeX, Механика и Техника, Химия,
Биология и Медицина, Экономика и Финансовая Математика, Гуманитарные науки




Начать новую тему Ответить на тему
 
 Сравнение по маске [C++]
Сообщение13.01.2014, 20:12 


20/10/12
235
Добрый вечер, уважаемые посетители форума!
Прошу у вас помощи в реализации функции, проверяющей слово по маске.
Маска дана в формате следующего типа a*b, то есть какая-то подстрока a , затем любая последовательность символов, затем подстрока b. Нам нужно проверить слово на соответствие маске.
Как реализовать эту функцию наиболее просто?
Просто все те идеи, которые я начал реализовывать - они очень долгие. Что-то вроде:
код: [ скачать ] [ спрятать ]
Используется синтаксис C++
int checkmask(char *word, char *mask)
{
  char *cp = mask;
  int flag = 0;
  while(TRUE)
  {
    if(*mask == '*')
    {
    while(*mask++!='*');
    while(*word)
      if(!strncmp(word, cp , mask - cp))
      {
        flag = 1;
        break;
      }
     if(!flag)
         return FALSE;
     }
  .....// продолжение в том же стиле
  }
}
 

 Профиль  
                  
 
 Re: Сравнение по маске
Сообщение13.01.2014, 21:16 
Заслуженный участник


27/04/09
28128
shukshin в сообщении #813918 писал(а):
Как реализовать эту функцию наиболее просто?
Используя существующие реализации регулярных выражений. В качестве регулярного выражения ваша маска переведётся как a.*b. Правда, придётся поэкранировать некоторые символы.

Или используя проверку, соответствует ли a началу строки и b концу. При этом, если заранее известно, что никакой конец a не может быть началом b, этим всё и кончится, а иначе надо будет проверить, не пересекаются ли вхождения (разумеется, не ходя по символам. Всё нужное можно собрать к этому моменту в виде чисел).

А, ну, во втором случае вам придётся сначала быстренько распарсить маску, хотя бы определив положение b в ней и длину a.

 Профиль  
                  
 
 Re: Сравнение по маске
Сообщение13.01.2014, 21:17 
Заслуженный участник


09/09/10
3729
Если вы можете гарантировать, что в строке mask всегда будет ровно одна звездочка, то все делается очень просто:

Используется синтаксис C++
bool checkmask(const char* word, const char* mask)
{
    const char *star = strchr(word, '*');
    assert(star);
    if (strncmp(word, mask, star - mask)) { return false; }

    size_t wlen = strlen(word + (star - mask)), blen = strlen(star + 1);
    if (wlen < blen) { return false; }

    return (!strcmp(word + wlen - blen, star + 1));
}

 Профиль  
                  
 
 Re: Сравнение по маске
Сообщение13.01.2014, 22:47 


05/09/12
2587
По традиции рекомендую простейший способ, описанный arseniiv под номером два, безо всяких библиотечных функций. Независимо от формата строки (сишная или паскальная, т.к. вы не указали явно язык, хотя пример кода на С++) сначала определить ее длину и конец и после проверок вхождений проверить отсутствие перехлеста. Имхо, гораздо проще остальных вариантов и не требует никаких гарантий от входящих данных.

 Профиль  
                  
 
 Re: Сравнение по маске
Сообщение14.01.2014, 00:28 
Заслуженный участник


09/09/10
3729

(Оффтоп)

_Ivana в сообщении #814026 писал(а):
не требует никаких гарантий от входящих данных.

Я имел в виду случай, когда mask равно aaa*bbb*ccc или aaa* или *bbb или aaabbb — что тут делать?

 Профиль  
                  
 
 Re: Сравнение по маске
Сообщение14.01.2014, 00:37 


05/09/12
2587
Joker_vD я сразу воспринимаю маску как пару подстрок (начала и конца), любая (или обе) из которых может быть пустой. Как запарсивать/распарсивать эти 2 подстроки в одну со звездочкой имхо в данной задаче непринципиально. На ваших примерах первый случай - более широкая задача, не рассматриваем, второй и третий - подстрока конца/начала пустая, четвертый - можно рассмотреть на полное равенство, но опять же, это за рамками поставленной задачи.

 Профиль  
                  
 
 Re: Сравнение по маске
Сообщение14.01.2014, 00:51 
Заслуженный участник


09/09/10
3729
_Ivana
Ну я тоже так подумал, что маска — это essentially две строки, но в исходном-то посте маска передается одной строчкой. А поскольку человек явно учится программировать, то необходимо вкладывать в голову представление о необходимости как-то справляться с некорректными данными.

 Профиль  
                  
 
 Re: Сравнение по маске
Сообщение14.01.2014, 03:15 
Заслуженный участник


16/02/13
4214
Владивосток
В принципе, идеи вполне правильные, только фрагмент, вами приведённый, явно нерабочий. Сильно быстрее не получится.

 Профиль  
                  
 
 Re: Сравнение по маске
Сообщение14.01.2014, 15:55 
Заслуженный участник


27/04/09
28128
_Ivana в сообщении #814026 писал(а):
безо всяких библиотечных функций
С библиотечными будет короче и яснее. Вот, например, Python 3 (надеюсь, ничего не упустил; может быть и не быть совместимым с 2):
Используется синтаксис Python
def satisfies_mask(s, mask):
    elems = mask.split('*')
    assert len(elems) == 2, 'mask должна содержать ровно один символ "*"'
    if len(s) < len(mask) - 1:
        return False
    return s.startswith(elems[0]) and s.endswith(elems[1])

Даже если их нет, startswith и endswith должны писаться в пару строк — и как просто с ними выглядит код.

 Профиль  
                  
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 9 ] 

Модераторы: Karan, Toucan, PAV, maxal, Супермодераторы



Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group