利用Lambda解决蓝桥杯【消除尾一】问题

C++ Lambda新技能GET

今天在做第七届蓝桥杯试题的时候,遇到一道题:

消除尾一

下面的代码把一个整数的二进制表示的最右边的连续的1全部变成0
如果最后一位是0,则原数字保持不变。

如果采用代码中的测试数据,应该输出:
00000000000000000000000001100111 00000000000000000000000001100000
00000000000000000000000000001100 00000000000000000000000000001100

请仔细阅读程序,填写划线部分缺少的代码。

#include <stdio.h>

void f(int x)
{
    int i;
    for(i=0; i<32; i++) printf("%d", (x>>(31-i))&1);
    printf("   ");

    x = ________________;

    for(i=0; i<32; i++) printf("%d", (x>>(31-i))&1);
    printf("\n");   
}

int main()
{
    f(103);
    f(12);
    return 0;
}

乍一看,这果断得用一个函数来做呀!可是题中要求不能在横线外的其他地方写代码。这可就有点尴尬了!

突然脑袋灵光一现,不是有lambda嘛,妥了!

先看一下Lambda的表达式规范:

[ capture ] ( params ) mutable exception -> ret { body }

  • capture :指定了在可见域范围内外部变量的列表;

    1. [a,&b] a变量以值的方式呗捕获,b以引用的方式被捕获。
    2. [this] 以值的方式捕获 this 指针。
    3. [&] 以引用的方式捕获所有的外部自动变量。
    4. [=] 以值的方式捕获所有的外部自动变量。
    5. [] 不捕获外部的任何变量。
  • params :传入lambda表达式中的参数,和普通函数的函数列表相同,比如(int a, int b)。当然也可省略,相当于f();

  • mutable :被capture捕捉到的变量默认是const类型,不可修改。如果加上mutable之后便可以修改捕获对象的no-const变量;

  • exception :用于指定lambda表达式可以抛出的异常;

  • ret:是lambda的返回值类型,如果不写系统会自动从函数体的return语句推导。如果没有return语句即返回值为空。

  • { body }:这里是函数体。

我的思路是这样的,从最后一位依次往前判断,一旦遇到0就停止。
先写一个简单的判断语句:x>>(3)&1(用来判断倒数第四位数是1还是0)
那么接下来理所当然了:

i = 0;
while(x>>(i++)&1); //这一步得到第几位开始不为1

/*假设x为00101111,i为4,通过以下两个步骤就可以把最后一位*/
x>>=i; //00101111 >> 4 = 0010
x<<=i; //0010111 << 4 = 00100000

然后我们带入lambda表达式:

[&]()mutable{i=0;while(x>>(i++)&1);x>>=i;x<<=i;return x;}()
尾部的(),这对括号使得这个lambda表达式立即执行

因为我们需要利用外部变量,所以使用[&]来捕获,并且需要对变量进行修改,我们使用mutable。

检测一下运行结果,完美!
这里写图片描述

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值