您好我的程序与大学课程表有关,它有一些排序函数,我们将处理升序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;
}
}
答案 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等等。但上述内容很简单,容易出错。
函数upGPA
和downGPA
不应该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
。