определение, содержит ли данное предложение заданное слово или нет c ++

0

Мне нужно определить, находится ли данное слово в другой строке или нет в c++.

мой прототип функции будет похож на bool check(string sentence, string word);

и "предложение" может быть похоже: word.someWord AND/OR/XOR word2.someWord *AND/OR/XOR* word3.someWord и идет так.

Для реального примера: unlock_the_door.value = 1 AND turn_of_car.checkSum = 1

Теперь, В этом примере Если я назначаю слово для блокировки, моя функция проверки должна быть возвращена false, но если я дам ей "разблокировать", она должна вернуть значение true.

Для этого я использовал функцию.find(), но, как вы все знаете, это было неправильно, потому что вернуло меня к истине, даже если я дам блокировку в качестве параметра слова, так как "разблокировка" содержит "блокировку",

Думаю, мне нужно использовать регулярное выражение, но я не знаю, как это сделать. Кто-нибудь может мне помочь? Заранее спасибо.

  • 0
    Могу я спросить, в чем причина -1?
  • 1
    Вы не выдвигаете попытку решения и не задаете вопрос; Вы предлагаете решение и просите SO реализовать его для себя (по крайней мере, для меня это так). Прежде чем вы сможете использовать реализацию на основе регулярных выражений, вы должны понять хотя бы некоторый синтаксис регулярных выражений; в противном случае любые решения, которые вы получите, вероятно, будут для вас непригодны (или применимы, но очень хрупки). В любом случае, вы спрашиваете об API регулярных выражений C ++, фактическом синтаксисе регулярных выражений или о чем-то еще?
Показать ещё 3 комментария
Теги:
string
substring

5 ответов

0
Лучший ответ

Вы можете использовать С++ 11 regex_search используя в качестве шаблона поиска свое слово, окруженное границей слов (\b) или подчеркиванием.

#include <iostream>
#include <string>

using namespace std;

bool check(const string &sentence, const string &word) {
    string boundary = "(_|\\b)";
    return regex_search(sentence, regex(boundary + word + boundary));
}

int main () {
    string sentence = "unlock_the_door.value=1 AND turn_of_car.checkSum=1";
    cout << check(sentence, "lock") << endl;
    cout << check(sentence, "unlock") << endl;
}

Если вы не хотите использовать С++ 11 или используете компилятор, который не поддерживает регулярное выражение С++ 11 (например, версии gcc до 4.9.0), вы можете использовать библиотеку Boost. Вам просто нужно загрузить библиотеку и добавить эти две строки в свой источник:

#include <boost/regex.hpp>
using namespace boost;

Также не забудьте передать опцию -lboost_regex в gcc.

1

Я имею в виду, что подчеркивания - это пробелы.

#include <iostream>
#include <iomanip>
#include <string>
#include <sstream>
#include <iterator>
#include <algorithm>


bool check( const std::string &sentence, const std::string &word )
{
   std::istringstream is( sentence );

   return std::find( std::istream_iterator<std::string>( is ),
                     std::istream_iterator<std::string>(),
                     word ) != std::istream_iterator<std::string>();
}

int main()
{
    std::cout << std::boolalpha
              << check( "unlock the door.value=1 AND turn of car.checkSum=1", "lock" )
              << std::endl;

    std::cout << std::boolalpha
              << check( "unlock the door.value=1 AND turn of car.checkSum=1", "unlock" )
              << std::endl;

    return 0;
}

Выход

false
true

Если подчеркивания не являются пробелами, вы можете использовать ту же std::istringstream и стандартную функцию std::getline и проверить каждую прочитанную строку, равна ли она данной строке.

Или вы действительно можете разбить предложение на объект типа std::vector<std::string> используя функцию-член find_first_of

Например

#include <iostream>
#include <iomanip>
#include <string>


bool check( const std::string &sentence, const std::string &word )
{
    const char *delimiters = " _=.";
    std::string::size_type first, last;
    bool found = false;

    first = 0;
    while ( !found && first != std::string::npos )
    {
        first = sentence.find_first_not_of( delimiters, first );

        if ( first != std::string::npos )
        {
            last = sentence.find_first_of( delimiters, first );
            found = sentence.substr( first, last == std::string::npos ? last : last - first ) == word;
            first = last;
        }
    }

    return found;
}

int main()
{
    std::string s = "unlock_the_door.value=1 AND turn_of_car.checkSum=1";

    std::cout << std::boolalpha
              << check( s, "lock" )
              << std::endl;

    std::cout << std::boolalpha
              << check( s, "unlock" )
              << std::endl;

    return 0;
}

Выход

false
true
  • 0
    @Vlad_from_Moscow подчеркивания - это не пустые места, это часть слова. Однако я не мог бы предложить вам это, не могли бы вы отредактировать его в соответствии с этим?
  • 0
    @eday Смотрите мой обновленный пост.
1

Сначала разделите предложение на слова, затем проверьте список, чтобы узнать, содержит ли оно точные слова (слова), которые вы ищете.

Вы также можете рассмотреть использование регулярных выражений и поиск слова (ов), каждый из которых предшествует любому запуску или пробелу в строке, а затем пробел, пунктуацию или конец строки.

  • 0
    @Steve_Barnes, спасибо за ответ. Если я разделю свое предложение на слова, для приведенного выше примера это будет похоже на word1 = unlock_tw_door.value = 1 word2 = И word3 = turn_of_car.checkSum = 1 и снова найдем, что funciton вернет true для слова блокировки так как word1 содержит его.
  • 1
    А ожидал, что вы сопоставите слова в списке, а не используйте поиск по слову в списке. "разблокировать"! = "заблокировать"
0

Если я правильно понял, вы хотите узнать, содержится ли в предложении не только слово, но и слова в этом предложении. Вы можете сделать это следующим образом:

bool check (std::string sentence, std::string word)
{
    std::string part;
    for(unsigned int ii=0; ii<sentence.size()-word.size(); ii++)
    {
        part = sentence.substr(ii,word.size());
        if(!part.compare(word)) {
            return true;
        }
    }
    return false;
}

Это проверяет каждую часть предложения, длина слова word.size(), если она равна слову. Если оно равно, это вернет true, иначе false.

Хорошо, что я написал раньше, возможно, именно то, чего вы не хотите. Если вы хотите сравнить только слова в предложении (что для вас слово, вам нужно подумать о разделителях), тогда вы можете сделать это так (вам нужно включить string.h):

bool check (std::string sentence, std::string word)
{
char *c_str_sentence = new char[sentence.size()+1]; //you need this cause string.c_str() will return const char* but strtok needs char*;
char *c_str_word = new char[word.size()+1];

strcpy(c_str_sentence,sentence.c_str());
strcpy(c_str_word,word.c_str());

bool is_contained = false;

const char *delimiters = " _=.";    //any delimiter you wish;

char *part = strtok(c_str_sentence,delimiters);
while (part != NULL)
{
    if(!strcmp(part,c_str_word)) {
        is_contained = true;
        break;
    }
    part = strtok(NULL,delimiters);
}

delete[] c_str_sentence;
delete[] c_str_word;

return is_contained;
}

Возвращает только true, если вы проверяете "разблокировать" не для "блокировки". Однако, указав разделители, вы можете указать, к чему вы хотите относиться как к слову, а что нет.

  • 1
    Ваша вторая функция будет пропускать память при каждом вызове. Он выделяет память с помощью new[] и никогда не освобождает ее с помощью delete[] .
  • 0
    Спасибо, я это исправил.
0

Разделите предложение под знаком подчеркивания как разделитель. И используйте функцию stricmp. Наверное, это должно решить.

  • 0
    Я полагаю, вы не понимаете мой вопрос, поэтому, пожалуйста, не нажимайте

Ещё вопросы

Сообщество Overcoder
Наверх
Меню