如何找到两个袋子的交叉点

时间:2013-09-17 04:39:51

标签: c++

好的,我把这段代码放下了。

行李接口

#ifndef BAGINTERFACE_H
#define    BAGINTERFACE_H

#include <vector>
#include <algorithm>

template<class ItemType>
class BagInterface
{
    public:

    virtual int getCurrentSize() const = 0;
    virtual bool isEmpty() const = 0;
    virtual bool add(const ItemType& newEntry) = 0;
    virtual bool remove(const ItemType& anEntry) = 0;
    virtual void clear() = 0;
    virtual int getFrequencyOf(const ItemType& anEntry) const = 0;
    virtual bool contains(const ItemType& anEntry) const = 0;
    virtual std::vector<ItemType> toVector() const = 0;
}; 

#endif    /* BAGINTERFACE_H */

袋      #ifndef BAG_H     #define BAG_H

#include "BagInterface.h"

template <class ItemType>
class Bag: public BagInterface<ItemType>
{

public:

    int getCurrentSize() const { return v.size(); }
    bool isEmpty() const { return v.empty(); }
    bool add(const ItemType& newEntry) { v.push_back(newEntry); return true; }
    bool remove(const ItemType& anEntry) { std::remove(v.begin(), v.end(), anEntry); return true; }
    void clear() { v.clear(); }
    int getFrequencyOf(const ItemType& anEntry) const { return std::count(v.begin(), v.end(), anEntry); }
    bool contains(const ItemType& anEntry) const { return true; }
    std::vector<ItemType> toVector() const { return v; }

private:

  std::vector<ItemType> v;

};

#endif    /* BAG_H */

和我的实际程序main.cpp

#include <iostream> // For cout and cin
#include <string> // For string objects
#include "Bag.h" // For ADT bag
using namespace std;
int main()
{
string clubs[] = { "Joker", "Ace", "Two", "Three",
"Four", "Five", "Six", "Seven",
"Eight", "Nine", "Ten", "Jack",
"Queen", "King" };
// Create our bag to hold cards
Bag<string> grabBag;
Bag<string> dumpBag;

grabBag.add(clubs[1]);
grabBag.add(clubs[2]);
grabBag.add(clubs[4]);
grabBag.add(clubs[8]);
grabBag.add(clubs[10]);
grabBag.add(clubs[12]);

dumpBag.add(clubs[3]);
dumpBag.add(clubs[5]);
dumpBag.add(clubs[7]);
dumpBag.add(clubs[9]);
dumpBag.add(clubs[10]);
dumpBag.add(clubs[12]);

Bag<string> Itersection(Bag<string> bagToCompare){


    return grabBag;
}


return 0;
}; // end main

我正试图找到两个袋子的交叉点,这个袋子将是一个新的袋子,其中包含两个原始两个袋子中的条目。所以基本上我需要设计并指定一个方法交集,作为一个新的包返回接收方法调用的包和方法的一个参数包。 假设bag1和bag2是袋子; bag1包含字符串a,b和c; and bag2包含字符串b,b,d和e。表达式bag1.intersection(bag2)返回一个只包含字符串b的包。

我已经将这两个包相互比较,但我不太确定如何设计交叉方法。

任何帮助都会很棒。 谢谢。

3 个答案:

答案 0 :(得分:1)

由于枚举行李中物品的唯一方法是使用toVector,因此您需要迭代其中一个输入行李的toVector。对于每个项目,在任一输入包中取出该项目的最小频率,并确保输出包中包含具有该频率的项目。由于toVector可能会重复包含相同的项目,因此您必须检查输出包,看它是否已包含您正在考虑的项目。

我不能快速使用C ++ 11,所以我只是采用一种老式的方式:

template<class T>
Bag<T> intersection(BagInterface<T> const &a, BagInterface<T> const &b) {
    Bag<T> c;
    std::vector<T> aItems = a.toVector();
    for (int i = 0; i < aItems.size(); ++i) {
        T const &item = aItems[i];
        int needed = std::min(a.getFrequencyOf(item), b.getFrequencyOf(item));
        int lacking = needed - c.getFrequencyOf(item);
        for ( ; lacking > 0; --lacking) {
            c.add(item);
        }
    }
    return c;
}

答案 1 :(得分:0)

尝试将enum用于俱乐部。你可以使用字符串,但字符串比较很棘手。

答案 2 :(得分:0)

来自std::set_intersection

<algorithm>对排序的输入范围执行此操作:

vector<int> as { 1, 2, 3 };
vector<int> bs { 2, 3, 4 };
vector<int> cs;

set_intersection(
    begin(as), end(as),
    begin(bs), end(bs),
    back_inserter(cs)
);

// 2 3
for (const auto c : cs)
    cout << c << ' ';

它通过循环输入范围直到至少有一个用尽,根据operator<强加的严格弱排序从另一个范围内复制这些元素,这是有效的:

while (first1 != last1 && first2 != last2) {
    if (*first1 < *first2) {
        ++first1;
    } else {
        if (!(*first2 < *first1)) {
            *output++ = *first1++;
        }
        ++first2;
    }
}
return output;