【C语言经典例题】——程序员必须会的经典基础例题(三)

这篇具有很好参考价值的文章主要介绍了【C语言经典例题】——程序员必须会的经典基础例题(三)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

关于C语言的一些基础经典题目放在专栏:[C语言刷题]
小菜坤日常上传gitee代码:https://gitee.com/qi-dunyan
❤❤❤
个人简介:双一流非科班的一名小白,期待与各位大佬一起努力!
推荐网站:cplusplus.com
【C语言经典例题】——程序员必须会的经典基础例题(三)

1、杨辉三角

首先我们要知道什么是杨辉三角,如下:
【C语言经典例题】——程序员必须会的经典基础例题(三)
思路:
我们可以看到,三角的两边都是1,并且从第二行(从0开始算)开始,两边之间的数字,都是上一行的两位数字之和,比如第三行的数字3,等于上一行的1+2,等等。如此,把它看成一个二维数组,便可直接入手

#include<stdio.h>
//     1
//    1 1
//   1 2 1
//  1 3 3 1
// 1 4 6 4 1
int main()
{
	int arr[10][10] = { 0 };
	int i = 0;
	int j = 0;
	int n = 0;
	scanf("%d", &n);
	for (i = 0; i < n; i++)
	{
		for (j = 0; j <= i; j++)
		{
			//第0列都是1
			if (j == 0)
				arr[i][j] = 1;
			//每一行的最后一列也都是1
			if (i == j)
				arr[i][j] = 1;
			//其余的就=上一行的两位数之和
			if (i >= 2 && j < i && j>0)
				arr[i][j] = arr[i - 1][j] + arr[i - 1][j - 1];
		}
	}
	//打印空格
	for (i = 0; i < n; i++)
	{
		//先打印这一行的空格
		for (j = 0; j < n - i; j++)
		{
			printf(" ");
		}
		//然后打印这一行的数字
		for (j = 0; j <= i; j++)
		{
			printf("%d ", arr[i][j]);
		}
		//换行
		printf("\n");
	}
	return 0;
}

【C语言经典例题】——程序员必须会的经典基础例题(三)

2、有序序列合并

输入两个升序排列的序列,将两个序列合并为一个有序序列并输出。
数据范围: 1≤n,m≤1000 , 序列中的值满足 0≤val≤30000
输入描述:
输入包含三行第一行包含两个正整数n, m,用空格分隔。n表示第二行第一个升序序列中数字的个数,m表示第三行第二个升序序列中数字的个数。
第二行包含n个整数,用空格分隔。
第三行包含m个整数,用空格分隔。
输出描述:
输出为一行,输出长度为n+m的升序序列,即长度为n的升序序列和长度为m的升序序列中的元素重新进行升序序列排列合并。

方法一:题目没有考虑到时间复杂度,这里最简单粗暴的就是将两次输入的数据放在一个m+n的数组里,然后再进行冒泡排序。如下:

#include <stdio.h>
//有序序列合并
//把两次输入的都放到同一个数组,然后对它进行冒泡排序
int main()
{
    int n = 0;
    int m = 0;
    scanf("%d %d", &n, &m);
    int arr[2000];
    int i = 0;
    int j = 0;
    for (i = 0; i < n; i++)
    {
        scanf("%d", &arr[i]);
    }
    //下标从n开始,一直到n+m-1,一共m个元素
    for (i = n; i < m + n; i++)
    {
        scanf("%d", &arr[i]);
    }

    //冒泡排序//趟数
    for (i = 0; i < n + m; i++)
    {
        for (j = 0; j < n + m - 1 - i; j++)
        {
            //两两相邻元素比较
            if (*(arr + j) > *(arr + j + 1))
            {
                int min = *(arr + j + 1);
                *(arr + j + 1) = *(arr + j);
                *(arr + j) = min;
            }
        }

    }
    //打印
    for (i = 0; i < m + n; i++)
    {
        printf("%d ", *(arr + i));
    }
    return 0;
}

方法二:分别存放在两个数组里,然后进行比较,将数据小的元素输出,然后下标++,但是需要考虑到两种特殊情况,就是一个数组已经输出完了,另一个还没输出完,完整实现代码如下:

#include<stdio.h>

int main()
{
	int n = 0;
	int m = 0;
	int arr1[1000];
	int arr2[1000];
	int i = 0;
	int j = 0;
	scanf("%d %d", &n, &m);
	for (i = 0; i < n; i++)
	{
		scanf("%d", &arr1[i]);
	}
	for (j = 0; j < m; j++)
	{
		scanf("%d", &arr2[j]);
	}
	i = 0, j = 0;
	while (i < n && j < m)
	{
		//输出小的
		if (arr1[i] < arr2[j])
		{
			printf("%d ", arr1[i]);
			i++;//下标++继续比较
		}
		else if (arr1[i] >= arr2[j])
		{
			printf("%d ", arr2[j]);
			j++;//++继续比较
		}
	}
	//当i==n时,说明arr1已经输出完了,直接把剩下的arr2输出即可
	if (i == n)
	{
		for (; j < m; j++)
		{
			printf("%d ", arr2[j]);
		}
	}
	//j==m时,说明arr2已经输出完了,直接把剩下的arr1输出即可
	else if (j == m)
	{
		for (; i < n; i++)
		{
			printf("%d ", arr1[i]);
		}
	}
	return 0;
}

两种方法都可以实现,方法一思路简单,直接粗暴的解决,方法二的时间复杂度要低于方法一,因此,假如考虑到时间复杂度的情况下,方法二优先。

3、有序序列插入一个数

题目:有一个有序数字序列,从小到大排序,将一个新输入的数插入到序列中,保证插入新数后,序列仍然是升序。
输入描述:
第一行输入一个整数(0≤N≤50)。
第二行输入N个升序排列的整数,输入用空格分隔的N个整数。
第三行输入想要进行插入的一个整数。
输出描述:
输出为一行,N+1个有序排列的整数。

思路:最简单的思路就是与上面相同,将插入的数放在同一个数组,然后直接qsort或者冒泡排序,简单粗暴。这里我采用了qsort(不会的或者已经遗忘的老铁可以去前面的文章复习一下)

#include<stdio.h>
#include<stdlib.h>
//比较
int cmp(const void* e1, const void* e2) {
    return *(int*)e1 - *(int*)e2;
}
//打印
void print(int* arr, int N) {
    int i = 0;
    for (i = 0; i <= N; i++) {
        printf("%d ", arr[i]);
    }
}

int main() 
{
    int arr[50] = { 0 };
    int N = 0;
    int i = 0;

    scanf("%d", &N);
    for (i = 0; i < N; i++) {
        scanf("%d", &arr[i]);
    }
    scanf("%d", &arr[N]);
    //qsort排序
    qsort(arr, N+1, sizeof(arr[0]), cmp);
    print(arr, N);
    return 0;
}

4、调整奇数偶数顺序

题目:
输入一个整数数组,实现一个函数,
来调整该数组中数字的顺序使得数组中所有的奇数位于数组的前半部分
所有偶数位于数组的后半部分

思路:这里题目没有说要保持相对位置不变,所以我们只需要将偶数与奇数分离即可
定义两个指针,一个指向首元素地址,另一个指向末元素地址
在有效范围内,一个从前往后找,找到偶数停止,另一个从后往前,直到找到奇数停止
当两者都停止时交换位置,继续循环
如下图(p1<p2)
【C语言经典例题】——程序员必须会的经典基础例题(三)
代码实现:

#include<stdio.h>
void swap(int* arr, int sz)
{
	int left = 0;
	int right = sz - 1;
	while (left < right)
	{
		//从前往后,找到偶数停止
		while ((left < right) && (*(arr + left) % 2 == 1))
		{
			left++;
		}
		//从后往前,找到奇数停止
		while ((left < right) && (*(arr + right) % 2 == 0))
		{
			right--;
		}
		//两者交换
		if (left < right)
		{
			int tmp = *(arr + left);
			*(arr + left) = *(arr + right);
			*(arr + right) = tmp;
		}
	}
	//打印
	int i = 0;
	for (i = 0; i < sz; i++)
	{
		printf("%d ", *(arr + i));
	}
}

int main()
{
	int arr[] = { 1,9,80,5,4,68,78,45,2,456,5,1,3,87,9,88,51,20 };
	int i = 0;
	int sz = sizeof(arr) / sizeof(arr[0]);
	swap(arr, sz);

	return 0;
}

5、修改数字—偶数改为0,奇数改为1

小乐乐喜欢数字,尤其喜欢0和1。他现在得到了一个数,想把每位的数变成0或1。如果某一位是奇数,就把它变成1,如果是偶数,那么就把它变成0。请你回答他最后得到的数是多少。

这里我们通过实际数字进行分析,比如数字123,分析如下:
【C语言经典例题】——程序员必须会的经典基础例题(三)
代码实现:

#include <stdio.h>
#include<math.h>
int main()
{
    int n=0;
    int tmp=0;
    int sum=0;
    int cont=0;//统计位数
    scanf("%d",&n);
    do
    {
        tmp=n%10;//得到尾数
        if(tmp%2 !=0)
        tmp=(int)1*pow(10,cont);
        else
        tmp=(int)0*pow(10,cont);
        sum+=tmp;//每次相加
        cont++;
    }while(n/=10);
    //打印即可
    printf("%d",sum);
    return 0;
}

6、猜名次

5位运动员参加了10米台跳水比赛,有人让他们预测比赛结果:
A选手说:B第二,我第三;
B选手说:我第二,E第四;
C选手说:我第一,D第二;
D选手说:C最后,我第三;
E选手说:我第四,A第一;
比赛结束后,每位选手都说对了一半,请编程确定比赛的名次

思路,把所有可能都列举出来,然后挑选符合题目要求的即可

#include<stdio.h>
int main()
{
	int a = 0;
	int b = 0;
	int c = 0;
	int d = 0;
	int e = 0;
	//穷举
	for (a = 1; a <= 5; a++)
	{
		for (b = 1; b <= 5; b++)
		{
			for (c = 1; c <= 5; c++)
			{
				for (d = 1; d <= 5; d++)
				{
					for (e = 1; e <= 5; e++)
					{
						if ((b == 2) + (a == 3) == 1 &&
							(b == 2) + (e == 4) == 1 &&
							(c == 1) + (d == 2) == 1 &&
							(c == 5) + (d == 3) == 1 &&
							(e == 4) + (a == 1) == 1
							)
						{
						//所有的可能中,只有1,2,3,4,5这五个不同的排名名次,只有这个才符合答案
							if (a * b * c * d * e == 120 && a + b + c + d + e == 15)
							{
								printf("a=%d b=%d c=%d d=%d e=%d\n", a, b, c, d, e);//a=3 b=1 c=5 d=2 e=4
							}
						}
					}
				}
			}
		}
	}
	return 0;
}

【C语言经典例题】——程序员必须会的经典基础例题(三)

7、猜凶手

日本某地发生了一件谋杀案,警察通过排查确定杀人凶手必为4个嫌疑犯的一个。
以下为4个嫌疑犯的供词:
A说:不是我。
B说:是C。
C说:是D。
D说:C在胡说
已知3个人说了真话,1个人说的是假话。
现在请根据这些信息,写一个程序来确定到底谁是凶手。

与上面的题思路一样,列举所有可能,然后只会存放在一种是符合题意的

#include<stdio.h>
int main()
{
	//凶手
	char killer = '0';
	//ABCD中的一个,列举所有可能
	for (killer = 'A'; killer <= 'D'; killer++)
	{
		//有三个是真的
		if ((killer != 'A') + (killer == 'C') + (killer == 'D') + (killer != 'D') == 3)
		{
			printf("%c\n", killer); //C
		}
	}

	return 0;
}

8、字符串逆序单词并打印

将一句话的单词进行倒置,标点不倒置。比如 I like beijing. 经过函数后变为:beijing. like I
输入描述:
每个测试输入包含1个测试用例: I like beijing. 输入用例长度不超过100
输出描述:
依次输出倒置之后的字符串,以空格分割
示例1:
输入
I like beijing.
输出
beijing. like I
不使用库函数strlen等

思路:这里介绍的是三指针两次反转法,比如 I like beijing.
第一次反转(每个单词)I ekil .gnijieb
第二次反转 (整个)beijing. like I
由于这里不让用库函数,所以这里用来计算整个字符串长度的strlrn用不了,但自己可以写一个
代码实现


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

//模拟实现strlen
int is_mystrlen(const char*arr)
{
	assert(arr);
	int count = 0;
	while (*(arr++))
	{
		count++;
	}
	return count;
}
//反转
void reserve(char* left, char* right)
{
	assert(left);
	assert(right);

	while (left < right)
	{
		char tmp = *(left);
		*left = *right;
		*right = tmp;

		left++;
		right--;
	}
}

int main()
{
	char arr[101];

	gets(arr);
	//数组名首元素地址
	char* cut = arr;
	//遇到\0结束
	while (*cut)
	{
		char* star = cut;
		char* end = cut;
		while (*end != ' ' && *end !='\0')
		{
			end++;
		}
		//反转
		reserve(star, end - 1);  
		if (*end != '\0')
			cut = end + 1;
		else
			cut = end;
	}
	//计算字符串长度
	int count_ = is_mystrlen(arr);
	//反转整个字符串
	reserve(arr, arr + count_-1 );
	printf("%s", arr);
	return 0;
}

【C语言经典例题】——程序员必须会的经典基础例题(三)

9、字符串左旋

实现一个函数,可以左旋字符串中的k个字符。
例如:
ABCD左旋一个字符得到BCDA
ABCD左旋两个字符得到CDAB

思路:旋转k次,每次旋转一个字符,k取模,防止不必要的旋转
【C语言经典例题】——程序员必须会的经典基础例题(三)
代码实现:

#include<stdio.h>
#include<string.h>
void leftRound(char* src, int time)
{
	int i, j, tmp;
	int len = strlen(src);
	time %= len; //长度为5的情况下,旋转6、11、16...次相当于1次,7、12、17...次相当于2次,以此类推。
	for (i = 0; i < time; i++) //执行k次的单次平移
	{
		tmp = src[0];
		for (j = 0; j < len - 1; j++) //单次平移
		{
			src[j] = src[j + 1];
		}
		//再把头赋值到尾
		src[j] = tmp;
	}
}
int main()
{
	int k = 0;
	char arr[1000] = { 0 };
	scanf("%s %d", arr,&k);
	leftRound(arr, k);
	printf("%s", arr);

	return 0;
}

10、判断字符串旋转结果

写一个函数,判断一个字符串是否为另外一个字符串旋转之后的字符串。
例如:给定s1 =AABCD和s2 = BCDAA,返回1
给定s1=abcd和s2=ACBD,返回0.
AABCD左旋一个字符得到ABCDA
AABCD左旋两个字符得到BCDAA
AABCD右旋一个字符得到DAABC

思路:和上个题是一样的,这里把它所有旋转的可能列举出来,然后用strcmp函数进行比较即可。
代码实现:

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

int reverse(char* arr1, char* arr2)
{
	assert(arr1 && arr2);
	int len1 = strlen(arr1);
	int len2 = strlen(arr2);
	//长度不相等,肯定不是旋转后的
	if (len1 != len2)
		return 0;
	int i = 0;
	int j = 0;
	//把所有可能都旋转
	for (i = 0; i < len1; i++)
	{
		char p = *arr1;
		for (j = 0; j < len1 - 1; j++)
		{
			*(arr1 + j) = *(arr1 + j + 1);
		}
		*(arr1 + len1 - 1) = p;
		//strcmp比较字符串,==0表示相等
		if (strcmp(arr1, arr2) == 0)
		{
			//相等返回1
			return 1;
		}
	}
	//如果经历循环后还没返回,说明不相等,返回0
	return 0;
}
int main()
{
	char arr1[] = "abcdefg";
	char arr2[] = "defgabc";
	//两个字符串
	int ret = reverse(arr1, arr2);
	//返回1表示相等,可打印YES看一下
	if (ret == 1)
		printf("YES");
	else
		printf("NO");
	return 0;
}


end
生活原本沉闷。但跑起来就会有风!🌹文章来源地址https://www.toymoban.com/news/detail-413343.html

到了这里,关于【C语言经典例题】——程序员必须会的经典基础例题(三)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 「程序员必须掌握的算法」动态规划「上篇」

    动态规划 (Dynamic Programming) 是一种算法思想,用于解决一些复杂的问题。本文将介绍动态规划的分类、概念和经典例题讲解。 动态规划可以分为以下两种类型: 0/1背包问题:该问题是动态规划的一种基本类型。在背包问题中,有n个物品可以放入容量为W的背包中,每个物品有

    2024年02月07日
    浏览(52)
  • 「程序员必须掌握的算法」字典树「上篇」

    前言: 在计算机科学中,字典树(Trie)是一种有序树,用于保存关联数组(有时我们称之为“映射”或“字典”)。与二叉查找树不同,键不是直接保存在节点中,而是由节点在树中的位置决定。字典树的优势在于能够非常快速地查找、插入和删除字符串。 本篇文章将介绍字

    2024年02月07日
    浏览(68)
  • 《黑马程序员2023新版黑马程序员大数据入门到实战教程,大数据开发必会的Hadoop、Hive,云平台实战项目》学习笔记总目录

    本文是对《黑马程序员新版大数据入门到实战教程》所有知识点的笔记进行总结分类。 学习视频:黑马程序员新版大数据 学习时总结的学习笔记以及思维导图会在后续更新,请敬请期待。 前言:配置三台虚拟机,为集群做准备(该篇章请到原视频进行观看,不在文章内详细

    2024年02月03日
    浏览(62)
  • 9个程序员必须掌握的Git命令

    介绍一些非常实用的Git命令。 微信搜索关注《Java学研大本营》 Git是最常用的版本控制系统之一。然而,对于初学者来说,Git的众多命令和工作流程会让人感到困惑和棘手。在Git的世界中很容易迷失,遇到合并冲突错误和意外更改,Git对于新手来说可能真的是一场噩梦。 本文

    2024年01月21日
    浏览(57)
  • 程序员必须避免的坑:编程陷阱与最佳实践

    摘要:作为一位资深程序员,我们在编程过程中可能会遇到各种各样的陷阱。本文将详细讨论程序员在编程过程中应避免的一些常见陷阱,并提供相应的最佳实践,以帮助您提高编程效率和代码质量。 正文: 编程过程中,务必保持代码风格的一致性。这包括缩进、命名规范

    2024年02月06日
    浏览(92)
  • 程序员必须了解的 10个免费 Devops 工具

    近年来,DevOps 已经成为一门将软件开发 (Dev) 与 IT 运维 (Ops) 相融合的重要学科,目的是为了缩短软件的开发生命周期并提供高质量软件的持续交付。 这篇文章整理了十种基本的免费开源的 DevOps 工具,这些工具已经在实践中得到了证明,凭借有效性和能够简化 DevOps 流程的能

    2024年04月11日
    浏览(71)
  • 学PYTHON必须学算法吗?老程序员告诉你真相!

    通过以上所学内容大家就可以比较清楚的了解到Python编程学完可以做什么了,主要可以选择的工作我挑了以下几个介绍: (1) 大数据分析师 :基于各种分析手段对大数据进行科学分析、挖掘、展现并用于决策支持。使企业清晰的了解到现状及竞争环境。 (2) 人工智能 :

    2024年02月06日
    浏览(57)
  • 程序员必会的英语单词汇总,学习速度可提高10倍,偷偷超越你身边的大聪明

    虽然说英语不好也能学编程,但学习速度却大大减慢,尤其是到后面你要查资料或者上Github等英文网站的时候,浏览器自带的翻译还会出错。 所以我专门花了几天的时间,结合自己这些年来的开发经验,把编程常用的英语单词都做了一次全面的汇总,总共700个计算机常用的单

    2023年04月20日
    浏览(45)
  • Visual Studio 2022 程序员必须知道高效调试手段与技巧(上)

    🎬 鸽芷咕 :个人主页  🔥 个人专栏 :《C语言初阶篇》 《C语言进阶篇》 ⛺️生活的理想,就是为了理想的生活!    🌈 hello! 各位宝子们大家好啊,前面给大家介绍了Visual Studio 2022 下载与安装今天我们就来介绍一下 VS2022 最强大的功能调试?    ⛳️ 调试可以说是一个

    2024年02月15日
    浏览(37)
  • 程序员必须掌握哪些算法?——前端开发工程师需要掌握的算法

    一个程序员一生中可能会邂逅各种各样的算法,但总有那么几种,是作为一个程序员一定会遇见且大概率需要掌握的算法。作为一名前端开发工程师,今天就通过这个话题和文章来聊聊前端开发工程师需要掌握的算法有哪些呢。 算法(Algorithm) 是指解题方案的准确而完整的

    2024年02月15日
    浏览(67)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包