2015-05-04 2 views
0

Я хочу проверить, является ли строка строго подмножеством другой строки. Для этого я использовал boost::contains и я сравниваю размер строки следующим образом:Как проверить, является ли строка подходящим подмножеством другой строки

#include <boost/algorithm/string.hpp> 
#include <iostream> 

using namespace std; 
using namespace boost::algorithm; 

int main() 
{ 
    string str1 = "abc news"; 
    string str2 = "abc"; 
    //strim strings using boost 
    trim(str1); 
    trim(str2); 
    //if str2 is a subset of str1 and its size is less than the size of str1 then it is strictly contained in str1 
    if(contains(str1,str2) && (str2.size() < str1.size())) 
    { 
    cout <<"contains" << end; 
    } 
    return 0; 
} 

Есть ли лучший способ решить эту проблему? Вместо того, чтобы сравнивать размер строк?


Пример

  • АВС является подмножеством ABC News
  • ABC не является собственным подмножеством АВС

+1

Почему бы не просто использовать 'зЬй :: строка :: find'? – Lingxi

+0

похоже ли это на подходящее подмножество? –

+3

Я бы отменил тесты (т. Е. Проверил размер * перед * вызовом 'contains()'), кроме этого, я не думаю, что вы можете сделать это лучше. – Nim

ответ

3

Вы можете просто использовать == или != для сравнения строк:

if(contains(str1, str2) && (str1 != str2)) 
    ... 

Если строка содержит строку, и оба не равны, то есть реальное подмножество.

Если это лучше, чем ваш метод, вы должны решить. Он менее типизирован и очень ясен (IMO), но, вероятно, немного медленнее, если обе строки длинны и равны или оба начинаются с той же длинной последовательности.

Примечание: Если вам действительно нужна производительность, вы можете попробовать поиск Boyer-Moore и поиск Boyer-Moore-Horspool. Они быстрее, чем любой тривиальный строковый поиск (как, очевидно, используется в строчном поиске в stdlibC++, см. here), я не знаю, использует ли их boost::contains.

+1

Сравнение длины было бы более эффективным. – tenfour

+0

@tenfour Действительно. Скорее всего, это не важно для строк, таких как «ABC News». –

+1

Но вы не можете знать, какая строка будет. Это могут быть произведения Шекспира! :) – Galik

1

О деятельности Comparaison

TL; DR: Убедитесь, что о формате, что вы сравниваете.

Будьте осторожны с тем, как вы определяете строго.

Например, вы не указали thoses вопрос ваш вопрос, но если я представить, скажем:

"ABC  " //IE whitespaces 
"ABC\n" 

Что вы думаете об этом? Вы принимаете это или нет?Если вы этого не сделаете, вам придется либо trim или очистить свой выход, прежде чем сравнивать - только общую записку о comparaison операций -

Во всяком случае, так как Baum pointed out, вы можете проверить равенство ваших строк с помощью == или вы может сравнить длину (которая более эффективна, если вы впервые проверили подстроку) либо size(), либо length();

+0

да, это очень важно mekap. Я должен был упомянуть об этом. Я фактически обрезал строки до того, как я сравню –

+0

@HaniGoc Да, я написал этот ответ больше для людей, которые нажимают на эту страницу, чтобы быть осторожным, какие операции нужно делать перед фактическим сравнением. – Mekap

4

Я хотел бы использовать следующее:

bool is_substr_of(const std::string& sub, const std::string& s) { 
    return sub.size() < s.size() && s.find(sub) != s.npos; 
} 

Это использует стандартную библиотеку только и делает проверку размера первого, который дешевле, чем s.find(sub) != s.npos.

+1

Я не получаю нисходящее - это правильно .. – Nim

+0

Не знаю, что такое downvote. Этот ответ использует только стандартную библиотеку и не тратит время на сравнение строк. – Galik

0

другой подход, используя только стандартную библиотеку:

#include <algorithm> 
#include <string> 
#include <iostream> 

using namespace std; 

int main() 
{ 
    string str1 = "abc news"; 
    string str2 = "abc"; 
    if (str2 != str1 
    && search(begin(str1), end(str1), 
       begin(str2), end(str2)) != end(str1)) 
    { 
    cout <<"contains" << endl; 
    } 
    return 0; 
} 
+1

'std :: string :: find' кажется более аккуратным. – Lingxi

+0

Это еще один способ, вы правы. Преимущество std :: search заключается в том, что искомая строка может представлять собой любую последовательность, ограниченную двумя итераторами. –

Смежные вопросы