颠倒排序的顺序

时间:2015-02-05 19:05:43

标签: c++ sorting

您好我的程序与大学课程表有关,它有一些排序函数,我们将处理升序gpa函数和降序gpa函数。

这是降序函数,它运行正常:

void classSchedule::downGPA(classSchedule schedule[], int& numElems)
{
    classSchedule temp;
    int end;
    for (end = numElems - 1; end >= 0; end--)
    {
        for (int counter = 0; counter < end; counter++)
        {
            if (schedule[counter].classNumber == 000)
                counter++;
           if (schedule[counter].currentGPA < schedule[counter + 1].currentGPA)
           {

              temp = schedule[counter];
              schedule[counter] = schedule[counter + 1];
              schedule[counter + 1] = temp;
           }
       }
    }
    schedule->outputToConsole(schedule, numElems);

}

这是升序功能,由于某种原因它没有显示任何内容:

void classSchedule::upGPA(classSchedule schedule[], int& numElems)
{
    classSchedule temp;
    int end;
    for (end = numElems - 1; end >= 0; end--)
    {
        for (int counter = 0; counter < end; counter++)
         {
            if (schedule[counter].classNumber == 000)
                counter++;
           if (schedule[counter].currentGPA > schedule[counter + 1].currentGPA)
           {

              temp = schedule[counter];
              schedule[counter] = schedule[counter + 1];
              schedule[counter + 1] = temp;
           }
       }
    }
    schedule->outputToConsole(schedule, numElems);
}

我更改了标志并且它没有显示任何人可以看到原因吗?

编辑:

按要求输出功能

void classSchedule::outputToConsole(classSchedule currentSchedule[], int numElems)
{
    int i;
    cout << endl << "Dept" << "\t" << "Class Number\t" "Credit Hours" << "\t" << "Name"
         << "\t" << "Room Number" << "\tGPA"
         << endl << "----" << "\t------------" << "\t-------------   ----"
         << "\t-----------" << "\t---";
    for (i = 0; i < numElems; i++)
    {
        if (currentSchedule[i].displayOrNot == "FALSE")
            i++;
        if(currentSchedule[i].currentGPA == -1)
        {
            break;
        }
        cout << endl << currentSchedule[i].classDepartment << "         " << currentSchedule[i].classNumber << "    \t"
             << "      " << currentSchedule[i].creditHours << "    \t"
             << currentSchedule[i].teacherLastName << " " << currentSchedule[i].teacherFirstName
             << "\t" << currentSchedule[i].roomWingAndNumber << "\t" <<      currentSchedule[i].currentGPA;
    }

}

2 个答案:

答案 0 :(得分:1)

您的排序功能存在几个问题:

  • 您的循环条件为counter < end并且您使用[counter + 1]作为数组索引,您将在第一次迭代时退出数组边界,建议更改条件为counter < end -1
  • 代码if (schedule[counter].classNumber == 000)很危险,不清楚为什么需要它。可能是为了避免以前的错误

Coolprit似乎就是这段代码:

if(currentSchedule[i].currentGPA == -1)
{
    break;
}

当您按降序排序时,记录结束并且工作正常。但是当你按升序排序时,记录正在开始并且你打断你的循环。如果您想要使用GPA -1跳过记录,请在该代码中将break替换为continue

答案 1 :(得分:0)

这是一个小帮手,可以轻松地按某些派生值进行排序:

template<class F>
struct order_by_t {
  F f;
  template<class Lhs, class Rhs>
  bool operator()( Lhs const& lhs, Rhs const& rhs ) const {
    return f(lhs) < f(rhs);
  }
};
template<class F>
order_by_t< F > order_by( F f ) { return {std::move(f)}; }

你调用order_by( function )并返回一个取值的函数对象,并按函数返回的顺序对它们进行排序。

所以order_by( function )返回一个带有两个东西的函数对象,并根据function告诉你的顺序告诉你左边的那个是否比右边的“少”。

这很有用,因为C ++的标准库可以传递排序函数对象并使用它们有很多原因。

这个助手使upGPA写得很短:

void classSchedule::upGPA(classSchedule schedule[], int numElems) {
  classSchedule* start = &schedule[0];
  classSchedule* finish = start+numElems;
  std::sort( start, finish,
    order_by( [](classSchedule const& s){return s.currentGPA;} )
  );
}

order_by( [](classSchedule const& s){return s.currentGPA;} )是神奇发生的地方。

我会展开它。写一个更简单的方法是:

[](classSchedule const& lhs, classSchedule const& rhs){
  return lhs.currentGPA < rhs.currentGPA;
}

但我喜欢我的方式。

order_by接受一个参数的函数,并构建一个排序(替换<)。

它需要A->B类型的函数(将其视为“类型B的元素的类型A的元素”),以便B被排序(支持<),并生成(A,A)->bool类型的函数,它是A的排序。它通过获取每个参数,将其映射到A->B地图,然后比较B来实现此目的。

因此order_by属于(A->B) -> (A,A) -> bool类型,它返回基于A->B函数的排序。

我发现这种投射 - 一种类型的订单 - 非常有用。在这种情况下,它可能有点矫枉过正。


轻松实现downGPA - 排序,然后反转:

void classSchedule::downGPA(classSchedule schedule[], int numElems) {
  upGPA(schedule, numElems);
  classSchedule* start = &schedule[0];
  classSchedule* finish = start+numElems;
  std::reverse( start, finish );
}

您可以改为使用反向迭代器,或使用否定的order-by等等。但上述内容很简单,容易出错。

函数upGPAdownGPA不应该outputToConsole。在另一个步骤中做到这一点。打印是一个与向上或向下重新排序不同的问题。

以上使用C ++ 11。使用gcc或clang,您可能需要传入一个标志以启用支持。

如果您缺少C ++ 11,这将起作用:

template<class F>
struct order_by_t {
  F f;
  order_by_t(F in):f(in) {}
  order_by_t(order_by_t const& o):f(o.f) {}
  template<class Lhs, class Rhs>
  bool operator()( Lhs const& lhs, Rhs const& rhs ) const {
    return f(lhs) < f(rhs);
  }
};
template<class F>
order_by_t< F > order_by( F f ) { return f; }
int getCurrentGPA( classSchedule const& s ) {
  return s.currentGPA;
}

然后:

void classSchedule::upGPA(classSchedule schedule[], int numElems) {
  classSchedule* start = &schedule[0];
  classSchedule* finish = start+numElems;
  std::sort( start, finish,
    order_by( getCurrentGPA )
  );
}

应该有用。

甚至更容易:

bool orderByCurrentGPA( classSchedule const& lhs, classSchedule const& rhs ) {
  return lhs.currentGPA < rhs.currentGPA;
}
void classSchedule::upGPA(classSchedule schedule[], int numElems) {
  classSchedule* start = &schedule[0];
  classSchedule* finish = start+numElems;
  std::sort( start, finish,
    orderByCurrentGPA
  );
}

做同样的事情。 (我在这里删除了order_by