Проверьте, содержит ли строка диапазон чисел - PullRequest
4 голосов
/ 22 июня 2010

Я бы хотел проверить std::string на наличие чисел любого диапазона, например, 5 to 35 в std::string s = "XDGHYH20YFYFFY", была бы функция, или мне пришлось бы преобразовать число в строку, а затем использовать цикл для поиска каждого один

Ответы [ 4 ]

9 голосов
/ 22 июня 2010

Я бы, вероятно, использовал локаль, которая рассматривает все, кроме цифр, как пробел, и читал бы числа из потока строк, пропитанных этим языком, и проверял бы, находятся ли они в диапазоне:

#include <iostream>
#include <algorithm>
#include <locale>
#include <vector>
#include <sstream>

struct digits_only: std::ctype<char> 
{
    digits_only(): std::ctype<char>(get_table()) {}

    static std::ctype_base::mask const* get_table()
    {
        static std::vector<std::ctype_base::mask> 
            rc(std::ctype<char>::table_size,std::ctype_base::space);

        std::fill(&rc['0'], &rc['9'], std::ctype_base::digit);
        return &rc[0];
    }
};

bool in_range(int lower, int upper, std::string const &input) { 
    std::istringstream buffer(input);
    buffer.imbue(std::locale(std::locale(), new digits_only()));

    int n;

    while (buffer>>n)
        if (n < lower || upper < n)
            return false;
    return true;
}

int main() {
    std::cout << std::boolalpha << in_range(5, 35, "XDGHYH20YFYFFY");
    return 0;
}
2 голосов
/ 22 июня 2010

Столько, сколько некоторые люди собираются немедленно перейти к регулярному выражению по этому вопросу, я думаю, что ваша лучшая ставка на самом деле является гибридным решением. Используйте REGEX, чтобы найти числа, затем проанализируйте их и посмотрите, находятся ли они в диапазоне.

Примерно так в C #. Не уверен, какие библиотеки регулярных выражений доступны вам в C ++.

using System.Text.RegularExpressions.Regex;
using System.Text.RegularExpressions.Match;
using System.Text.RegularExpressions.MatchCollection;

private static const Regex NUMBER_REGEX = new Regex(@"\d+")

public static bool ContainsNumberInRange(string str, int min, int max)
{
    MatchCollection matches = NUMBER_REGEX.Matches(str);
    foreach(Match match in matches)
    {
        int value = Convert.ToInt32(match.Value);
        if (value >= min && value <= max)
            return true;
    }

    return false;
}
0 голосов
/ 22 июня 2010

Вы можете сделать это итеративно с объектом stringstream.

#include <iostream>
#include <string>
#include <sstream>
#include <cctype>

void check (std::string& s) {
    std::stringstream ss(s);

    std::cout << "Searching string: " << s << std::endl;
    while (ss) {

        while (ss && !isdigit(ss.peek ()))
            ss.get ();

        if (! ss)
            break;

        int i = 0;
        ss >> i;
        std::cout << "  Extraced value: " << i << std::endl;

    }
}


int main () {

    std::string s1 = "XDGHYH20YFYFFY";
    std::string s2 = "20YF35YFFY100";
    check (s1);
    check (s2);
    return 0;
}

Выход:

Searching string: XDGHYH20YFYFFY
  Extraced value: 20
Searching string: 20YF35YFFY100
  Extraced value: 20
  Extraced value: 35
  Extraced value: 100

Добавление параметров в функцию check для ограничения принятых результатов будеттривиальный.

0 голосов
/ 22 июня 2010

Если вы ищете все числа в диапазоне, тогда используйте функцию string :: find в цикле.Вот ссылка на функцию:

http://www.cplusplus.com/reference/string/string/find/

Также вы хотите использовать числа в строке только один раз?Например, SDFSD256fdsfs выдаст вам номера 2 5 6 25 56 256, если вы не удаляете их из строки после каждого совпадения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...