C语言题目练习

一、字符旋转结果

1、题目

写一个函数,判断一个字符串是否为另外一个字符串旋转之后的字符串。

例如:给定s1 =AABCD和s2 = BCDAA,返回1

给定s1=abcd和s2=ACBD,返回0.

AABCD左旋一个字符得到ABCDA

AABCD左旋两个字符得到BCDAA

AABCD右旋一个字符得到DAABC

2、思路

本题当然可以将所有旋转后的结果放到一个数组里,然后进行查找,但是这种做法既不好操作,也太费事,但是这题有一个很简单的做法:

其实ABCDE无论怎么旋,旋转后的所有结果,都包含在了ABCDEABCD这个字符串里了。所以做法很简单,只需要将原字符串再来一遍接在后面,然后找一找待查找的字符串是不是两倍原字符串的子集即可。

3、代码实现

#include"stdio.h"

#include"string.h"

int findRound(const char* src, char* find)

{

	char tmp[256] = { 0 }; //用一个辅助空间将原字符串做成两倍原字符串

	strcpy(tmp, src); //先拷贝一遍

	strcat(tmp, src); //再连接一遍

	return strstr(tmp, find) != NULL; //看看找不找得到

}

int is_left_move(char* str1, char* str2)

{

	int len1 = strlen(str1);

	int len2 = strlen(str2);

	if (len1 != len2)

		return 0;



	strncat(str1, str1, len1);

	if (strstr(str1, str2) == NULL)

		return 0;

	else

		return 1;

}

int main()

{

	char arr1[20] = "abcdef";//bcdefa cdefab defabc efabcd fabcde abcdef

	//abcdefabcdef



	char arr2[] = "cdefab";

	int ret = is_left_move(arr1, arr2);

	if (ret == 1)

		printf("Yes\n");

	else

		printf("No\n");



	return 0;

二、杨氏矩阵

1、题目

有一个数字矩阵,矩阵的每行从左到右是递增的,矩阵从上到下是递增的,请编写程序在这样的矩阵中查找某个数字是否存在。要求:时间复杂度小于O(N);

2、思路

收先我们要了解杨氏矩阵,他的特点是每行从左到右是递增的,矩阵从上到下是递增的,我们仔细分析,不难发现,对于杨氏矩阵老说,右上角和左下角的元素是有特点的。右上角的元素是一行中最大的,一列中最小的。左下角的元素是一行中最小的,是一列中最大的。所以我们可以从右上角或者左下角开始查找。比如:从右上角开始查找的时候,右上角的元素比我们要查找元素小,我们就可以去掉右上角元素所在的这一行;右上角的元素比我们要查找的元素大,我们就可以去掉右上角元素所在的这一列。然后依然找右上角的元素继续和要查找的元素与比较。这样每一次比较去掉一行或者去掉一列。这个查找效率是高于遍历数组元素的,所以时间复杂度是小于O(N),也满足题目要求

3、代码实现

#define _CRT_SECURE_NO_WARNINGS 1

#include<stdio.h>

int find(int a[3][3], int row, int col, int key)

{

	 int x = 0;

	 int y = col - 1;

	

	while (y>=0&&x<=row-1)

	{

		if (a[x][y] == key)

		{

			return 1;

		}

		else if (a[x][y] > key)

		{

			y--;

		}

		else

		{

			x++;

		}

	}

	return 0;

}

int main()

{

	int a[3][3] = { 1,2,3,4,5,6,7,8,9 };

	int ret=find(a, 3, 3, 9);

	if (ret == 1)

	{

		printf("找到了!\n");

	}

	else

	{

		printf("没找到!\n");

	}

三、猜凶手

1、题目

日本某地发生了一件谋杀案,警察通过排查确定杀人凶手必为4个嫌疑犯的一个。

以下为4个嫌疑犯的供词:

A说:不是我。

B说:是C。

C说:是D。

D说:C在胡说

已知3个人说了真话,1个人说的是假话。

现在请根据这些信息,写一个程序来确定到底谁是凶手。

2、思路

我们已知的信息:
1、A、B、C、D中一定有1个人是凶手
2、A、B、C、D中3个人说真话,1个人说假话
从以上2个信息当中,我们去确定谁是凶手,可以采用假设法。

一、假设A是凶手(A说了假话)
A说:不是我。(假)
B说:是C。 (真) ——> 凶手是C
C说:是D。 (真) ——> 凶手是D
D说:C在胡说。(真) ——> 凶手不是D
很容易看出,B、C、D产生了矛盾,所以假设不成立,即A不是凶手。

二、假设B是凶手(B说了假话)
A说:不是我。 (真)
B说:是C。 (假)
C说:是D。 (真) ——> 凶手是D
D说:C在胡说。(真) ——> 凶手不是D
C、D产生了矛盾,所以假设不成立,即B不是凶手。

三、假设C是凶手(C说了假话)
A说:不是我。 (真) ——> 凶手不是A
B说:是C。 (真) ——> 凶手是C
C说:是D。 (假) ——> 凶手不是D
D说:C在胡说。 (真) ——> 凶手不是D
刚好满足3个人说真话,1个人说假话,假设成立,即C是凶手。

为了确保万无一失,我们进行第4次假设:
四、假设D是凶手(D说了假话)
A说:不是我。 (真)
B说:是C。 (真) ——> 凶手是C
C说:是D。 (真) ——> 凶手是D
D说:C在胡说。 (假)
很明显,这里B、C也产生了矛盾,假设不成立,即D不是凶手。以上是按照离散数学的做法来思考。

我们假设,说了真话是1,说了假话是0,那么A、B、C、D 4个人说的话加起来就是1+1+1+0=3。
对A、B、C、D 4个人进行一次遍历,如果某一次4个人说的话加起来的值等于3,那么我们就找到了凶手。

3、代码实现

#include<stdio.h>

int main()

{

	int find = 0;

	for (find = 'a'; find<= 'd'; find++)

	{

		if ((find != "a") + (find == 'c') + (find == 'd') + (find != 'd') == 3)

			printf("凶手是:%c", find);

	}

	return 0;

四、杨辉三角

1、题目

在屏幕打印杨辉三角。

1

1 1

1 2 1

1 3 3 1

……

2、思路

通过观察,我们知道第一列和主对角线都是1,然后其他位置的元素都是由于这个位置的上方的元素加上左上角的元素的和即data[i][j]=data[i-1][j]+data[i-1][j-1].

3、代码实现

#include<stdio.h>



int main()

{

	int data[9][9];

	for (int i = 0; i < 9; i++)

	{

		for (int j = 0; j < 9; j++)

		{

			data[i][j] = 1;

		}

	}

	for (int i = 1; i < 9; i++)

	{

		for (int j = 1; j < i; j++)

		{

			data[i][j] = data[i-1][j]+data[i-1][j-1];

		}

	}

	for (int i = 0; i < 9; i++)

	{

		for (int j = 0; j <= i; j++)

		{

			printf("%9d", data[i][j]);

		}

		printf("\n");

	}

	

	return 0;

至此今天的学习就到此结束了,笔者在这里声明,笔者写文章只是为了学习交流,以及让更多学习C语言的读者少走一些弯路,节省时间,并不用做其他用途,如有侵权,联系博主删除即可。感谢您阅读本篇博文,希望本文能成为您编程路上的领航者。祝您阅读愉快!

  • 8
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值