#c
#c
Вопрос:
Я хотел бы использовать sort () для выполнения следующего
- У меня есть текстовый символ [] T, который является (частным) членом класса. Текст имеет длину n.
- У меня также есть массив int[] P, который содержит первые n целых чисел.
Я хотел бы использовать std::sort P таким образом, чтобы сохранялся лексикографический порядок среди суффиксов T, т. Е. для любого, i < j
который T[P[i]...n]
у нас есть, значение lex меньше, чем T[P[j]...n]
.
Я могу сделать это, когда char[] T
является глобальной переменной, определив
bool myfunction (int i,int j) {
int m = i, l = j;
while(m<n and l <n) {
if(T[m] != T[l]) return (T[m]<T[l]);
m ; l ;
}
return (m<l);
}
и вызывать std::sort(P, P n, myfuction)
Я в затруднении, когда T
является членом объекта (и сортировка вызывается методом этого объекта).
Как я могу определить, myfunction
чтобы это T
было видно? Должен ли он быть членом этого объекта? Если да, то каким образом? Большое вам спасибо.
Редактировать: bool вместо int
Комментарии:
1. Я отредактировал вопрос для наглядности, вы можете нажать на кнопку редактирования, чтобы увидеть выполненные изменения, в основном: элементы начинаются с » -» и нуждаются в начальной пустой строке. Вы можете форматировать код, встроенный в текст, с помощью обратных меток `, и вы можете форматировать блоки кода, выбирая блок и нажимая на
{}
кнопку.2. Какую версию
sort
вы используете? Это не такstd::sort
, или, если это так, вы используете его ужасно неправильным образом…
Ответ №1:
Как вы догадались, один из способов сделать это — определить yourfunction() как открытый член этого класса.
Пример:
#include <algorithm>
#include <vector>
using namespace std;
class T
{
private:
int value;
public:
T()
{
value = rand() % 100;
}
static bool Compare(const T amp;a, const T amp;b)
{
return a.value < b.value;
}
};
int main(int argc, char** argv)
{
vector<T> data;
//add some data
for (int i=0; i<10; i )
data.push_back(T());
//sort using static method that can access private attributes
std::sort(data.begin(), data.end(), T::Compare);
}
Ответ №2:
Если sort
представляет std::sort
, то функция, которую вы используете в качестве предиката, неверна по нескольким причинам, первая из которых заключается в том, что возвращаемый тип из функции должен быть bool
, а не an int
.
Следующая ошибка заключается в том, что предикат должен быть согласованным, то есть при наличии двух входных данных, a
а b
результат predicate( a, b )
должен быть либо true, либо false и всегда одним и тем же. Если это условие не выполнено, результат вызова sort
будет неопределенным, возможно, включая бесконечный цикл.
Этот подход (а не сам предикат), вероятно, также не является хорошим, поскольку количество раз, когда предикат будет вызван, зависит от входных данных и результатов различных вызовов предиката (до тех пор, пока алгоритм не посчитает, что в соответствии с вашим частичным порядком последовательность отсортирована).
Комментарии:
1. Да, я написал функцию так, как если бы это были c и qsort. Конечно, проблема в моем коде была не из-за этой опечатки bool / int.
2. Предикат правильный. Любой вызов myfuction всегда ссылается на один и тот же текст T. Таким образом, он согласован и выдает правильно отсортированные выходные данные. Моя проблема в том, что я не могу ссылаться на T всякий раз, когда он является членом объекта.
Ответ №3:
Вероятно, вам нужен объект-функтор:
struct myfunctor {
const char *T;
size_t n;
myfunctor(const char *T, size_t n) : T(T), n(n) {}
bool operator()(int i, int j) {
// stuff using T and n
}
// Optionally, something along these lines, I haven't tested it
template <size_t N> myfunctor(const char (amp;x)[N]) : T(amp;x[0]), n(N) {}
template <size_t N> myfunctor(char (amp;x)[N]) : T(amp;x[0]), n(N) {}
};
SomeObjectContainingT x;
std::sort(P, P n, myfunctor(x.T, x.n));
Или, если x.T
это фактический массив, а не просто указатель, конструкторы шаблона будут определять размер массива по типу, второй параметр не нужен:
std::sort(P, P n, myfunctor(x.T));
Редактировать: извините, пропустил, что T является закрытым. Я думаю, что здесь у вас есть две проблемы: область действия и доступность. Функтор решает проблему области видимости, теперь для доступности.
Если вы хотите, чтобы внешние функции обращались к T, x
необходимо предоставить средства для доступа к нему. Например, это может возвращать объект-функтор:
class SomeObjectContaining T {
char T[23];
public:
myfunctor comparator() { return myfunctor(T); }
};
std::sort(P, P n, x.comparator());
Или вы могли бы возиться с friend
: определите свой класс functor как friend
из SomeObjectContainingT , затем передайте объект его конструктору, а не массиву.