我正在尝试检测字符串中方括号中找到的最高数字。
例如
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]
进行检查。
会有更好的解决方案吗?
答案 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::copy
与std::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;
}