对类的向量进行排序

Sort vector of class

本文关键字:排序 向量      更新时间:2023-10-16

在我得到"这是线程链接的副本"的回复之前,我想说的是,我已经实现了我在StackOverflow和CPlusPlus网站上阅读的内容。问题是我的向量无法排序。我在实现中一定遗漏了一些东西。可能是参考文献等的错误使用。

如下所示:我有两个类-DETargetParam和一个名为DETargetParamVector的包装类,该包装类包括一个类型为DETargetParam的STL向量。我的目标是使用DETargetParam的适应度成员变量按升序对std::向量进行排序。我试图通过在DETargetParam类中重载小于运算符并返回布尔结果来实现这一点。

然而,这并没有排序。所有的东西都编译和执行得很完美,但没有排序。我真的希望这里有人能帮助我。

这是DETargetParam:的源代码

#ifndef _DE_TARGET_PARAM_H_DP_
#define _DE_TARGET_PARAM_H_DP_
template <typename T, unsigned int N>
class DETargetParam {
 private:
  /** The array of N parameters in type T */
  T param[N];
  long double fitness;
  long double probability;
  long double probabilityInterval;
 public:
  /**
   * @brief Default constructor.
   *
   * Nada!
   */
  DETargetParam() {
    /* NULL */
  }
  long double getFitness() {
    return fitness;
  }
  void setFitness(long double x) {
    fitness = x;
  }
  long double getProbability() {
    return probability;
  }
  void setProbability(long double x) {
    probability = x;
  }
  long double getProbabilityInterval() {
    return probabilityInterval;
  }
  void setProbabilityInterval(long double x) {
    probabilityInterval = x;
  }
  bool operator<(const DETargetParam& rhs) const {
    return (fitness < rhs.fitness);
  }
  T& operator[](unsigned int i) {
    return param[i];
  }
};
#endif // _DE_TARGET_PARAM_H_DP_

和DETargetParamVector包装类:

#ifndef _DE_TARGET_PARAM_VECTOR_H_DP_
#define _DE_TARGET_PARAM_VECTOR_H_DP_
#include <algorithm>
#include <cstdio>
#include <vector>
#include "DETargetParam.h"
template <typename T, unsigned int N, unsigned int NP>
class DETargetParamVector {
 private:
  /** This is a STL vector holding the parameters */
  std::vector< DETargetParam<T, N> > vec;
 public:
  /**
   * @brief Default constructor
   *
   * Move along... nothing to see here.
   */
  DETargetParamVector() {
    vec.reserve(NP);
  }
  void SortAndCalculate() {
    SortVector();
    PrintSorted();
  }
  void SortVector() {
    std::sort(vec.begin(), vec.end());
  }
  void PrintSorted() {
    for (unsigned int i = 0; i < NP; ++i) {
      fprintf(stdout, "%.12Lf, %.12Lf, %.12Lfn", vec[i].getFitness(), vec[i].getProbability(), vec[i].getProbabilityInterval());
    }
    fprintf(stdout, "n");
    fflush(stdout);
  }
  DETargetParam<T, N>& operator[](unsigned int i) {
    return vec[i];
  }
};
#endif // _DE_TARGET_PARAM_VECTOR_H_DP_

以及主要功能细节:

#include <cmath>
#include <ctime>
#include "DETargetParamVector.h"
const unsigned int N = 10;
const unsigned int NP = 10;
int main() {
  srand(time(0));
  DETargetParamVector<long double, N, NP> targetVector;
  // For each member of the population.
  for (unsigned int i = 0; i < NP; ++i) {
    targetVector[i].setFitness(static_cast<long double>(rand()));
  }
  targetVector.SortAndCalculate();
  return 0;
}

提前谢谢。

您的向量确实得到了排序。问题是你的向量是空的,你所做的只是在向量之外写和读。

  /**
   * @brief Default constructor
   *
   * Move along... nothing to see here.
   */
  DETargetParamVector() {
    vec.reserve(NP);
  }

这个评论很讽刺,因为这是你的错误。vec.reserve(NP)不会改变矢量的大小,它只是在将来做一些节省工作的事情。你需要用调整大小来代替保留,或者更好的是从一开始就初始化它:

  /**
   * @brief Default constructor
   *
   * Move along... nothing to see here.
   */
  DETargetParamVector() : vec(NP) {
  }

在侧节点上,这是:

int N = 10;
int NP = 10 * N;
int main() {
  DETargetParamVector<long double, N, NP> targetVector;

是非法的,因为您有非常数作为模板参数。您需要将int N替换为int const N(对于NP也是如此)。

我已经为您的代码编写了一个稍微简化的版本,它至少可以生成和排序一些对象。我还(至少IMO)修复了一些地方,你的设计让我觉得有点问题(尽管结果仍然远远不够完美,至少IMO)。

de_target_param.h:

#ifndef _DE_TARGET_PARAM_H_DP_
#define _DE_TARGET_PARAM_H_DP_
#include <iostream>
template <typename T, unsigned int N>
class DETargetParam {
private:
    /** The array of N parameters in type T */
    //  T param[N];
    long double fitness;
    //  long double probability;
    //  long double probabilityInterval;
public:
    DETargetParam(long double f) : fitness(f) { }
    /*
    long double getFitness() {
    return fitness;
    }
    void setFitness(long double x) {
    fitness = x;
    }
    long double getProbability() {
    return probability;
    }
    void setProbability(long double x) {
    probability = x;
    }
    long double getProbabilityInterval() {
    return probabilityInterval;
    }
    void setProbabilityInterval(long double x) {
    probabilityInterval = x;
    }
    */
    friend std::ostream &operator<<(std::ostream &os, DETargetParam const &d) { 
        return os << d.fitness;
    }
    bool operator<(const DETargetParam& rhs) const {
        return (fitness < rhs.fitness);
    }
};
#endif // _DE_TARGET_PARAM_H_DP_

de_target_param_vector.h:

#include "de_target_param.h"
#ifndef _DE_TARGET_PARAM_VECTOR_H_DP_
#define _DE_TARGET_PARAM_VECTOR_H_DP_
#include <vector>
#include <iostream>
#include <algorithm>
#include <iterator>
template <typename T, unsigned int N, unsigned int NP>
class DETargetParamVector {
    std::vector< DETargetParam<T, N> > vec;
public:
    void push(DETargetParam<T, N> const &d) {
        vec.push_back(d);
    }
    void SortAndCalculate() {
        SortVector();
        std::cout << *this;
    }
    void SortVector() {
        std::sort(vec.begin(), vec.end());
    }
    friend std::ostream &operator<<(std::ostream &os, DETargetParamVector const &d) {
        std::copy(d.vec.begin(), d.vec.end(), std::ostream_iterator<DETargetParam<T, N> >(os, "n"));
        return os;
    }
};
#endif // _DE_TARGET_PARAM_VECTOR_H_DP_

而且,我已经编写了一个小型main,它创建、排序和打印(按排序顺序)一些对象:

#include "de_target_param_vector.h"
int main() {
    DETargetParamVector<int, 1, 5> params;
    for (int i=0; i<5; i++) 
        params.push(rand());
    params.SortAndCalculate();
    return 0;
}

根据你设计DETargetParam类的方式,我认为在谷歌上搜索一下"伪面向对象"或类似的东西应该会找到一些有用的、相关的阅读。你的很多代码似乎(至少在我看来)都是这种类型的例证。