IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> 为暑期画上句号之C语言数学题总结 -> 正文阅读

[C++知识库]为暑期画上句号之C语言数学题总结


没有加号的相加

题目描述
写一个函数,求两个整数之和,要求在函数体内不得使用+、-、*、/四则运算符号。
牛客题目来源
分析:
不用加减法,咋做加减?
这是个好问题
这里要补充一个知识点
两个数 相 & 能够得到要 进位 的位 A
两个数相 ^ 能够达到各位相加后的没有进位的数 B
通过异或,我们是可以达到加法的目的的,前提是没有进位
那是不是一步步消除进位就好了呀
怎么消除进位呢,我们看一个例子

例子:
如果是 5+7 二进制分别为 0101 和 1001
0101 & 1001 = 0001 = 1
此时需要进位 1<<=1 == 2
0101 ^ 1001 = 1100 = 10
10+2 = 5+7
但是此时 不能直接用 ^ 得到最终结果
只要在 & 最终 为0 时,才能用 ^直接得到最终结果
还得继续
2 = 0010
10 = 1100
2&10 = 0
2^10 = 1110 = 12 = 5+7

题解和分析

int Add(int num1, int num2 ) {
    // write code here
    int a = 0;
    int b = 0;
    while(b = num1^num2,a = num1&num2)
    {
        a <<= 1;
        num1 = a;
        num2 = b;
    }
    return b;
}

总结

  1. 我总觉得这是计算机加法的本质 -
  2. 通过 & 可以得到 要进位的值然后进行进位即可, 异或 可以得到 无需进位的相加值

统计 int 补码中的1

一个数在计算机是以补码的形式存在,如何统计补码中一的个数
这里用了一个比较巧妙的方式
n&(n-1) 会清除最右边的 1

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int main()
{
	int n = -1;
	int count = 0;
	while (n)
	{
		count++;
		n &= (n - 1);
	}
	printf("%d", count);
	return 0;
}

小总结

  1. n&(n-1) 会清除最右边的 1

除自身之外的积

除自身之外的积题目力扣来源
后面的题解是提供思路,直接拿去提交是过不了的

题解和分析

要求-给定一个数组,然后求除了某个数之外的数的乘积

方法一: 遍历,每次得到某个数,再遍历,得到其余数的乘积
好处: 简单暴力,但是不能满足时间要求

方法2 :从那个数处分成两个数组,前缀积数组和后缀积数组,第一遍遍历得到 前缀积,再遍历,得到后缀积,两者相乘就是合积
在这里插入图片描述

版本1

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>

int main()
{
	int arr[4] = { 1,2,3,4 };
	int pre[4] = { 0 };
	int aft[4] = { 0 };

	int i = 0,product = 1;
	for (i = 0, product = 1; i < 4; i++)
	{
		pre[i] = product;
		product *= arr[i];
	}
	for (i = 3, product = 1; i >=0; i--)
	{
		aft[i] = product;
		product *= arr[i];
	}
	for (i = 0; i < 4; i++)
	{
		printf("%d ", pre[i] * aft[i]);
	}
	return 0;
}

分析

我们有没有必要用三个数组,用三个循环?
其实是不用的,我们借用一个前缀数组,得到前缀积,此时的数就已经能够运算了,可以少用一个 aft

版本2

只是直接利用了 原数组的空间直接接受 后缀 * 前缀的值,减少空间利用罢了

for (i = 0, product = 1; i < 4; i++)
	{
		pre[i] = product;
		product *= arr[i];
	}
	for (i = 3, product = 1; i >= 0; i--)
	{
		pre[i] *= product;
		product *= arr[i];
	}
	for (i = 0; i < 4; i++)
	{
		printf("%d ", pre[i]);
	}

摩尔投票法

要求:
给定一个数组,一定会有一个数出现大于 n/2 次, 找到这个数
分析:
找到多数元素
长度多,数据大,本来我是想着全部统计,但是显然会直接超时
这里给到一个信息,是出现次数大于 n/2 的元素,利用这个特性,思考一下
如果是n个数据 , 只有两个数 一个数大于 n/2个, 一个数小于 n/2 个
无论哪个在前,当我一个个用大于 n/2的数来抵消其他数,剩下的一定是大于 n/2的数
如何实现这个过程?
取到第一个数,一路抵消到没有,就换数,这样每个数都被逐个抵消,剩下的只能是 多数
大鱼吃小鱼,剩下的只有大鱼
寻找多数元素的题目

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int main()
{
	int nums[] = { 2,2,1,1,1,2,2 };
	int sz = sizeof(nums) / sizeof(nums[0]);
	int i = 0;
	int temp = nums[0];
	int count = 1;
	for (i = 1; i < Size; i++)
	{
		if (nums[i] == temp)
		{
			count++;
		}
		else
		{
			count--;
			if (count == 0)
			{
				temp = nums[i];
				count = 1;
			}
		}
	}
	printf("%d", temp);
	return 0;
}

珠玑妙算

珠玑妙算题目描述
题目描述:
计算机有4个槽,每个槽放一个球,颜色可能是红色(R)、黄色(Y)、绿色(G)或蓝色(B)。
例如,计算机可能有RGGB 4种(槽1为红色,槽2、3为绿色,槽4为蓝色)。
作为用户,你试图猜出颜色组合。
打个比方,你可能会猜YRGB。
要是猜对某个槽的颜色,则算一次“猜中”;要是只猜对颜色但槽位猜错了,则算一次“伪猜中”。注意,“猜中”不能算入“伪猜中”。

题目分析:
一开始看,我是一脸懵逼
首先,比较简单理解的就是,猜中,位置颜色都对就是猜中吧
那我就先把位置颜色一样的搞定,然后伪猜中的时候不管他,去掉
伪猜中怎么理解?
我们可以尝试把不是猜中的颜色按顺序编号
比如你猜的是 YRGB 实际是 RGGB
去掉猜中的 G 剩下 YR-B 和 RG-B
然后编号颜色 Y1 R1 B1 ; R1 G1 B1

然后按顺序找
猜测有R1, 实际也有 R1
猜测有B1, 实际也有 B1
就是两次伪猜测

int* masterMind(char* solution, char* guess, int* returnSize)
{
   int i = 0;
   int lens = 4;
   int *times = malloc(2*sizeof(int));
   
   for(i = 0;i<2;i++)
   {
       times[i] = 0;
   }
   //处理猜中的
   for(i = 0;i<lens;i++)
   {
       if(solution[i]==guess[i])
       {
           times[0]++;
           solution[i] = 0;
           guess[i] = 1;
       }
   }
   //处理伪猜中
   for(i = 0;i<lens;i++)
   {
       int j = 0;
       for(j = 0;j<lens;j++)
       {
           if( guess[i] == solution[j])
           {
               solution[j] = 0;// solution的消除方式
               guess[i]=1; //guess 的消除方式
               times[1]++;
           }
       }
   }
   *returnSize = 2;
   return times;
}

总结

  1. 虚心学习别人的代码,比对优化自己的代码
  2. 记住一些操作的特性 如n&(n-1) 可以消除 最右边的1
  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-09-13 10:54:41  更:2022-09-13 10:58:45 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/19 14:51:47-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码