【问题标题】:c++: check for an object of a class in an array of objectsc ++:在对象数组中检查类的对象
【发布时间】:2015-10-14 16:37:23
【问题描述】:

假设我有一个类元素,

class Element {
private:
    int value;
public:
    void setValue(int v) {
        value = v;
    }
    int getValue() {
        return value;
    }
};

我将此类的对象存储在一个数组中。 现在如何检查我的对象数组是否包含某个元素类的对象。我尝试使用此函数匹配对象的值...有没有更好的方法?

bool contains(Element e)
{
    int i;

    for(i=0;i<size;i++)
        if(elements[i].getValue()==e.getValue()) return true;
    else return false;
}

【问题讨论】:

  • 你从哪里得到“元素”数组?
  • 首先,您在代码中使用了类似于“for else”循环的python。在 c++ 中它不会像在 python 中那样工作。 “Else”是“if else”控制流结构的一部分,因此您的 for 循环将在第 0 个元素处结束。除了你的代码应该可以工作。
  • 也忘记在函数参数中设置大小。

标签: c++ arrays class vector


【解决方案1】:

您可以使用像 std::array 这样的 C++ 容器,然后使用 std::find_if。

如果您更喜欢扩展您的代码,您可以使用

重载 operator==
bool operator==(const Element& lhs, const Element& rhs) {
    return lhs.value == rhs.value
}

那么你可以使用

for(i=0;i<size;i++)
    if(elements[i]==e) return true;

编辑:

由于Element.value 是私有的,您可能希望将其设为Element 的方法

bool Element::operator==(const Element& other) {
    return value == other.value
}

【讨论】:

  • 仅供参考,value 成员是私有的。您打算使用getValue() 还是将其实现为成员函数?需要修复 const 正确性才能使用 getValue() 成员函数。
【解决方案2】:

我建议使用像 stds::arraystd::vector 这样的 C++ 容器来保存您的元素,并使用 std::find_if 来搜索它。

如果您使用的是支持 C++11 语法的编译器,那么您可以像这样使用 std::find_if:

int main () 
{
    std::vector<Element> myvector;

    // fill vector

   int valueToCompare = 1234;

   auto it = std::find_if(begin(myvector), end(myvector), [=](const Element& e) {return e.getValue() == valueToCompare;});

   return 0;
}

【讨论】:

  • 是的,我编译了,只是想知道这样做是否可以
  • @SaifulIslam 你的 if 逻辑是错误的。 return false 语句应该在没有 else 的 for 循环之外。否则,如果您在第一个项目中没有找到您要查找的内容,那么当该项目可能存在于数组中的某个位置时,您将返回 false。
【解决方案3】:

您可以将比较运算符添加到您的元素类中,然后使用 stl 算法或类似 stl 的算法来确定元素是否在容器中。

class Element {
private:
    int value;
public:
    Element(int v) : value(v) {}
    Element(Element const& e) : value(e.value) {}

    Element & operator=(Element const& e) {
        value = e.value;
    }

    bool operator==(Element const& e) const {
        return value == e.value;
    }

    bool operator!=(Element const& e) const {
        return value != e.value;
    }

    void setValue(int v) {
        value = v;
    }
    int getValue() {
        return value;
    }
};

现在你可以做这样的事情了。

std::vector<Element> elements;

for(int i = 0; i < 10; ++i) {
    elements.push_back(Element(i));
}

 // Find the element with the value 4
auto found = std::find(elements.begin(), elements.end(), Element(4));
if(found != elements.end()) {
    // Do something
}

或者像你描述的那样使用循环。

Element toFind(4);

for(auto it = elements.begin(); it != elements.end(); ++it) {
     if(*it == toFind) {
       // Do something
     }
}

【讨论】:

    【解决方案4】:

    首先你可以实现等比运算符

    class Element {
    private:
        int value;
    public:
        // btw. These setters and getters are Java style, not C++ style.
        void setValue(int v) {
            value = v;
        }
        // note that a getter should be const. It doesn't change the object.
        auto getValue() const -> int {
            return value;
        }
        auto operator == (const Element& other) const -> bool {
            return value == other.value;
        }
        auto operator != (const Element& other) const -> bool {
            return !(*this == other);
        }
    };
    

    现在你可以使用 std::find():

    auto contains(const Element& e) -> bool
    {
        auto end = elements + size; // pointers can be used as iterators as well.
        return std::find(elements, end, e) != end;
    }
    

    您应该更喜欢 std::vectorstd::array 而不是原始数组。 std::array 不增加任何开销,但使接口与其他std::-containers 更加一致。 std::vector 用于动态大小的数组。它为您处理所有分配、初始化、销毁、释放等操作。

    【讨论】:

      【解决方案5】:

      虽然上述答案可能对专业程序员有好处,但我相信在您的水平上,Adkison,您会想要一个更简单的答案。

      bool contains(Element e)
      {
          int i;
      
          for(i=0;i<size;i++)
              if(elements[i].getValue()==e.getValue()) return true;
          else return false;
      }
      

      好的,所以一个问题是元素没有值,大小也没有。它应该作为参数传入。我们还将在 e 上使用 const-&,这样就不需要复制它了(尽管这不是很大的成本)。

      bool contains  (const Element elements[], int size, const Element& e) ...
      

      (是的,我们可以将元素作为向量传递,但现在让我们保持简单。)

      我相信您注意到的问题是它永远不会超过查看第 0 个元素。追溯,你会明白为什么。假设元素#0 等于e;您的函数返回 true,并完成。假设它不相等:您的函数返回 false,并且完成。那么所有其他元素呢?我们不应该也检查它们吗,至少如果元素 #0 不是我们想要的?

      那么:什么时候应该我们返回false?当我们遍历整个列表却找不到e

          for(i=0;i<size;i++)
              if(elements[i].getValue()==e.getValue()) return true;
      
          return false;
      

      这个版本在遍历整个数组并且没有找到 e 之前不会返回 false。

      【讨论】:

        猜你喜欢
        • 2013-06-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-09-07
        • 1970-01-01
        • 2016-01-20
        • 2021-12-14
        相关资源
        最近更新 更多