【问题标题】:given list of grades给定的成绩列表
【发布时间】:2022-01-23 13:01:02
【问题描述】:

这是我编写的代码,但是显示的内容不正确。请教我我需要解决什么问题。

#include <iostream>
#include <list>
using namespace std;

bool check(int passing){
    int g;
    if(g<=passing){
        return false;
    }else{
        return true;
    }
}

int main()
{
    int pg;

    cout<<"What is the passing grade?"<<endl;
    cin>>pg;

    list<int> grades = {100,90,93,95,92,98,97,99,96,94};
    grades.remove_if(check);
    for(int x : grades){
        cout<<x<<'\t';
    }
    return 0;
}

【问题讨论】:

  • 解释int g; if(g&lt;=passing) 的用途,特别是考虑到g 在与passing 比较之前没有确定的值。 Methinks g 应该是一个形式参数,而不是本地 var,它应该从 main 接收 pg 作为其参数,由 lambda 或 std 绑定绑定。事实上,完全摆脱check,只需在main 中实现一个lambda。
  • int g; if(g
  • DEMO。要么使用 lambda 将 passing grade 传递给 check 函数
  • 你如何使用 lambda

标签: c++ list c++11 remove-if


【解决方案1】:

使用 lambda 作为 remove_if谓词,如下所示:

#include <iostream>
#include <list>


int main( )
{
    std::cout << "What is the passing grade?\n";
    int passingGrade { };
    std::cin >> passingGrade;

    std::list<int> grades { 100, 90, 93, 95, 92, 49, 50, 98, 97, 99, 11, 94 };

    /*grades.remove_if( [ &passingGrade ]( const int grade ) // lambda approach
                      {
                          return ( grade < passingGrade ) ? true : false;
                      }
                    );*/

    for ( auto it = grades.begin( ); it != grades.end( ); ) // for-loop approach
    {
        if ( *it < passingGrade )
        {
            it = grades.erase( it );
        }
        else
        {
            ++it;
        }
    }

    for ( const int grade : grades )
    {
        std::cout << grade << '\t';
    }
}

示例 I/O

What is the passing grade?
50
100     90      93      95      92      50      98      97      99      94

另一个示例:

What is the passing grade?
95
100     95      98      97      99

【讨论】:

  • 是否可以不使用 lambda 并仍然使用 list 执行此操作?
  • @rese 也许吧。但事实上您已经在使用remove_if,将它与 lambda 结合起来只会让它更容易、更易读。现在,你为什么不想使用 lambda?
  • Lambda 还没教给我们。
  • @rese 哦,所以你可能不想惹恼你的老师!好吧,那我更新一下答案。
  • 是的。另外,我认为这将是下一课的一部分,所以我不想太领先
【解决方案2】:

你在这里:

#include <iostream>
#include <list>
#include <functional>

bool check(int const lhs, int const rhs) {
    return lhs < rhs;
}

int main() {
    int pg;
    std::cout << "What is the passing grade?\n";
    std::cin >> pg;
    std::list<int> grades{
        70, 90, 79, 85, 96, 73, 99, 91, 81, 83,
        99, 94, 80, 79, 85, 83, 82, 90, 84, 82,
        72, 83, 76, 93, 90, 77, 82, 76, 100, 94
    };
    grades.remove_if(std::bind(check, std::placeholders::_1, pg));
    for (auto const g : grades) {
        std::cout << g << '\t';
    }
    return 0;
}

当被问及是否删除调用它的特定元素时,函数检查必须返回 true。由于 remove_if 需要一元谓词(只能用 1 个参数调用的函数),我使用 std::bind 生成新的可调用对象,调用时传递参数 std::placeholders::_1 和 pg 来检查 where 而不是 std::placeholders ::_1 使用了来自等级的元素的副本。

让我们用 pg = 90 来玩这个。

check(70, 90) -> 是 70 是 -> 删除

check(90, 90) -> 是 90 没有 -> 保留

check(79, 90) -> 79 是 -> 删除

check(85, 90) -> 85 是 -> 删除

check(96, 90) -> 96 没有 -> 保留

我想你明白了。

【讨论】:

  • 谢谢。我得到它。但是有没有更简单的方法可以在不使用 std::bind 的情况下做到这一点??
  • 还有两个,即 lambda 和 struct/class,它们重载了 operator(),可以作为函数调用,但实际上,当您使用第一个 (lambda) 时,编译器会将其转换为第二个(具有 operator() 重载的结构/类)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-08-13
  • 2021-04-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-03-31
相关资源
最近更新 更多