【问题标题】:Passing Vector to function while using Graph使用 Graph 时将向量传递给函数
【发布时间】:2013-12-16 22:35:58
【问题描述】:

我在一个类中编写了这样的代码来计算从源到节点的最大距离。现在我需要把它从课堂上拿出来,并有一个类似的函数来计算我的距离,但要使用 Djikstra。因此,我需要将这个城市向量和源作为我的顶点之一传递(这将遍历顶点)并将该函数的距离返回给我的下一次计算。我的时间不多了,请帮帮我。

int distanceToNearCity(int cityIdOfStore, const std::vector<City> & AllCities) const
{
  // is there a store in this city ?
  if (storeExists || cityId == cityIdOfProposedNewStore)
  {
     return 0; // 0 distance
  }

  int distance = TOOFAR; // initialise with more than max allowed
  for (int i=0; i<connectingCities.size(); ++i)
  {
     int id = connectingCities[i];
     if (AllCities[id-1].hasStore() || AllCities[id-1].getId() == cityIdOfProposedNewStore)
     {
       // we have a store (or proposed one) here, but is it's distance more than other stores ?
       if (distances[i] < distance)
       {
          distance = distances[i];
       }
     }
  }

  return distance;
}

如何将这些类对象传递给公开的函数。谢谢!!

【问题讨论】:

  • 当你说你需要把它带出课堂时,你的意思是你需要把它变成一个静态/全局函数吗?我不清楚你的问题到底是什么。
  • 是的。因为我需要图表的每个顶点值才能从 main 访问它。我想让它成为全球性的。我正在尝试使用 Dijkstra 解决所有对的距离。所以,当我在循环时有一个新的源时,我可以在函数调用中使用它。
  • 如何让distanceToNearCity 虚拟化,从当前类派生并重新定义距离算法?
  • 您希望 1) 使其成为非成员函数,以及 2) 将算法更改为 Dijkstra。您需要哪方面的帮助?
  • @Beta 我在这两个方面都需要帮助。更多地关注(1)然后我需要知道如何将参数传递给这个非成员函数。

标签: c++ algorithm graph graph-algorithm


【解决方案1】:

嗯,从 main 访问内部成员变量可能是一个糟糕的设计,破坏了封装,可能是问题的根源,因此不是一个好主意。

解决方案 1

假设您的课程名为 MyOriginal。将distanceToNearCity 设为虚拟。创建派生类MyDerived 并重写distanceToNearCity 以便实现Djikstra。在派生类中,您可以从MyOriginal 访问原始成员变量,只要它们是公共的或受保护的。用户(主)不需要知道实现细节。

解决方案 2

重写原来的distanceToNearCity 方法,使它没有副作用,因为它是一个静态方法。这意味着它不需要访问任何成员变量。通过参数将所有参数传递给方法。我提到'因为它是一个静态方法',因为该方法不会是原始 MyOriginal 类的成员。将MyOriginal 设为模板类,在外部类中实现distanceToNearCity,并将该类作为模板参数传递给MyOriginal。作为非成员,您可以实现任意数量的距离算法并将它们传递给原始类。此解决方案的优势在于,对“虚拟”方法的调用在编译时是已知的,因此可以生成更快的代码。

template<class T> // T will contain distance computation
class MyOriginal
{
public:
  void process()
  {
    .. // your staff
    int distance = T::distanceToNearCity(necessary arguments); // call the external implementation
    .. // rest of your staff
  }
};
class OriginalDistance
{
public: 
  static int distanceToNearCity(necessary arguments); // your original implementation
};
class DjikstraDistance
{
public: 
  static int distanceToNearCity(necessary arguments); // another distance computation
};

int main(int argc, char *argv[])
{
  MyOriginal<DjikstraDistance> myInstance;
  myInstance.process(); // call processing, use DjikstraDistance::distanceToNearCity() inside
}

解决方案 3

如果您出于某种原因不喜欢之前的两种实现,您可以使用“c”样式的解决方案。创建一个表示distanceToNearCity 方法签名的类型。 编写“distanceToNearCityOriginal”和“distanceToNearCityDjikstra”函数。将指向所需函数的指针作为MyOriginal::process 方法的参数传递。 C++ 开发人员会不喜欢你。

typedef int (DistanceAlgo*)(necessary arguments); // pointer to a function which returns int
int distanceToNearCityOriginal(necessary arguments); // first implementation of distance
int distanceToNearCityDjikstra(necessary arguments); // second implementation of distance
class MyOriginal
{
public:
  void process(DistanceAlgo algo)
  {
    .. // your staff
    int distance = (*algo)(necessary arguments); // call the external implementation
    .. // rest of your staff
  }
};
int main(int argc, char *argv[])
{
  DistanceAlgo algo = &distanceToNearCityDjikstra; // choose djikstra
  MyOriginal myInstance;
  myInstance.process(algo); // call processing, use distanceToNearCityDjikstra inside
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-08-07
    • 2011-12-02
    • 1970-01-01
    • 1970-01-01
    • 2018-10-15
    • 2011-06-21
    • 2013-06-04
    • 1970-01-01
    相关资源
    最近更新 更多