如何在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::findstd::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 &lt;cstring&gt;,如果在字符串中找不到该字符,则返回一个空指针。

【讨论】:

为什么使用 C 函数?可以使用std::array&lt;char, size&gt; arr /* ... */ ; if (std::find(arr.cbegin(), arr.cend(), '+') == arr.cend() || /* ... */) @6EQUJ5 因为它简单、清晰、简洁。我不会因为其他语言也提供相同的功能而对完全可用的功能有偏见 @6EQUJ5 std::strchr 是 C++ 标准强制要求的,并未弃用。它与上述文档规定的任何其他功能一样,都是 C++ 的一部分 @6EQUJ5:您建议的替代方案甚至比原始代码更加混乱和冗长,更不用说 MM 的建议了。 我想我应该注意,如果ch 可能是空字符,我的解决方案将不起作用

以上是关于如何在if条件语句中搜索char数组中的char的主要内容,如果未能解决你的问题,请参考以下文章

字符类型中的if / else语句

用于检查 char 数组是不是包含 Java 中用户给定字母的 if 语句

比较 c 中的 int 和 char,使用 if 条件

条件语句循环数组

如何检查 char 数组中的空格?

c语言中如何把结构体中的char num[10]与数组中的char num2[10]比较数据啊?