力推C语言必会题目终章(完结篇)

news2024/11/14 16:29:57

W...Y的主页 😊

代码仓库分享 💕

今天是分享C语言必会题目最终章,全部都是硬货,大家都坐好准备开始喽!!!

编写一个函数,计算字符串中含有的不同字符的个数。字符在 ASCII 码范围内( 0~127 ,包括 0 和 127 ),换行 表示结束符,不算在字符里。不在范围内的不作统计。多个相同的字符只计算一次

例如,对于字符串 abaca 而言,有 a、b、c 三种不同的字符,因此输出 3 。

数据范围: 0 <= n <= 500

输入描述:输入一行没有空格的字符串。

输出描述:输出 输入字符串 中范围在(0~127,包括0和127)字符的种数。

OJ链接【牛客网题号: HJ10 字符个数统计】

示例: 输入:abc 输入:aaa

            输出:3 输出:1


这道题非常简单,ASCII码的范围为127,我们只需要创建一个char类型的数组进行全部初始化为0,然后将字符作为数组下标在数组中进行标记,若数组中没有标记过表示第一次出现,进行计数,否则表示重复字符。

示例:查表法, "aaa" ,首先把a字符( ascii 值为 97 )作为下标,将标记数组的第 97 位置 1 ,下次如果还有 a 字符出 现,到下标 'a' 或者 97 的位置一看是1就表示a已经统计过了,使用if进行判断即可成功。

下面为代码实现:

#include <stdio.h>

int main() {
    char tmp[501] = {0};
    while(scanf("%s", tmp) != EOF)
    {
        char mark[128] = {0};
        int count = 0;
        char *ptr = tmp;
        while(*ptr)
        {
            if(mark[*ptr] != 1)
            {
                count++;
            }
            mark[*ptr] = 1;
            ptr++;
        }
        printf("%d\n", count);
    }
    return 0;
}

给定一个大小为 n 的数组,找到其中的多数元素。多数元素是指在数组中出现次数 大于 ⌊ n/2 ⌋ 的元素。 你可以假设数组是非空的,并且给定的数组总是存在多数元素。

OJ链接【 leetcode 题号:169. 多数元素】 

示例 1:

输入:nums = [3,2,3]
输出:3

示例 2:

输入:nums = [2,2,1,1,1,2,2]
输出:2
提示:

n == nums.length 

1 <= n <= 5 * 104

进阶:尝试设计时间复杂度为 O(n)、空间复杂度为 O(1) 的算法解决此问题。


解法一:

首先我们得清楚这个数组中一定会有一个元素出现次数大于等于n/2,所以当我们排序后再取中间的元素返回一定是多数元素。(只需要极少量的代码即可完成)

时间复杂度O(nlogn),空间复杂度O(1)。

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

int compar(const void* p1, const void* p2)
{
	return *(int*)p1 - *(int*)p2;
}


int majorityElement(int* nums, int numsSize){
    qsort(nums, numsSize,sizeof(int), compar);
    
    return nums[numsSize / 2];
}

进阶解法二:

一个数组中有一个数字出现次数大于 n/2 ,从第 0 个字符开始,假设它就是最多的那个数字,遇到相同的数字则 计数 +1 , 遇到不同的则计数 -1 ,其实就是互相消耗,等到计数为 0 的时候,表示本次互拼完毕,从下一个字符重 新开始互拼,但是归根结底出现次数大于 n/2 的这个数字数量更多,因此也是最后保留的字符。

示例: "23335" 首先从字符 2 开始计数 1 ,遇到 3 ,不同则 -1 ,互拼消耗 重新从剩下的 "335" 开始的过程,这时 候保存的字符为 3 ,遇到 3 则计数 +1 , 遇到5则计数 -1 ,在计数不为 0 时,走到末尾保存的字符就是个数超过 n/2 的字符。

这种方法不容易被想到,但是优化了时间复杂度。

int majorityElement(int* nums, int numsSize){
    int count = 1;
    int tmp = nums[0];
    for(int i = 1; i < numsSize; i++)
    {
            if(tmp == nums[i])
            {
                count++;
            }
            else
            {
                count--;
            }
            if(count == 0)
            {
                tmp = nums[i+1];
            }
    }
    return tmp;
}

 写一个函数,求两个整数之和,要求在函数体内不得使用+、-、*、/四则运算符号。

数据范围:两个数都满足 0≤n≤1000

OJ链接【牛客网题号: JZ65 不用加减乘除做加法】     

进阶:空间复杂度 O(1),时间复杂度O(1)   

示例: 输入:1,2 返回值:3


十进制相加思想: 15+07 , 先计算不考虑进位的相加结果 12 (因为 5+7 的不考虑进位的结果是 2 ,遇 10 进位 嘛),然后计算进位 5+7 进位是 10 ,则 10 与 12 再次相加,得到 22 ,进位为 0 ,则计算到此结束。

这里使用二进制求和完成,思想类似,但是二进制计算相加和进位不需要使用 + 符号

二进制相加思想:与十进制相同,先计算不考虑进位的相加结果( 0+0 得 0 , 1+1 进位得 0 , 1+0 得 1 ),使用 异或可以取得; 然后计算相加的进位结果(同 1 的位置左移一位即可),使用相与后左移取得。

示例:

5   0101 + 7   0111 不考虑进位的相加结果 0101^0111 -> 0010 相加的进位 0101&0111 -> 0101 因为进位左移得到 1010

1010 + 0010 不考虑进位的相加结果 1010 ^ 0010 -> 1000 相加的进位 1010 & 0010 -> 0010 因为进位左移得到 0100

1000 + 0100 不考虑进位的相加结果 1000 ^ 0100 -> 1100 相加的进位 1000 & 0100 -> 0000 进位为0结束运算。

int Add(int num1, int num2 ) {
   int sum = 0;
   while(num2 != 0)//进位不为0则持续与相加结果进行相加
   {
    sum = num1 ^ num2;//进位不为0则持续与相加结果进行相加
    num2 = (num1 & num2) << 1;//同1的位相加则会进位
    num1 = sum;
   }

   return num1;
}

 1、给定一个二进制数组, 计算其中最大连续 1 的个数。

OJ链接【 leetcode 题号:485. 最大连续 1 的个数】

示例: 输入:[1,1,0,1,1,1] 输出:3

解释:开头的两位和最后的三位都是连续 1 ,所以最大连续 1 的个数是 3.


这道题思路比较简单,统计连续1的个数,遇到0时表示连续中断,判断如果当前的统计数大于之前最大的则替换, 然后继续下一个位置开始的统计即可。

int findMaxConsecutiveOnes(int* nums, int numsSize){
    int max = 0;
    int count = 0;
    for(int i = 0; i < numsSize; i++)
    {
        if(nums[i] == 1)
        {
            count++;
            if(max < count)
            {
                max = count;
            }
        }
        else
        {
            count = 0;
        }
    }
    return max;
}

求输出n以内(含n)完全数的个数。完全数(Perfect number),又称完美数或完备数,是一些特殊的自然数。 它所有的真因子(即除了自身以外的约数)的和(即因子函数),恰好等于它本身。

例如:28,它有约数1、2、4、7、14、28,除去它本身28外,其余5个数相加,1+2+4+7+14=28。

注意:本题输入含有多组样例。

输入描述:输入一个数字n 输出描述:输出不超过n的完全数的个数

OJ链接【牛客网题号: HJ56 完全数计算】

示例: 输入:1000 7 100 输出:3 1 2


这道题的关键在于完全数的判断:完全数指的是一个数字的所有约数的和和自身相等。我们只需要从 1 开始将这个 数的约数相加求和即可。

约数就是能够被数字整除,而这里简化的一个思路是数字能够被整除,则除数和结果就都是约数,这种思路下,只 需要从1计算到平方根即可

比如:数字 8 , 能够整除 2 ,结果是 4 ,则除数 2 和结果 4 都是约数,而这两个只需要一次计算判断即可。

需要注意的是 4,9,25... 这种,除数和结果相同的情况,则除数或者结果只相加一次就够了。

#include <stdio.h>
#include<math.h>
int is_perfect_num(int num)
{
int sum = 1;
for (int i = 2; i <= sqrt(num); i++) {
if (num % i == 0) {//判断是否能够整除i,能整除则i和结果都是约数
sum += i; //与除数相加
if (i != sqrt(num))//防止除数和结果相同的情况下重复相加
sum += num / i; //与相除结果相加
}
}
if (sum == num) return 1;
return 0;
}
int main()
{
int n;
while(~scanf("%d", &n)){
int count = 0;
for(int i = 2; i <= n; i++) {//对n以内的数字都进行判断是否是完全数,注意1不参与判断
if (is_perfect_num(i)) count++;
}
printf("%d\n", count);
}
return 0;
}

数列的定义如下:数列的第一项为n,以后各项为前一项的平方根,求数列的前m项的和。 输入描述: 输入数据有多组,每组占一行,由两个整数 n(n<10000) 和 m(m<1000) 组成,n和m的含义如前所述。

输出描述: 对于每组输入数据,输出该数列的和,每个测试实例占一行,要求精度保留2位小数。

OJ链接【牛客网题号: ZJ16 数列的和】 

输入:

81 4
2 2

输出:

94.73
3.41

求取一个数字的平方根可以使用数学库中的 double sqrt(double num) 函数完成,接下来只需要从数字自身开始进行 求和并在求和后将 n 自身计算成为自身的平方根即可。

#include <stdio.h>
#include<math.h>
int main() {
    double m, n;
    while(scanf("%lf %lf", &n, &m) != EOF)
    {
        double sum = 0;
        while(m-- > 0)
        {
            sum +=n;
            n = sqrt(n);
        }
        printf("%.2lf\n",sum);
    }
    return 0;
}

现在有一个长度为 n 的正整数序列,其中只有一种数值出现了奇数次,其他数值均出现偶数次,请你找出那个 出现奇数次的数值。

输入描述:第一行:一个整数n,表示序列的长度。第二行:n个正整数ai,两个数中间以空格隔开。

输出描述:一个数,即在序列中唯一出现奇数次的数值。

OJ链接【牛客网题号: KS33 寻找奇数】

示例: 输入:5 2 1 2 3 1 输出:3


异或:二进制比特位相同则0, 不同则1.

异或法:两个相同的数字异或得到的是0, 基于这个思路,这道题对数组中的所有数据进行逐一异或就可以解决得到奇数次 的数字,因为偶数次的数字都被异或成为0了,最后单独保留了奇数次的数字。

#include <stdio.h>

int main() {
    int n;
    while(~scanf("%d", &n))
    {
        int num = 0, tmp = 0;
        //对每个数字进行异或,出现偶数次的就会异或为0了,而奇数次刚好剩下的就是对应数字
        for (int i = 0; i < n; i++)
         {
            scanf("%d", &tmp);
            num ^= tmp;
        }
        printf("%d\n", num);
    }
    return 0;
}

给定一个长度为n的数组 nums ,请你找到峰值并返回其索引。数组可能包含多个峰值,在这种情况下,返回任 何一个所在位置即可。

1.峰值元素是指其值严格大于左右相邻值的元素。严格大于即不能有等于

2.假设 nums[-1] = nums[n] = 负无穷小

3.对于所有有效的 i 都有 nums[i] != nums[i + 1]

OJ链接【牛客网题号: NC107 寻找峰值】

示例: 输入:[2,4,1,2,7,8,4] 返回值:1

说明:4和8都是峰值元素,返回4的索引1或者8的索引5都可以

输入:[5,3,4,2,6] 返回值:0

说明:-1作为下标或者n下标位置都表示负无穷小, 则0号下标5是峰值,或者4号下标6也是峰值


方法一:

先将数组中首位进行特殊处理,如果满足题中要求直接返回对应下标,如果不满足条件只需要判断数组中当前元素与下一个元素大小即可,如果当前元素大于下一元素则返回当前元素下标即可,反之则继续循环。

int findPeakElement(int* nums, int numsLen ) {
    if (numsLen == 1 || nums[0] > nums[1]) 
        return 0;
    if (nums[numsLen-1] > nums[numsLen-2]) 
        return numsLen-1;
        int a = 0;
    for(int i = 1; i < numsLen-1; i++)
    {
        if(nums[i] > nums[i+1])
        {
            a = i;
            break;
        }
    }
    return a;
}

方法二:

二分思想,中间比右边大,认为从右往左半边递增,则把 right 不断向左靠拢 right=mid ,注意不能是 mid-1 ,因为这个位置有 可能就是峰值点。

直到遇到中间比右边小了,意味着数据开始递降了,则 left 向右偏移, left=mid+1 ; 而一旦 mid+1 位置大于了 right ,意味着刚好这个 mid+1 位置,是一个左半边-右往左递降,右半边-右往左递增的点,就是一个峰值点。

示例: int arr[] = {3, 5, 4, 4, 3, 2, 1} , 这个数组中两边边界都是非峰值点

int left = 0, right = 6;

left=0,right=6,mid=3: arr[3]=4 > arr[4]=3, 则right = mid = 3; //从右往左是递增的 left=0,right=3,mid=1: arr[1]=5 > arr[2]=4, 则right = mid = 1; //从右往左是递增的 left=0,right=1,mid=0: arr[0]=3 < arr[1]=5, 则left = mid + 1 = 1; //从右往左开始递降了

left > right 退出循环, 返回left,也就是1号下标位置。

代码实现:

int findPeakElement(int* nums, int numsLen ) {
    if (numsLen == 1 || nums[0] > nums[1]) 
        return 0;
    if (nums[numsLen-1] > nums[numsLen-2]) 
        return numsLen-1;
    int left = 0, right = numsLen - 1, mid;
    while(left < right) {
        mid = left + (right - left) / 2;
        if (nums[mid] < nums[mid + 1])//中间比右边小,意味着右边肯定有个峰值
            left = mid + 1;
        else //否则在左边包括当前位置肯定有个峰值
            right = mid;
    }
    return left;
}

 以上是本次C语言必会题目,都是些非常经典的内容,希望博主的分享对你们有帮助。

你们的支持是博主最大的动力,谢谢观看!!!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/888045.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【深入理解Linux内核锁】三、原子操作

我的圈子: 高级工程师聚集地 我是董哥,高级嵌入式软件开发工程师,从事嵌入式Linux驱动开发和系统开发,曾就职于世界500强企业! 创作理念:专注分享高质量嵌入式文章,让大家读有所得! 文章目录 1、原子操作思想2、整型变量原子操作2.1 API接口2.2 API实现2.2.1 原子变量结…

国家一带一路和万众创业创新的方针政策指引下,Live Market探索跨境产业的创新发展

现代社会&#xff0c;全球经济互联互通&#xff0c;跨境产业也因此而崛起。为了推动跨境产业的创新发展&#xff0c;中国政府提出了“一带一路”和“万众创业、万众创新”的方针政策&#xff0c;旨在促进全球经济的互联互通和创新发展。在这个大环境下&#xff0c;Live Market积…

【24择校指南】华东师范大学计算机考研考情分析

华东师范大学(B) 考研难度&#xff08;☆☆☆☆&#xff09; 内容&#xff1a;23考情概况&#xff08;拟录取和复试分数人数统计&#xff09;、院校概况、23考试科目、23复试详情、各科目及专业考情分析。 正文2563字&#xff0c;预计阅读&#xff1a;3分钟。 2023考情概况…

Springboot 集成Beetl模板

一、在启动类下的pom.xml中导入依赖&#xff1a; <!--beetl模板引擎--><dependency><groupId>com.ibeetl</groupId><artifactId>beetl</artifactId><version>2.9.8</version></dependency> 二、 配置 beetl需要的Beetl…

【Java转Go】快速上手学习笔记(二)之基础篇二

【Java转Go】快速上手学习笔记&#xff08;二&#xff09;之基础篇一 了解了基本语法、基本数据类型这些使用&#xff0c;接下来我们来讲数组、切片、值传递、引用传递、指针类型、函数、泛型、map、结构体。 目录 数组和切片值传递、引用传递指针类型defer延迟执行函数泛型ma…

c++通过gsop调用基于https的webservice接口总结

ww哦步骤&#xff1a; 第一步&#xff1a;生成头文件 webservice接口一般会有一个对外接口文档。比如&#xff1a;http://www.webxml.com.cn/WebServices/WeatherWebService.asmx?WSDL 问号后面的参数表示WSDL文档&#xff0c;是一个XML文档&#xff0c;看不懂配置没关系&a…

UglifyJS 和JShaman相比有什么不同?都可以进行js混淆加密吗?

UglifyJS 和JShaman相比有什么不同&#xff1f; UglifyJS主要功能是压缩JS代码&#xff0c;减小代码体积&#xff1b;JShaman是专门用于对JS代码混淆加密&#xff0c;目的是让JS代码变的不可读、混淆功能逻辑、加密代码中的隐秘数据或字符&#xff0c;是用于代码保护的。 因此…

linux两台服务器互相备份文件(sshpass + crontab)

crontab crontab是linux系统自带的定时调度软件&#xff0c;可用于设置周期性被执行的指令&#xff0c;一般用在每天的非高峰负荷时间段运行作业&#xff0c;可在无需人工干预的情况下运行作业。支持在一周或一月中的不同时段运行。 crontab命令允许用户提交、编辑或删除相应的…

【HBZ分享】java中的BitSet 与 Redis中的BitMap 与 布隆过滤器

BitMap的存储原理 bitMap他会标识出某个整数是否存在&#xff0c;存在即为1&#xff0c;不存在对应位即为0bitMap是存储int类型的&#xff0c;int 4byte&#xff0c; 1byte 8bit&#xff0c;因此bitMap数组中的每个下标可以标识出32个数字是否存在bitMap相当于一个个小格子&…

【数据结构】二叉树的链式结构的实现 -- 详解

一、前置说明 在学习二叉树的基本操作前&#xff0c;需先要创建一棵二叉树&#xff0c;然后才能学习其相关的基本操作。为了降低大家学习成本&#xff0c;此处手动快速创建一棵简单的二叉树&#xff0c;快速进入二叉树操作学习。 typedef char BTDataType;typedef struct Binar…

管理类联考——逻辑——真题篇——按知识分类——汇总篇——一、形式逻辑——模态——-句式转换+性质

文章目录 第三节 模态命题-句式转换性质题-模态命题-句式转换性质-句式转换-逻辑转换&#xff1a;①不一定不可能&#xff1b;②不一定可能不未必。句式转换-语文转换&#xff1a;①一定不可能不必然&#xff1b;②一定不不可能必然不。性质-两命题间的关系-包含&#xff1a;①…

c语言——计算两个数的乘积

//计算两个数的乘积 #include<stdio.h> #include<stdlib.h> int main() {double firstNumber,secondNumber,product;printf("两个浮点数&#xff1a;");scanf("%lf,%lf",&firstNumber,&secondNumber);productfirstNumber*secondNumber…

shell scripts 学习记录

shell scripts 学习记录 1. 环境变量的使用2. Shell中的数组使用Array关联数组 (理解为python中的字典) 3. shell中的基本运算符4. shell 中流程控制语法case...esac使用 5. 函数定义与调用5.1 带返回值的函数5.2 带传参数的函数 6. shell 中的输入/输出重定向6.1 输出重定向6.…

糖尿病视网膜病变,黄斑病变,年龄相关检测研究(Matlab代码)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

sCrypt于8月12日在上海亮相BSV数字未来论坛

2023年8月12日&#xff0c;由上海可一澈科技有限公司&#xff08;以下简称“可一科技”&#xff09;、 临港国际科创研究院发起&#xff0c;携手美国sCrypt公司、福州博泉网络科技有限公司、复旦大学区块链协会&#xff0c;举办的BSV数字未来论坛在中国上海成功落下帷幕。 本次…

好消息!多地明确鼓励提取公积金作首付

大家好&#xff01; 我是老洪&#xff0c;看到一则公积金资讯&#xff0c;聊两句。 据媒体报道&#xff0c;多地明确鼓励提取公积金作首付。 我个人觉得鼓励提取公积金作首付&#xff0c;对于购房者来说挺好的。 这种做法不仅可以减轻首付资金压力&#xff0c;还可以提高购房者…

出现丢包问题的情况以及解决方法

为什么会出现丢包&#xff1f; 我们在网络上传输数据的时候&#xff0c;数据需要经过很多的路由器/交换机&#xff08;交通枢纽&#xff09;进行传输&#xff0c;而路由器/交换机的结构是很复杂的&#xff0c;传输的数据量也是不确定的&#xff0c;可能这一会传输的数据比较少&…

mysql 03.查询(重点)

先准备测试数据&#xff0c;代码如下&#xff1a; -- 创建数据库 DROP DATABASE IF EXISTS mydb; CREATE DATABASE mydb; USE mydb;-- 创建student表 CREATE TABLE student (sid CHAR(6),sname VARCHAR(50),age INT,gender VARCHAR(50) DEFAULT male );-- 向student表插入数据…

vscode用ssh远程连接linux

1、vscode是利用ssh远程连接linux的&#xff0c;所以首先确保vscode已经安装了这两个插件 2、点击左下角的连接 3、选择Connect to Host…… 5、按格式输入 ssh 主机名ip 比如我的&#xff1a;ssh mnt192.168.198.128 6、选择第一个打开配置文件&#xff0c;确保输入正确 7、…

el-table :span-method合并单元格

2023.8.17今天我学习了如何使用el-table进行单元格的合并&#xff0c;效果如下&#xff1a; 在开发的过程中&#xff0c;如果有多个重复的值&#xff0c;我们希望可以进行合并显示&#xff0c;这样就不会显得重复太多&#xff0c;el-table有自带的方法&#xff1a; Element - …