2014 dxdy logo

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

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




 
 Сравнение по маске [C++]
Сообщение13.01.2014, 20:12 
Добрый вечер, уважаемые посетители форума!
Прошу у вас помощи в реализации функции, проверяющей слово по маске.
Маска дана в формате следующего типа 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 
shukshin в сообщении #813918 писал(а):
Как реализовать эту функцию наиболее просто?
Используя существующие реализации регулярных выражений. В качестве регулярного выражения ваша маска переведётся как a.*b. Правда, придётся поэкранировать некоторые символы.

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

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

 
 
 
 Re: Сравнение по маске
Сообщение13.01.2014, 21:17 
Если вы можете гарантировать, что в строке 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 
По традиции рекомендую простейший способ, описанный arseniiv под номером два, безо всяких библиотечных функций. Независимо от формата строки (сишная или паскальная, т.к. вы не указали явно язык, хотя пример кода на С++) сначала определить ее длину и конец и после проверок вхождений проверить отсутствие перехлеста. Имхо, гораздо проще остальных вариантов и не требует никаких гарантий от входящих данных.

 
 
 
 Re: Сравнение по маске
Сообщение14.01.2014, 00:28 

(Оффтоп)

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

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

 
 
 
 Re: Сравнение по маске
Сообщение14.01.2014, 00:37 
Joker_vD я сразу воспринимаю маску как пару подстрок (начала и конца), любая (или обе) из которых может быть пустой. Как запарсивать/распарсивать эти 2 подстроки в одну со звездочкой имхо в данной задаче непринципиально. На ваших примерах первый случай - более широкая задача, не рассматриваем, второй и третий - подстрока конца/начала пустая, четвертый - можно рассмотреть на полное равенство, но опять же, это за рамками поставленной задачи.

 
 
 
 Re: Сравнение по маске
Сообщение14.01.2014, 00:51 
_Ivana
Ну я тоже так подумал, что маска — это essentially две строки, но в исходном-то посте маска передается одной строчкой. А поскольку человек явно учится программировать, то необходимо вкладывать в голову представление о необходимости как-то справляться с некорректными данными.

 
 
 
 Re: Сравнение по маске
Сообщение14.01.2014, 03:15 
В принципе, идеи вполне правильные, только фрагмент, вами приведённый, явно нерабочий. Сильно быстрее не получится.

 
 
 
 Re: Сравнение по маске
Сообщение14.01.2014, 15:55 
_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 ] 


Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group