C语言数组练习以及场景练习题

简介: C语言数组练习以及场景练习题

写了那么久的知识点梳理,今天来写点自己觉得不错的练习题来分享,顺便来巩固自己的知识点,和加强题型的解决方法的记忆。今天给大家带来的有数组的找数字题目,以及场景找凶手的题目,下面让我们来看看今天的第一道题目。


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


大家看到题目是否有了自己的思路了呢?下面我展示一下答案。

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
 
int Find_Num(int p[][4], int i, int j, int key)
{
  int x = 0;
  int y = j - 1;
  while (x < i && y < j)
  {
    if (p[x][y] > key)
    {
      y--;
    }
 
    if (p[x][y] < key)
    {
      x++;
    }
 
    if (p[x][y] == key)
    {
      return p[x][y];
    }
 
  }
 
  return 0;
 
 
 
 
}
 
 
 
 
int main()
{
  int ret = 0;
  int arr[4][4] = { {1,2,3,4},{5,6,7,8,},{11,12,13,14},{22,33,44,55} };
  int key = 0;
  
  printf("请输入你想查找的数字\n");
  scanf("%d", &key);
 
  ret=Find_Num(arr, 4, 4,key);
  if (ret != 0)
  {
    printf("数组中存在这个数字\n");
 
  }
  else
  {
    printf("数组中不存在这个数字\n");
 
  }
  return 0;
}


首先我们需要借助图来解析我的代码思路



首先我们从题目知道,矩阵的每行从左到右是递增的,矩阵从上到下是递增的,那我们先按照题目设一些值。首先我们不能从第一行第一列一个一个往下找吧,不然这样就太耗费时间了,就不符合要求了。那怎么办呢,那我们就要想到一个奇妙的位置那就是右上角的位置,为什么要这样呢?首先在这个位置上我们首先对右上角的值,例如图中的4与Key进行对比,因为key大于4,那么就是要找比4大的数,也就是往下一行进行查找,因为在4的左边的数比4还要小。这样我们就可以排除掉一行的值,在下来也类似,8比Key大那么往小里找,8往下的值比8还大,那么舍弃掉这一列。直到找到Key与p[x][y]相等为止。


所以代码中就有这么些代码:

if (p[x][y] > key)
        {
            y--;
        }
 
        if (p[x][y] < key)
        {
            x++;
        }
 
        if (p[x][y] == key)
        {
            return p[x][y];
        }


接下来我们看第二题:

一个数组中只有两个数字是出现一次,其他所有数字都出现了两次。
编写一个函数找出这两个只出现一次的数字。

例如:
有数组的元素是:1,2,3,4,5,1,2,3,4,6
只有5和6只出现1次,要找出5和6.

看过我前面的文章的是不是觉得似曾相识呢?与前面不同的是,这个题目要找的是两个数这么一看,大家能否有思路解决这道题呢。下面先展示参考答案。

FindNum(int arr[], int* num1, int* num2,int n)
{
 
  int i = 0;
  int tem=0;
  for (i = 0; i < n; i++)
  {
    tem ^= arr[i];
  }
 
  int k = 0;
  for (i = 0; i < 32; i++)
  {
    if ((tem >> i) & 1 == 1)
       k = i;
 
  }
 
 
  for (i = 0; i < n; i++)
  {
    if (((arr[i] >> k) & 1) == 1)
    {
      *num1^= arr[i];
    }
 
    else
    {
      *num2^=arr[i];
    }
  }
 
}
 
 
 
 
int main()
{
  int arr[10] = { 1,2,3,4,76,4,3,2,1,45 };
  int sz = sizeof(arr) / sizeof(arr[2]);
  int num1 = 0;
  int num2 = 0;
  FindNum(arr, &num1, &num2, sz);
  printf("%d %d", num1, num2);
 
 
  return 0;
}


这道题要解释起来,我们还是得画图来理解:


解析:首先我们如图解所说要将数分成两部分,然后需要异或操作符。我们前面将过两个公式不知道大家是否记得:

a^a=0;

0^a=a;


这两个公式就可以让我们区分一个单次出现过的数,但是这里如何将数组的数区分成两部分呢?首先我们将数组中的所有数进行异或,那么我们最终异或得到的值存到tem中,如上方:这时tem=76^45 ,那么大家仔细一想异或操作符,相异为1,这是不是就是两个数的区别了,那么这时我们就可以想一下能否从这个地方找到方法区分两个数和其他数两两分到同一部分呢。这里我们就可以从32位比特上找到tem中为1的那一个比特位,(可看下图理解)然后将数组中的所有数为1的分为一部分,为0的分为一部分,这样我们就可以将数组的数分为两部分,然后不断异或就可以得到两个数,这既是那两个数组中只出现一次的数。如图:

代码解释:

将tem进行异或后,用tem借助>>操作符找到为1的比特位,然后再用>>和^操作符进行分类,最后得到两个数,打印即可。


最后一道场景题:

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

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

A说:不是我。
B说:是C。
C说:是D。
D说:C在胡说
已知3个人说了真话,1个人说的是假话。


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


根据这个场景各位能否想到方法来找出凶手呢?下面展示参考代码:

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int main()
{
  char Killer;
 
  for (Killer = 'a'; Killer <= 'd'; Killer++)
  {
    if (((Killer != 'a') + (Killer =='c') + (Killer == 'd') + (Killer != 'd')) == 3)
    {
      break;
    }
  }
  printf("%c是凶手\n", Killer);
  return 0;
}
 


这么一看是否发现其实代码很简洁,但是这道题却很考验对代码的熟练和思维。


从题目中我们知道四个人中有一个人是凶手,所有四个人中有三个人说的话是真的,只有凶手说假的话。那么我们就需要思考出怎么在代码中确定什么时候是3个人说真话,1个人说假话得场景。


代码中我们就运用到判断语句,我们知道在C语言中判断语句中,真为1,假为0,这时我们可以根据四个人讲的话作为条件,进行判断,最后相加起来,当为3时,就是凶手,这时我们就需要代码轮番将四个人假设为凶手,那我们也要知道字符++,也是根据ASCII码值来储存,++就会得到下一个字符了。这么一解释,相信各位就已经能看懂代码了吧。

文章已到篇尾,能看到这里也谢谢您的支持了,可以的话记得三连哟。

 


目录
相关文章
|
23天前
|
传感器 算法 安全
【C语言】两个数组比较详解
比较两个数组在C语言中有多种实现方法,选择合适的方法取决于具体的应用场景和性能要求。从逐元素比较到使用`memcmp`函数,再到指针优化,每种方法都有其优点和适用范围。在嵌入式系统中,考虑性能和资源限制尤为重要。通过合理选择和优化,可以有效提高程序的运行效率和可靠性。
72 6
|
26天前
|
存储 缓存 算法
在C语言中,数据结构是构建高效程序的基石。本文探讨了数组、链表、栈、队列、树和图等常见数据结构的特点、应用及实现方式
在C语言中,数据结构是构建高效程序的基石。本文探讨了数组、链表、栈、队列、树和图等常见数据结构的特点、应用及实现方式,强调了合理选择数据结构的重要性,并通过案例分析展示了其在实际项目中的应用,旨在帮助读者提升编程能力。
52 5
|
26天前
|
存储 程序员 编译器
C 语言数组与指针的深度剖析与应用
在C语言中,数组与指针是核心概念,二者既独立又紧密相连。数组是在连续内存中存储相同类型数据的结构,而指针则存储内存地址,二者结合可在数据处理、函数传参等方面发挥巨大作用。掌握它们的特性和关系,对于优化程序性能、灵活处理数据结构至关重要。
|
1月前
|
存储 C语言 计算机视觉
在C语言中指针数组和数组指针在动态内存分配中的应用
在C语言中,指针数组和数组指针均可用于动态内存分配。指针数组是数组的每个元素都是指针,可用于指向多个动态分配的内存块;数组指针则指向一个数组,可动态分配和管理大型数据结构。两者结合使用,灵活高效地管理内存。
|
1月前
|
存储 NoSQL 编译器
C 语言中指针数组与数组指针的辨析与应用
在C语言中,指针数组和数组指针是两个容易混淆但用途不同的概念。指针数组是一个数组,其元素是指针类型;而数组指针是指向数组的指针。两者在声明、使用及内存布局上各有特点,正确理解它们有助于更高效地编程。
|
1月前
|
存储 人工智能 算法
数据结构实验之C 语言的函数数组指针结构体知识
本实验旨在复习C语言中的函数、数组、指针、结构体与共用体等核心概念,并通过具体编程任务加深理解。任务包括输出100以内所有素数、逆序排列一维数组、查找二维数组中的鞍点、利用指针输出二维数组元素,以及使用结构体和共用体处理教师与学生信息。每个任务不仅强化了基本语法的应用,还涉及到了算法逻辑的设计与优化。实验结果显示,学生能够有效掌握并运用这些知识完成指定任务。
56 4
|
2月前
|
存储 编译器 C语言
【c语言】数组
本文介绍了数组的基本概念及一维和二维数组的创建、初始化、使用方法及其在内存中的存储形式。一维数组通过下标访问元素,支持初始化和动态输入输出。二维数组则通过行和列的下标访问元素,同样支持初始化和动态输入输出。此外,还简要介绍了C99标准中的变长数组,允许在运行时根据变量创建数组,但不能初始化。
59 6
|
2月前
|
存储 人工智能 BI
C语言:数组的分类
C语言中的数组分为一维数组、多维数组和字符串数组。一维数组是最基本的形式,用于存储一系列相同类型的元素;多维数组则可以看作是一维数组的数组,常用于矩阵运算等场景;字符串数组则是以字符为元素的一维数组,专门用于处理文本数据。
|
2月前
|
存储 算法 C语言
C语言:什么是指针数组,它有什么用
指针数组是C语言中一种特殊的数据结构,每个元素都是一个指针。它用于存储多个内存地址,方便对多个变量或数组进行操作,常用于字符串处理、动态内存分配等场景。
|
2月前
|
存储 C语言
C语言:一维数组的不初始化、部分初始化、完全初始化的不同点
C语言中一维数组的初始化有三种情况:不初始化时,数组元素的值是随机的;部分初始化时,未指定的元素会被自动赋值为0;完全初始化时,所有元素都被赋予了初始值。