如何在字符串中检测“ [” +数字+“]”并找到最高的数字

时间:2019-08-08 03:35:59

标签: c++

我正在尝试检测字符串中方括号中找到的最高数字。

例如

std::string str = "a[1]b[7]cde[8]fg[3]h[5]";
int highest = findHighestDigit(str);
std::cout << highest << '\n';

在这种情况下,我希望结果为8

我现在能想到的就是在for循环中手动从[0][9]进行检查。

会有更好的解决方案吗?

2 个答案:

答案 0 :(得分:3)

可以使用std::basic_string函数.find().substr()stoi()来制作更多的C ++解决方案(优雅在某种程度上是任意的)。只需循环使用.find()来定位每次出现的"[",然后使用.substr()来检索"["之后的字符并传递到stoi(),以尝试转换为{ {1}}。可以在std::basic_string上找到每个参考。

例如:

int

注意:,您应该将int findHighestDigit (const std::string& str) { int max = std::numeric_limits<int>::min(); /* set max to lowest value */ size_t n = 0; /* initialize index zero */ while ((n = str.find ("[", n)) != std::string::npos) { /* if "[" found */ int val = std::stoi (str.substr (++n)); /* get following int */ if (val > max) /* check if int > max, update max accordingly */ max = val; } return max; /* return max */ } 调用和stoi()的检查包装在val > max异常处理程序中,以处理{{1} }后面没有可选的空格和数字-这留给您)

在简短的示例中使用您的字符串将其组合在一起,您可以这样做:

try {...} catch {...}

使用/输出示例

"["

答案 1 :(得分:2)

David C. Rankin的答案已经是“更多,更好”的C ++解决方案。

我想添加“ Full blown” -Algorithm plus Regex” C ++解决方案;-)

这可能会浪费时间和内存,但这是一个非常优雅的C ++解决方案。

所有人都愿意使用std::sregex_token_iterator。正是针对给定的目的进行了此迭代器。匹配一些模式,给我结果,然后选择max元素。

我们定义了一个正则表达式,它将匹配方括号中的数字。类似于“ [\ d]”。由于我们想用std::sregex_token_iterator返回某物,因此我们在数字周围建立了一个组:“ [(\ d)]”。

好,现在我们可以遍历字符串中的所有数字。而且由于我们现在可以执行此操作,因此可以使用标准算法std::max_element来找到最大值。

要在屏幕上显示此内容,我们还可以使用算法:std::copystd::ostream_itarator组合。

所有这些加起来

std::copy_n(std::max_element(std::sregex_token_iterator(str.begin(), str.end(), re, 1), std::sregex_token_iterator()), 1, std::ostream_iterator<std::string>(std::cout, "\n"));

由于将所有内容都塞进一行并不是很好,所以我将在此处按Enter并添加许多注释:

    std::copy_n(                         // We wan to copy one value from a range to std::cout
        std::max_element(                // Find the max element in a range
            std::sregex_token_iterator(  // The range starts with the begin of the list of tokens
                str.begin(),             // Start reading tokens from begin of str
                str.end(),               // Read all tokens up to the end of the string
                re,                      // This is the token that we are looking for. A digit in brackets
                1),                      // We want to get the matched result
            std::sregex_token_iterator() // Find all tokens up until lats
        ),
        1,                               // Even, if there are more than one max value (equal values possible), return only 1
        std::ostream_iterator<std::string>(std::cout, "\n") // Print on screen
    );

现在,我们在各处使用算法来发表声明。

再次明确一点,它基本上没有任何价值,而且是硬性的。但这是“成熟的” C ++;-)

请在下面查看完全可执行的代码(MSVS 19,C ++ 17):

#include <string>
#include <iostream>
#include <regex>
#include <algorithm>
#include <iterator>

// Regex for one digit in brackets
const std::regex re(R"(\[(\d)\])");

int main()
{
    // The source string to evaluate
    std::string str = "a[1]b[7]cde[8]fg[3]h[5]";

    // Step 1: Find all digits in bracket and output them
    std::cout << "\nStep 1:  Iterate over all digits and display them\n";
    for (std::sregex_token_iterator sti(str.begin(), str.end(), re, 1); sti != std::sregex_token_iterator(); ++sti)
        std::cout << *sti << "\n";

    // Step 2:  Use an algorithm an COPY to ststd::cout
    std::cout << "\n\nStep 2:  We can also iterate over the values and copy them to std::cout\n";
    std::copy(
        std::sregex_token_iterator(str.begin(), str.end(), re, 1),
        std::sregex_token_iterator(),
        std::ostream_iterator<std::string>(std::cout, "\n")
    );

    // Step 3: Iteration clear now. Use max_element to find max in range of digits
    std::cout << "\n\nStep 3:  We know how to iterate. Find max_element\n"
        << *std::max_element(std::sregex_token_iterator(str.begin(), str.end(), re, 1), std::sregex_token_iterator());

    // Step 4: All in one solution
    std::cout << "\n\nStep 4:  All in one\n";
    std::copy_n(std::max_element(std::sregex_token_iterator(str.begin(), str.end(), re, 1), std::sregex_token_iterator()), 1, std::ostream_iterator<std::string>(std::cout, "\n"));

    // Step 5: All in one solution. More readable version with comments
    std::cout << "\n\nStep 5:  All in one and mare readable\n";
    std::copy_n(                         // We wan to copy one value from a range to std::cout
        std::max_element(                // Find the max element in a range
            std::sregex_token_iterator(  // The range starts with the begin of the list of tokens
                str.begin(),             // Start reading tokens from begin of str
                str.end(),               // Read all tokens up to the end of the string
                re,                      // This is the token that we are looking for. A digit in brackets
                1),                      // We want to get the matched result
            std::sregex_token_iterator() // Find all tokens up until lats
        ),
        1,                               // Even, if there are more than one max value (equal values possible), return only 1
        std::ostream_iterator<std::string>(std::cout, "\n") // Print on screen
    );

    return 0;
}