Сортировать вектор класса - PullRequest
0 голосов
/ 22 марта 2012

Прежде чем я получу свою справедливую долю ответов «это дубликат ссылки на поток», я хотел бы сказать, что я реализовал то, что читал в StackOverflow и на веб-сайте CPlusPlus. Проблема в том, что мой вектор не сортируется. Я должен что-то упустить в реализации. Возможно неправильное использование ссылок и т. Д.

Здесь идет речь: у меня есть два класса - DETargetParam и класс-оболочка с именем DETargetParamVector, который включает вектор STL типа DETargetParam. Моя цель - отсортировать std :: vector в порядке возрастания, используя переменную-член пригодности DETargetParam. Я попытался сделать это, перегрузив оператор less в классе 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, %.12Lf\n", 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;
}

Заранее спасибо.

Ответы [ 2 ]

4 голосов
/ 22 марта 2012

Ваш вектор сортируется. Проблема в том, что ваш вектор пуст, и все, что вы делаете, это пишите и читаете вне вектора.

  /**
   * @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).

1 голос
/ 22 марта 2012

Я собрал несколько упрощенную версию вашего кода, которая по крайней мере работает для генерации и сортировки некоторых объектов. Я также (по крайней мере, 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, я думаю, что немного поиска в Google для «псевдообъект-ориентированной» или чего-то подобного должно привести к некоторому полезному, релевантному чтению. Большая часть вашего кода кажется (по крайней мере мне) примером жанра.

...