如何在if条件语句中搜索char数组中的char
Posted
技术标签:
【中文标题】如何在if条件语句中搜索char数组中的char【英文标题】:How to search a char in a char array in if condition statement 【发布时间】:2017-10-30 21:28:45 【问题描述】:是否有任何功能可以帮助我更轻松地完成以下操作?
char ch = '+';
if (( ch == '+') || (ch == '-') || (ch == '*'))
//do something
由于必须在我的代码中多次检查这一点,我希望有类似的方法
char arr ='+','-','*';
if (ch in arr)
//do something
【问题讨论】:
是什么让你觉得现有的代码不“高效”?您能否向我们展示您的基准测试表明它是您的代码中的一个瓶颈,以及您的研究表明它可以改进吗? 现在,如果你想要这样让你的代码更易于维护和表达,那是完全合理的:) 您可以使用std::find
或 std::any_of
之类的东西,但正如 @BoundaryImposition 所说,如果这会比您的第一个版本在性能上获胜,我会感到惊讶。
std::any_of
? std::count_if
? std::find
?
@BoundaryImposition 有问题的不是运行时间,而是打字时间。在实际代码中,我必须在七个字符之间进行检查,并执行三次。正如你所说,我只是想知道是否有某种方法可以使代码更易于维护和编写:)
【参考方案1】:
对于这种特定情况,您可以将布尔表达式包装在您自己的自定义函数中:
bool isOperator(char ch)
return ( ch == '+') || (ch == '-') || (ch == '*');
这将减少其余代码中的冗余,因为现在您可以这样做了
if(isOperator(ch))
【讨论】:
【参考方案2】:试试这个
#include <algorithm>
int main()
char arr[] ='+','-','*';
char ch = '-';
if(std::find(arr, arr+sizeof(arr)/sizeof(char), ch) - arr < sizeof(arr)/sizeof(char))
//do anything
return 0;
【讨论】:
硬编码的3
可以改进,你不觉得吗?
我已经编辑了我的答案,可以吗?谢谢你告诉我。
我会考虑使用std::array
,这样你就可以简单地使用.size()
而不是sizeof技巧。
当然你是对的,但我试图回答这个特定的问题,我试图使用 char arr[] 就像问题一样。我是对的还是什么?我想在这里有用。谢谢:D【参考方案3】:
对我来说,乍一看,这是一个集合查找:这个元素中的任何一个等价于这组元素是否包含这个元素。因此:
if ((std::set<char> 'a','b','c').count(x) > 0)
// ...
See it on Coliru
【讨论】:
【参考方案4】:如果您的数组也是,这会使any
成为编译时构造。如果范围是任意的,我真的想不出一种更优化的方法。
我选择重载==
,因为它看起来比并排传递参数更好。
#include<iterator>
template<typename Iter>
class any
public:
using value_type = typename std::iterator_traits<Iter>::value_type;
constexpr any(Iter begin, Iter end) : beginbegin, endend
template<typename T, size_t N>
constexpr any(T (&arr)[N]) : anyarr, arr + N
constexpr bool operator==(const value_type& v)
return compare(v, begin);
private:
Iter begin, end;
constexpr bool compare(const value_type& v, Iter it)
return it != end && (v == *it || compare(v, it + 1));
;
template<typename T, size_t N>
any(T (&)[N]) -> any<T*>;
template<typename T, typename Iter>
constexpr bool operator==(const T& t, any<Iter> a)
return a == t;
这会产生一个漂亮的格式
static_assert('+' == any("+-*"), "Failure!");
constexpr char ops[] = '+', '-', '*';
char c = '/';
if(c == any(ops))
do_stuff(c);
说明
using value_type = typename std::iterator_traits<Iter>::value_type;
是将类型Iter
取消引用的别名为value_type
。
template<typename T, size_t N>
any(T (&)[N]) -> any<T*>;
是deduct the type 的any
,没有明确的模板参数。
return it != end && (v == *it || compare(v, it + 1));
是递归检查范围是否已经耗尽,如果没有,则检查值是否等于当前元素。
请注意,any("+-*")
中有 4 个字符,最后一个是 '\0'
。
【讨论】:
【参考方案5】:你可以写一个函数来生成等价于
的代码if (( ch == '+') || (ch == '-') || (ch == '*'))
具有更好的用户语法。
template <typename X>
bool any(const X&) noexcept
return false;
template <typename X, typename T, typename... Ts>
bool any(const X& x, const T& curr, const Ts&... rest) noexcept
return x == curr || any(x, rest...);
用法:
if(any(ch, '+', '-', '*')) /* do something */
如by this godbolt.org comparison 所示,这是一个零成本抽象的示例。
在 C++17 中,您可以使用 fold expression:
template <typename X, typename... Ts>
bool any(const X& x, const Ts&... rest)
return ((x == rest) || ...);
如果您想多次重复使用相同的比较值而不重复自己,您可以创建 any
的“curried”版本,它首先绑定要检查的参数,然后在后续调用中进行比较。
template <typename... Ts>
auto bound_any(const Ts&... xs)
return [xs...](const auto& x)
return ((x == xs) || ...);
;
用法:
auto is_op = bound_any('+', '-', '*');
if(is_op(ch)) /* do something */
这里是a godbolt.org comparison。
【讨论】:
你的函数的名字不是很好,而且你也不允许在代码的多个部分中不重复自己这样做(这似乎是OP所关心的)跨度> 现在更好,但最终过度设计。 :) @BoundaryImposition:为什么说这是过度设计? 用一个复杂的函数替换三个==
和两个||
环境(甚至还不是标准),是过度设计的。举个例子:上面的 OP 完全不知道你的建议是如何工作的。这很聪明,但不实用。
我也认为这主要是过度设计,但有两件事可以挽救它:(1)原版“设计不足”(重复,容易出错)和(2)c ++ 17是可读和简洁的。因此,我认为答案只是信息丰富且富有洞察力。谢谢。【参考方案6】:
在这种情况下,您可以使用:
if ( std::strchr("+-*", ch) )
strchr
函数来自 #include <cstring>
,如果在字符串中找不到该字符,则返回一个空指针。
【讨论】:
为什么使用 C 函数?可以使用std::array<char, size> arr /* ... */ ; if (std::find(arr.cbegin(), arr.cend(), '+') == arr.cend() || /* ... */)
。
@6EQUJ5 因为它简单、清晰、简洁。我不会因为其他语言也提供相同的功能而对完全可用的功能有偏见
@6EQUJ5 std::strchr
是 C++ 标准强制要求的,并未弃用。它与上述文档规定的任何其他功能一样,都是 C++ 的一部分
@6EQUJ5:您建议的替代方案甚至比原始代码更加混乱和冗长,更不用说 MM 的建议了。
我想我应该注意,如果ch
可能是空字符,我的解决方案将不起作用以上是关于如何在if条件语句中搜索char数组中的char的主要内容,如果未能解决你的问题,请参考以下文章