重要思想总结

2023-11-14

求二进制序列中1的个数:

m&(m-1)会把m的二进制序列中最右边的1去掉,每进行一次m&(m-1)得到一个新的m,都会消除掉m二进制序列中最右边的1,故m二进制序列中1的个数即消除1的次数,即m和m-1相与的次数。

#include<stdio.h>

int main()
{
	int m = 15;
	int count = 0;
	
	while (m)
	{
		m = m & (m - 1);
		count++;
	}

	printf("%d\n", m);

	return 0;
}

拓展: 如果m = 2^n,那么m和(m-1)相与一次,结果就为0。

检测num中某一位是0还是1:

我们将一个数的二进制序列和1相与,如果相与后的结果位1,则说明该数最低位为1,如果相与后的结果为0,说明该数的最低位为0。

所以如果我们想要检测num中第i位是0还是1,我们只需将其向右移动i位,即移动到最低位,然后和1相与,如果结果为0,则第i个比特位为0,如果结果为1,则第i个比特位为1。

注:
二进制序列的位数从0开始算,即最低位为第0位,最高位为第31位。

不创建临时变量交换值:

#include <stdio.h>

int main()

{

	int a = 10;

    int b = 20;

    printf("交换前:a = %d b = %d\n", a,b);

    a = a^b;

    b = a^b;

    a = a^b;

    printf("交换后:a = %d b = %d\n", a,b);

	return 0;

}

判断数值的位数

获取数值的每一位:

数值拆分的规律如下:

个位 :数值 % 10
十位 :数值 / 10 % 10
百位 :数值 / 10 / 10 % 10
千位 :数值 / 10 / 10 / 10 % 10;

判断数值的位数:

#include<stdio.h>

int main()
{
	int count = 1;//至少为1位数
	int temp = 0;

	scanf("%d", &temp);

	while (temp /= 10)

	{
		count++;
	}

	printf("%d\n", count);

}

获取数值的每一位数:

#include<stdio.h>

//获取数值的每一位数

int main()
{
	int num = 0;
	scanf("%d", &num);
	int m = 0;

	while (num)
	{
		//依次获取个位数,十位数,百位数....
		m = num % 10;
		num /= 10;
	}

	return 0;
}

把一个整数的二进制位的奇数位和偶数位交换

所谓奇数位和偶数位交换就是指所有奇数位左移一位,所有偶数位右移一位,那我们只需要获取这个数的偶数位,奇数位全部置为0,然后将偶数位右移一位,即实现了所有偶数位右移一位,同时获取奇数位,偶数位全部置位0,然后所有奇数位再左移一位,即实现了所有奇数位左移一位,把所有偶数位右移一位后的结果加上所有奇数位左移一位后的结果即为所有偶数位右移一位且所有奇数位左移一位后的结果,即偶数位和奇数位交换的结果。

那我们要如何获取这个数的偶数位,奇数位全部置为0,并且同时获取奇数位,偶数位全部置位0呢?

我们只需将这个整数与101010101010101010101010101010相与,即与0xaaaaaaaa相与,就可以获取所有的偶数位同时奇数位全部置为0,同理,我们只需要将这个整数与01010101010101010101010101010101相与,即与0x55555555相与即可获取所有的奇数位并且将偶数位置为0。

用一个宏来实现这个功能就是

#define SWAP(x)((((x)&0xaaaaaaaa) >> 1) + (((x)&0x55555555) << 1))

函数同理。

将个位数,十位数,百位数…组成一个完整的数

核心思想:个位数乘以十的零次方 + 十位数乘以十的1次方 + 百位数乘以十的2次方…

#include<stdio.h>
#include<math.h>;

int main()
{
	int n = 0;//表示几位数
	scanf("%d", &n);
	int k = 0;//用于核心语句的幂次
	int re = 0;//记录结果
	int i = 0;//记录每一位数

	while (n)
	{
	//依次输入个位数,十位数,百位数
		scanf("%d", &i);
		//该句是核心代码
		re += i * pow(10, k++);
		n--;
	}

	printf("%d\n", re);

	return 0;
}

找素数

判断1~n之间有多少个素数,并输出所有素数,素数:如果除了1和它本身以外,不能被其他正整数整除,就叫素数。对于一个整数y,无需判断在2 ~ y-1之间能否被其它整数整除。只需判断2 ~ 根号y之间是否能够被其它整数整除:

#include <math.h>

int main()
{
	int y = 0;
	int count = 0;
	for (y = 101; y <= 200; y+=2)
	{
		//因为偶数一定不是素数,所以直接判断奇数即可
		int n = 0;
		int flag = 1;//假设y是素数
		for (n = 2; n <= sqrt(y); n++)
		{
			if (y % n == 0)
			{
				flag = 0;//y不是素数
				break;
			}
		}
		if (flag == 1)
		{
			printf("%d ", y);
			count++;
		}

	}
	printf("\ncount = %d\n", count);

	return 0;
}

将秒转化为时分秒

#include <stdio.h>

int main()
{
	int h = 0;//小时数
	int m = 0;//分钟数
	int s = 0;//秒数
	int seconds = 0;
	//输入
	scanf("%d", &seconds);

	//计算
	h = seconds / 3600;
	m = (seconds % 3600) / 60;
	s = (seconds % 3600) % 60;

	//输出
	printf("%d %d %d", h, m, s);
	return 0;
}

求最大公约数

方法一:

#include <stdio.h>
 int main()
{
	int m = 0;
	int n = 0;
	scanf("%d %d", &m, &n);

	//求最大公约数
	int ret = 0;
	//1. 求m和n 较小值,假设就是最大公约数
	if (m > n)
		ret = n;
	else
		ret = m;

	while (1)
	{
		if (m % ret == 0 && n % ret == 0)
		{
			break;
		}
		ret--;
	}
	//打印
	printf("%d\n", ret);

	return 0;
}

方法二:辗转相除法

int main()
{
	int m = 0;
	int n = 0;
	scanf("%d %d", &m, &n);//18 24
	//求最大公约数
	int ret = 0;
	while (ret=m%n)
	{
		m = n;
		n = ret;
	}
	printf("%d\n", n);

	return 0;
}

求最小公倍数

方法一:暴力求解法

#include<stdio.h>

int minbei(int a, int b)
{

    int re = 0;

    if (a == b)
    {
        re = a;
    }
    else
    {
        re = a > b ? a : b;

        while (!(re % a == 0 && re % b == 0))
        {
            re++;
        }
    }

    return re;;
}

int main()
{
    int a = 0;
    int b = 0;
    scanf("%d %d", &a, &b);

    printf("%d\n", minbei(a, b));

    return 0;
}

方法二:

#include<stdio.h>

int main()
{
    int a = 0;
    int b = 0;
    scanf("%d %d",&a,&b);
    int i = 1;
    
//如果a*i%b==0,那么a*i一定是最小公倍数
    while((a * i % b)!= 0)
    {
        i++;
    }
                        
    printf("%d\n",a*i);
    
    return 0;
}

闰年的判断

# include <stdio.h>

//1. 能被4整除,并且不能被100整除是闰年
//2. 能被400整除是闰年

int main()
{
	int y = 0;
	int count = 0;
	for (y = 1000; y <= 2000; y++)
	{
		if (((y % 4 == 0) && (y % 100 != 0)) || (y % 400==0))
		{
			count++;
			printf("%d ", y);
		}
	}
	//输出个数
	printf("\ncount = %d\n", count);
	return 0;
}

倒置字符串

比如输入为:I like Beijing.
逆置后输出为:Beijing. like I

思想:先逆置每个单词,然后逆置整个字符串,就实现了逆置一句话中的单词

#include<stdio.h>
#include<string.h>
#include<assert.h>

//逆置函数
void reverse(char* left, char* right)
{
	//断言,确保指针不为空再进行操作
    assert(left && right);

    while (left < right)
    {
        char temp = *left;
        *left = *right;
        *right = temp;
        left++;
        right--;
    }
}

int main()
{
    char arr[100] = { 0 };

    //输入字符串
    gets(arr);
    int sz = strlen(arr);//获取字符串的长度

    //逆置字符串
    char* start = arr;
    char* end = start;

    //1.先逆置每个单词
    while (1)
    {
        while (*end != ' ' && *end != '\0')
        {
            end++;
        }

        reverse(start, end - 1);

			//当*end == '\0',说明刚刚逆置的是最后一个单词,所以跳出该循环
        if (*end == '\0')
        {
            break;
        }
        else
        {
            start = end + 1;
            end = start;
        }
    }

    //2.逆置整个字符串
    start = arr;
    end = arr + sz - 1;
    reverse(start, end);

    //输出字符串
    printf("%s", arr);

    return 0;
}

给元素排序且删除掉重复的元素

核心思想:我们假设一共有n个元素,且元素的值k满足 k>=0 && k<=n,那我们可以定义一个数组arr[n+1],也就是k的取值在下标范围之内,那么如果k的值为2,那我们就将2赋值给arr[2],如果k的值为80,那么我们就将80赋值给arr[80],这样就既保证了元素有序,也保证了元素不会重复。

但是要切记,使用这个思想的前提是k的取值在下标范围之内

假设0 ≤ n ≤ 100,0 ≤ k ≤ n代码如下:

#include<stdio.h>

int main()
{
    int i = 0;
    int n = 0;//表示我们要排序的元素个数
    int temp = 0;//输入几,就把它存放到下标为几的元素中
    int arr[101] = { 0 };
    scanf("%d", &n);
    

    for (i = 1; i <= n; i++)
    {
        scanf("%d", &temp);
        arr[temp] = temp;
    }

    for (i = 1; i <= n; i++)
    {
        if (arr[i] != 0)
        {
            printf("%d ", arr[i]);
        }
    }


    return 0;
}

删除指定元素

方法一:

对于一个数组我们想删除一个指定元素,只需要定义两个变量i和j,i不断向后遍历来寻找要删除的元素,j表示当前可以存放元素的位置,只要i所指向的元素不是要删除的元素,那么我们就可以将i所指向的元素赋值给j所指向的数组单元,然后i和j都自增1,如果i指向的元素是待删除元素,那么不进行赋值操作,j此时指向待删除元素,j不变,i自增1,如果后面的元素不是待删除元素,那么将i指向的元素赋值给j指向的位置,即实现了删除指定元素。

如图所示,假设我们要删除元素9,从上往下依次为执行过程:

在这里插入图片描述

#include <stdio.h>

int main()
{
		int arr[50] = { 0 };
    int n = 0;//记录有效序列的长度
    scanf("%d", &n);
    int i = 0;
    int j = 0;
    //输入要删除的值
    int del = 0;
    scanf("%d", &del);
    
    //输入数据
    for (i = 0; i < n; i++)
    {
        scanf("%d", &arr[i]);
    }

    for (i = 0; i < n; i++)
    {
        if (arr[i] != del)
        {
            arr[j++] = arr[i];
        }
    }
	//遍历输出
    for (i = 0; i < j; i++)
    {
        printf("%d ", arr[i]);
    }
    return 0;
}

方法二:
如果我们只是需要输出数组中的元素,那么可以直接跳过待删除元素进行输出,也就是依次遍历输出数组中的每个元素,当遇到指定元素时跳过不输出,继续输出后面的元素。这样做的缺点是表面上删除了指定元素,实际上并没有删除。

#include<stdio.h>


int main()

{

   int n = 0;
   scanf("%d",&n);
   int arr[50] = {0};
   int i = 0;
   int key = 0;//要删除的数字
   scanf("%d",&key);//获取要删除的元素

	 //将元素存储到数组中
    for(i = 0;i<n;i++)
	 {
		scanf("%d",&arr[i]);
	 }

   //跳过输出指定数字即删除指定数字
    for(i = 0;i<n;i++)
	 {
		  if(arr[i] != key)
			{
				 printf("%d ",arr[i]);   
			}
	  }
	
	return 0;

}

左旋字符串

实现一个函数,可以左旋字符串中的k个字符。

常规思路:旋转k个字符串即旋转k次,每次旋转1个字符

void left_move(char* str, int k)
{
	int i = 0;
	//旋转k次
	for (i = 0; i < k; i++)
	{
		//每次旋转一个字符
		char tmp = *str;
		int len = strlen(str);
		int j = 0;
		for (j = 0; j < len - 1; j++)
		{
			*(str + j) = *(str + j + 1);
		}
		*(str + len - 1) = tmp;
	}
}

思路2:
左旋k个字符,我们只需要分三步走即可:
第一步,逆置第1个字符到第k个字符之间的字符
第二部,逆置第k+1个字符到最后1个字符之间的字符
第三步,逆置第1个字符至最后一个字符,即整体逆置一遍

#include<stdio.h>
#include<string.h>
void reverse(char* left, char* right)
{
	while (left < right)
	{
		char temp = *right;
		*right = *left;
		*left = temp;
		left++;
		right--;
	}
}

void leftMove(char* str, int k)
{ 
	int len = strlen(str);
	k %= len;
	reverse(str, str + k - 1);
	reverse(str+k, str + len-1);
	reverse(str, str + len-1);
}

int main()

{
	char str[] = "ABCD";
	int k = 0;
	scanf("%d", &k);
	leftMove(str, k);
	printf("%s\n", str);

	return 0;
}

其它

如果元素取值与数组下标有关系,可将元素存在数组中,方便存取。

比如1月31 天,2月28/29天,3月31天…。月份的天数和月份1,2,3,4…相关,即与数组下标相关,故我可以将月份的天数存储在数组中:

int arr[12] = {31,28,31,30,31,30,31,30,30,31,30,31}

那么1月份的天数就是arr[0],2月份的天数就是arr[1]…

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

重要思想总结 的相关文章

随机推荐

  • Windows更新CUDA

    经过整整一天的奋战 终于成功更新了CUDA 特此记录一下这个艰难的过程 最最最先要确定的是 你的电脑得是支持GPU的 一 查看电脑现存CUDA版本 电脑搜索NVIDIA 在出现的页面中的左下角点击 系统信息 出现以下界面 可以看到驱动版本是
  • LXC 3.0交叉编译

    LXC交叉编译 代码下载 git clone https github com lxc lxc git 代码文件编译 编写交叉编译文件 host machine system linux cpu family arm cpu arm end
  • redis的持久化和主从复制

    什 么是redis持久化 redis作为一个键值对内存数据库 nosql 数据存储在内存当中 在处理客户端请求时 所有操作都是在内存当中运行 问题 存储在内存中的数据 只要服务器关机 内存中的数据就会消失 不仅服务器关机会造成数据消失 re
  • VMware虚拟机安装Linux系统

    文章目录 前言 一 Linux是什么 二 安装步骤 1 新建虚拟机 2 安装CentOS 7 总结 前言 之前使用VMware虚拟机安装了Windows系统 本文讲的是使用VMware虚拟机安装Linux系统 提示 以下是本篇文章正文内容
  • Modbus通信协议详解

    一 Modbus 协议简介 Modbus 协议是应用于电子控制器上的一种通用语言 通过此协议 控制器相互之间 控制器经由网络 例如以太网 和其它设备之间可以通信 它已经成为一通用工业标准 有了它 不同厂商生产的控制设备可以连成工业网络 进行
  • APPCAN + wampserver 实现简单的个人登录功能

    开发背景 Appcan wampserver 其中wampserver主要用于提供本地服务器和数据库 这是软件开发工程这门课中的一个大作业 需要实现 1 首页 index html 首页包含 滚动图片 新闻列表和导航栏 首页内容通过Requ
  • 用python编写递归爬取多重网址的网站信息

    项目组要得到这个http kalug linux org tw shawn project thesis 目录网址下面的所有文件以及这个文件目录的下层目录以及更下层目录的文件包括这个 用迅雷 flashget好像都没这样的功能 找到给一个链
  • 经过两天的折腾,我终于写成了我的第一个flutter app程序,差点把我折磨精神崩溃了

    最近看头条 天天给我推送flutter 说flutter如何好 如何先进 如何简单 忍不住诱惑我就练练试试吧 没想到掉到了一个无底大坑 其实flutter语言本身挺简单方便 编安卓程序也很容易 关键是搭建环境和编译程序极其困难 中间各种bu
  • javascript复制到剪切板

    一 这是一个复制方法 复制到剪切板 param text returns Promise
  • 区块链技术医疗卫生领域运用综述————医药供应链(2019年4月份)

    区块链技术医疗卫生领域运用综述 医药供应链 FJTCM区块链技术开发学习小组 时间 2019 04 24 目录 摘要 1 Abstract 2 引言 3 一 医药冷链物流现状分析 4 1 发展机遇 4 2 存在的问题
  • unity,如何通过协程,将物体的颜色逐渐变浅,慢慢消失

    介绍 unity 如何通过协程 将物体的颜色逐渐变浅 慢慢消失 方法 IEnumerator Stop while sprite color a gt 0 sprite color new Color sprite color r spri
  • 论文笔记:CVPR 2022 Cross-Domain Adaptive Teacher for Object Detection

    摘要 我们解决了对象检测中的域适应任务 其中有注释的源域和没有注释的感兴趣的目标域之间存在域间隙 注 在一个数据集上训练模型 再另外一个数据集上进行预测性能下降很大 在一个数据集上训练好的模型无法应用在另一个数据集上 作为一种有效的半监督学
  • opencv轻松入门面向pythonpdf下载_小白入门到大佬都在看的Python电子书奉上!最好用的PDF...

    关注 转发 最后私信小编 资料 即可获取小编准备的pythonPDF资料啦 电子版的哦 只赠送前500位哦 书籍简介 像计算机科学家一样思考Python 第2版 本书以培养读者以计算机科学家一样的思维方式来理解Python语言编程 贯穿全书
  • sqlmap工具学习记

    学习时间2022 7 20 既要不辜负别人也要对得起自己 1 python2 7版本下载安装 因为sqlmap依赖环境是2 7所以我们下载2 7版本 进入下载官网Download Python Python org 选择你要下载的版本 选择
  • python爬虫之JS混淆加密、字体反爬

    1 JS混淆加密 我们之前爬取有道翻译的翻译内容时 我们通过fiddler抓取url地址时 我们发现如果我们直接将相关参数传入 会报错 只是因为 某些参数是变化的 因此 我们需要解读JS文件 取得相关参数的生成算法 利用python生成参数
  • 电流源等效噪声公式

  • 华为OD机试真题-单词倒序【2023Q1】【JAVA、Python、C++】

    题目描述 输入单行英文句子 里面包含英文字母 空格以及 三种标点符号 请将句子内每个单词进行倒序 并输出倒序后的语句 输入描述 输入字符串S S的长度1 N 100 输出描述 输出逆序后的字符串 补充说明 标点符号左右的空格 0 单词间空格
  • obb vtk 定点坐标_vtk学习笔记 --- 显示坐标系

    有的时候 在显示三维物体时 我们希望知道当前场景对应的坐标系位置或者方向 这样在旋转物体的时候 就能够很清楚地看到当前正对这视野的是什么面xy平面 还是y轴等信息了 在vtk库中有一个vtkAxesActor负责显示坐标系 在查阅了vtk的
  • OpenMAX学习资料收集

    OpenMAX框架拆解与实现 OpenMax OMX 开发入门 OpenMax人口 OpenMAX IL spec手册下载 https www khronos org files openmax il spec 1 0 pdf OpenMA
  • 重要思想总结

    重要思想总结 求二进制序列中1的个数 检测num中某一位是0还是1 不创建临时变量交换值 判断数值的位数 判断数值的位数 获取数值的每一位数 把一个整数的二进制位的奇数位和偶数位交换 将个位数 十位数 百位数 组成一个完整的数 找素数 将秒