比较运算符

发布于 2024-09-28 10:49:32 字数 349 浏览 4 评论 0原文

这可能是个愚蠢的问题。 有没有办法在运行时使用字符串变量给出比较运算符。
假设我有一个向量中的工资数据。


vector < int > salary;
Input:
salary[i] != /* ==,>,<,>=,<= (any comparison operator)) */ 9000.

像上面给出的输入。我将比较运算符存储在字符串 str 中。 str =(任何比较运算符)。有没有办法像这样检查而不需要 if 和 switch。


salary str 9000

It may be silly question.
Is there any way to give comparison operator at runtime using string variable.

Suppose i have a data of salaries in vector.


vector < int > salary;
Input:
salary[i] != /* ==,>,<,>=,<= (any comparison operator)) */ 9000.

The input given like above. I store the comparison operator in string str. str = (any comparison operator). Is there any way to check like this without if and switch.


salary str 9000

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

花落人断肠 2024-10-05 10:49:32

您可以创建一个映射,其中运算符字符串作为键,对应比较操作的函数对象作为值。


创建地图:

std::map<std::string, boost::function<bool(int, int)> > ops;
ops["=="] = std::equal_to<int>();
ops["!="] = std::not_equal_to<int>();
ops[">"]  = std::greater<int>();
ops["<"]  = std::less<int>();
ops[">="] = std::greater_equal<int>();
ops["<="] = std::less_equal<int>(); 

使用它:

bool resultOfComparison = ops[str](salary[i], 9000);

(请参阅此链接一个完整的工作示例。)


编辑:

正如@sbi在下面的评论中所说,使用map[key]访问地图将创建一个条目,如果该键没有存在。因此,请改用 it = map.find(key) 。如果结果等于 map.end() 则未找到键,否则值为 it->second。在根据您的需求调整此解决方案时请注意这一点。

You can create a map with operator-strings as keys and function objects for corresponding comparison operations as values.


Creating a map:

std::map<std::string, boost::function<bool(int, int)> > ops;
ops["=="] = std::equal_to<int>();
ops["!="] = std::not_equal_to<int>();
ops[">"]  = std::greater<int>();
ops["<"]  = std::less<int>();
ops[">="] = std::greater_equal<int>();
ops["<="] = std::less_equal<int>(); 

Using it:

bool resultOfComparison = ops[str](salary[i], 9000);

(See this link for a complete working example.)


EDIT:

As @sbi said in the comments below, accessing a map using map[key] will create an entry if the key didn't exist. So use it = map.find(key) instead. If the result is equal to map.end() the key wasn't found, otherwise value is it->second. Take note of this while adapting this solution to your needs.

彩扇题诗 2024-10-05 10:49:32

不过,您可能有一个 std::map ,其中包含字符串内容和指向运算符的指针之间的映射。

Still, you might have a std::map with a mapping between contents of your strings and pointers to your operators.

☆獨立☆ 2024-10-05 10:49:32

不,不可能。除非你解析给定的输入并调用相应的操作。无论如何,您都需要一个 if - else 语句。

No. Not possible. Unless you parse the given input and call the corresponding operation. In any case, you would need a if - else statement.

缺⑴份安定 2024-10-05 10:49:32

您的编程语言中需要有某种 EVAL 来评估您的字符串。

编辑:C++ 没有 EVAL 来支持您的事业。

You need to have something of sort of EVAL in your programming language, which evaluates your strings.

EDIT: C++ does not have EVAL to support your cause.

雪若未夕 2024-10-05 10:49:32

不,像 C++ 这样的编译语言不能那样工作。最终可执行文件中必须有代码进行比较,并且根据设计,C++ 不会生成该代码,除非它实际上位于源程序中。

No, compiled languages like C++ don't work like that. There has to be code in the final executable that does the comparison, and by design C++ doesn't generate that code unless it's actually in the source program.

他不在意 2024-10-05 10:49:32

您还可以创建一个函子,它将字符串作为构造函数或工厂,它将产生不同的函子(取决于您需要的灵活性)。

所以类似::

输入
比较 cmp = 比较 (str);

if (cpm(工资[i], 9000))
{
计算<< “哇”;
}

You can also create a functor which will take string as a constructor or factory which will produce different functors (depending on flexibility you need).

So something like:

:Input
Comp cmp = Comp(str);

if (cpm(salary[i], 9000))
{
cout << "wow";
}

紫﹏色ふ单纯 2024-10-05 10:49:32

您必须“破解”这个所需的评估! ;)即

template <typename T>
bool eval_op(const string& op, const T& lhs, const T& rhs)
{
  switch(op.size())
  {
    case 2:
    {
      switch(op[1])
      {
        case '=':
        {
          switch(op[0])
          {
            case '=': return lhs == rhs;
            case '!': return lhs != rhs;
            case '>': return lhs >= rhs;
            case '<': return lhs <= rhs;
          }
        }
        default: throw("crazy fool!");
      };
    }
    case 1:
    {
      switch(op[0])
      {
        case '>': return lhs > rhs;
        case '<': return lhs < rhs;
        default: throw ("crazy fool!");
      }
    }
    default: throw ("crazy fool!");
  }

  return false;
}

免责声明:我还没有测试过这个......但这是一个想法......

You'd have to "hack" in this required eval! ;) i.e.

template <typename T>
bool eval_op(const string& op, const T& lhs, const T& rhs)
{
  switch(op.size())
  {
    case 2:
    {
      switch(op[1])
      {
        case '=':
        {
          switch(op[0])
          {
            case '=': return lhs == rhs;
            case '!': return lhs != rhs;
            case '>': return lhs >= rhs;
            case '<': return lhs <= rhs;
          }
        }
        default: throw("crazy fool!");
      };
    }
    case 1:
    {
      switch(op[0])
      {
        case '>': return lhs > rhs;
        case '<': return lhs < rhs;
        default: throw ("crazy fool!");
      }
    }
    default: throw ("crazy fool!");
  }

  return false;
}

DISCLAIMER: I've not tested this... but it's an idea...

ゝ偶尔ゞ 2024-10-05 10:49:32

在这种特殊情况下,if-else 分支是最简单的解决方案。这仅仅是因为只有这么多的比较选择,而且您可以确定不会存在其他选择。本质上,您的代码应该遵循以下内容:

if( in == "==" )
    cond = salary[i] == 9000;
else if( in == "!=" )
    cond = salary[i] != 9000;
// ...
else
  // throw, return -1, raise a flag or burst out in laughter

这实际上比动态 eval() 更安全,因为在这里您可以清理输入。您要确保其中没有类似于 Little Bobby Tables 攻击的恶意代码。

当然,您可以在这里使用多态性,但多态性的要点是支持开放式类型替代方案。当您希望添加案例时,多态性可以让您轻松做到这一点。但您需要做一些工作来打好基础,这里正好有 6 种比较方案。或者 7,如果您想添加对任意谓词的支持。

In this particular situation an if-else branch is your simplest solution. This is simply because there are only so many comparison alternatives, and you can be sure none others will ever exist. In essence your code should be along the lines of

if( in == "==" )
    cond = salary[i] == 9000;
else if( in == "!=" )
    cond = salary[i] != 9000;
// ...
else
  // throw, return -1, raise a flag or burst out in laughter

This is in fact safer than a dynamic eval() because here you sanitize the input. You make sure there is no malicious code in there, along the lines of a Little Bobby Tables attack.

Granted, you could use polymorphism here, but the point of polymorphism is support open-ended type alternatives. When you wish to add a case, polymorphism allows you to do that with ease. But you'd need to do some work to get foundations up, and here there are exactly 6 comparison alternatives. Or 7, if you want to add support for an arbitrary predicate.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文