【C++】B2093 查找特定的值


在这里插入图片描述

博客主页: [小ᶻ☡꙳ᵃⁱᵍᶜ꙳]
本文专栏: C++

文章目录

  • 💯前言
  • 💯题目描述
    • 输入格式
    • 输出格式
    • 输入输出示例
  • 💯题目分析与解题思路
  • 💯代码实现与对比分析
    • 我的实现代码
    • 老师的实现代码
    • 详细对比与分析
      • 1. 数组的定义方式
      • 2. 遍历与查找逻辑
      • 3. 输出逻辑
  • 💯最终优化实现
  • 💯扩展与深入
    • 1. 时间与空间复杂度分析
    • 2. 常见错误与调试技巧
    • 3. 拓展问题
  • 💯小提示:数组操作注意事项
  • 💯小结


在这里插入图片描述


💯前言

  • 在编写程序时,数组是最常用的数据结构之一。我们常常需要对数组进行遍历、查找或操作,而在竞赛和算法题中,数组的用法更加广泛。本次讨论的题目是关于数组中查找特定值的经典问题,它不仅考察基本的数组操作,还涉及对程序逻辑和优化的理解。在本文中,我们将详细解读题目,分析不同的解法及其优劣,并从多个角度拓展与优化。
    C++ 参考手册
    在这里插入图片描述

💯题目描述

B2093 查找特定的值
在这里插入图片描述

在一个序列(下标从 0 开始)中查找一个给定的值,输出第一次出现的位置。

输入格式

  1. 第一行包含一个正整数 n n n,表示序列中元素个数。
    • 1 ≤ n ≤ 10 , 000 1 \leq n \leq 10,000 1n10,000
  2. 第二行包含 n n n 个整数,依次给出序列中的每个元素,两个整数之间用单个空格隔开。
    • 元素的绝对值不超过 10,000。
  3. 第三行包含一个整数 x x x,为需要查找的特定值。
    • x x x 的绝对值不超过 10,000。

输出格式

若序列中存在 x x x,输出 x x x 第一次出现的下标;否则输出 −1。

输入输出示例

输入:

5
2 3 6 7 3
3

输出:

1

输入:

5
1 2 3 4 5
6

输出:

-1

通过题目的描述,我们知道其核心目标是找到某个值在数组中的第一个下标(从 0 开始),并返回其位置,或在数组中不存在时返回 -1。


💯题目分析与解题思路

题目看似简单,但要在限定条件下写出清晰高效的代码,需要我们认真思考以下问题:

  1. 输入处理:如何处理并存储数组和目标值?

    • 输入数据的长度 n n n 和数组中的每个元素需要正确存储。
    • 对目标值 x x x 的查找需要考虑数组的遍历顺序。
  2. 逻辑设计:

    • 遍历数组时如何判断目标值是否存在?
    • 如果找到目标值,应如何处理下标?
    • 如果找不到,如何设计合理的输出逻辑?
  3. 代码的优化:

    • 如何避免数组越界?
    • 如何提升代码的清晰度和运行效率?

接下来我们将详细分析两个解法——我的实现与老师的实现,并逐步优化。


💯代码实现与对比分析

我的实现代码

#include <iostream>
using namespace std;int main()
{int n;cin >> n;int arr[n];for(int i = 0; i < n; i++){cin >> arr[i];}int m, find = 0;int index = 0;cin >> m;for (int a : arr){if(a == m){find++;cout << index << endl;break;}index++;    }if(find == 0)cout << -1 << endl;return 0;    
}

在这里插入图片描述

老师的实现代码

#include <iostream>
using namespace std;const int N = 10010; // 定义数组最大长度为 10010
int arr[N]; // 静态数组int main()
{int n = 0;cin >> n; // 输入数组长度for (int i = 0; i < n; i++) // 输入数组内容{cin >> arr[i];}int k = 0;cin >> k; // 输入需要查找的目标值int i = 0;for (i = 0; i < n; i++) // 遍历数组{if (k == arr[i]) // 如果找到目标值{cout << i << endl; // 输出目标值的下标break; // 跳出循环}}if (i == n) // 如果没有找到cout << -1 << endl;return 0;
}

在这里插入图片描述

详细对比与分析

1. 数组的定义方式

  • 我的代码:

    int arr[n];
    
    • 使用动态数组,大小正好为 n n n
    • 优点:节省内存,仅分配实际需要的空间。
    • 缺点:在旧版本 C++ 标准中,动态数组 int arr[n] 不被支持,可能出现兼容性问题。
  • 老师的代码:

    const int N = 10010;
    int arr[N];
    
    • 使用静态数组,大小固定为 10010。
    • 优点:兼容性更好,保证了程序稳定运行,避免数组越界。
    • 缺点:在实际使用中可能浪费部分内存。

优化建议:如果使用现代 C++ 标准(如 C++11 及之后),推荐使用 std::vector 代替静态或动态数组。


2. 遍历与查找逻辑

  • 我的代码:

    for (int a : arr)
    {if(a == m){find++;cout << index << endl;break;}index++;    
    }
    
    • 使用了范围 for 循环,语法简洁。
    • 设置了额外变量 find 作为标志位。
    • 优点:代码较为现代化,适合用 std::vector
    • 缺点:find 变量是多余的,完全可以通过循环的控制逻辑避免。
  • 老师的代码:

    for (i = 0; i < n; i++) // 遍历数组
    {if (k == arr[i]) // 如果找到目标值{cout << i << endl; // 输出目标值的下标break; // 跳出循环}
    }
    if (i == n) // 如果没有找到cout << -1 << endl;
    
    • 使用经典 for 循环,判断循环变量是否超出范围。
    • 优点:逻辑直观,不需要额外标志位。
    • 缺点:需要检查 i == n,稍显冗余。

优化建议:使用 return 提前退出,可以进一步简化逻辑。


3. 输出逻辑

  • 我的代码:

    if(find == 0)cout << -1 << endl;
    
    • 使用 find 标志判断是否输出 -1
  • 老师的代码:

    if (i == n)cout << -1 << endl;
    
    • 直接通过循环变量判断是否找到。

优化建议:结合遍历逻辑,直接在找到目标值时退出程序,减少多余检查。


💯最终优化实现

以下是结合两者优点并优化后的代码:

#include <iostream>
#include <vector>
using namespace std;int main()
{int n;cin >> n;vector<int> arr(n); // 动态数组for (int i = 0; i < n; i++) {cin >> arr[i];}int k;cin >> k;for (int i = 0; i < n; i++) {if (arr[i] == k) {cout << i << endl; // 输出下标return 0; // 找到后直接退出程序}}cout << -1 << endl; // 未找到return 0;
}

在这里插入图片描述

改进点总结:

  1. 使用现代 C++ 的 std::vector 代替普通数组,动态管理内存,安全高效。
  2. 遍历时直接通过 return 提前退出,逻辑更加简洁。
  3. 减少多余变量 find 和冗余检查,代码更加紧凑。

💯扩展与深入

1. 时间与空间复杂度分析

  • 时间复杂度:

    • 本题的核心逻辑是对数组的线性遍历,时间复杂度为 O ( n ) O(n) O(n)
    • 在最坏情况下(目标值不在数组中),需要遍历整个数组。
  • 空间复杂度:

    • 如果使用静态数组,空间复杂度为 O ( n ) O(n) O(n)
    • 如果使用动态数组(如 std::vector),额外的空间开销也为 O ( n ) O(n) O(n)

2. 常见错误与调试技巧

  • 数组越界:

    • 确保数组的大小正确定义,避免访问未分配的内存。
    • 在循环遍历时,条件应严格限制在数组范围内。
  • 输入边界情况:

    • 测试输入数组为空(即 n = 0 n=0 n=0)。
    • 测试目标值位于数组的开头和结尾。

3. 拓展问题

  • 变体问题:
    • 如果需要查找所有出现目标值的位置,可以将下标存入一个结果数组。
    • 如果需要返回目标值的最后一次出现位置,可以反向遍历数组。

💯小提示:数组操作注意事项

  1. 下标管理:

    • 有些题目要求从下标 0 开始存储数据,有些则从下标 1 开始。需要注意开辟足够的空间,避免数组越界。
    • 如果题目要求从下标 1 开始,可以额外分配一个位置,比如 int arr[n+1],让下标 0 空出。
  2. 预留空间:

    • 数组空间的开辟建议留出额外的空间,防止越界。例如,当需要存储 n n n 个数据时,预留 n + 10 n+10 n+10 空间。浪费一点内存通常不会对性能产生太大影响,但能提高程序安全性。
  3. 局部数组与全局数组:

    • 局部数组存储在栈区,空间有限,定义过大的局部数组可能导致栈溢出。对于较大的数组,建议使用全局数组(存储在静态区)或者动态数组(如 std::vector)。

💯小结

本文通过一个经典的数组查找问题,分析了不同实现方案及其优化方法。通过对代码逻辑、时间复杂度和空间复杂度的全面解析,我们总结出以下关键点:

  1. 清晰的逻辑是解决问题的基础。
  2. 代码优化应注重减少冗余逻辑,提升效率。
  3. 扩展与思考能帮助我们从更多维度理解问题。

在这里插入图片描述


在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述

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

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

相关文章

计算机网络:网络层知识点及习题(一)

网课资源&#xff1a; 湖科大教书匠 1、概述 网络层实现主机到主机的传输&#xff0c;主要有分组转发和路由选择两大功能 路由选择处理机得出路由表&#xff0c;路由表再生成转发表&#xff0c;从而实现分组从不同的端口转发 网络层向上层提供的两种服务&#xff1a;面向连接…

CDP集群安全指南-动态数据加密

[〇]关于本文 集群的动态数据加密主要指的是加密通过网络协议传输的数据&#xff0c;防止数据在传输的过程中被窃取。由于大数据涉及的主机及服务众多。你需要更具集群的实际环境来评估需要为哪些环节实施动态加密。 这里介绍一种通过Cloudera Manager 的Auto-TLS功能来为整个…

Swift Protocols(协议)、Extensions(扩展)、Error Handling(错误处理)、Generics(泛型)

最近在学习 Swift&#xff0c;总结相关知识 1. Protocols&#xff08;协议&#xff09; 1.1 协议的定义和实现 协议&#xff08;protocol&#xff09; 是一种定义方法和属性的蓝图&#xff0c;任何类、结构体或枚举都可以遵循协议。遵循协议后&#xff0c;需要实现协议中定义…

uni-app开发-习惯养成小程序/app介绍

目录 一:功能概述 二:功能部分代码和截图 一:功能概述 1 习惯目标生成 创建习惯:用户可以添加新的习惯目标,每个习惯可以包含名称、描述、图标、目标天数。 关联习惯完成:用户通过设定达成目标以后,生成习惯养成记录。 2 习惯打卡 简单快捷的打卡:提供一个直观的界面…

【HTML】Day02

【HTML】Day02 1. 列表标签1.1 无序列表1.2 有序列表1.3 定义列表 2. 表格标签2.1 合并单元格 3. 表单标签3.1 input标签基本使用3.2 上传多个文件 4. 下拉菜单、文本域5. label标签6. 按钮button7. div与span、字符实体字符实体 1. 列表标签 作用&#xff1a;布局内容排列整齐…

基于Spring Boot的车辆违章信息管理系统(LW+源码+讲解)

专注于大学生项目实战开发,讲解,毕业答疑辅导&#xff0c;欢迎高校老师/同行前辈交流合作✌。 技术范围&#xff1a;SpringBoot、Vue、SSM、HLMT、小程序、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、安卓app、大数据、物联网、机器学习等设计与开发。 主要内容&#xff1a;…

Git - 记录一次由于少输入了一个命令导致的更改丢失

Git - 记录一次由于少输入了一个参数导致的更改丢失 前言 某晚我激情开发了几个小时&#xff0c;中途没有进行commit存档。准备睡觉时&#xff0c;我想创建一个新的分支并将今晚所有更改提交到新分支上&#xff08;似乎应该开发时候就创建&#xff1f;&#xff09;。 然后因…

探索Rust在Web开发中的实际应用

近年来&#xff0c;Rust语言因其高性能、内存安全性和强大的工具链支持而迅速崛起。在Web开发领域&#xff0c;Rust提供了一套高效、现代化的框架和工具&#xff0c;使得开发者能够构建快速、安全的Web应用程序。在本文中&#xff0c;我们将深入探讨如何使用Rust进行Web开发&am…

Apache Celeborn 在B站的生产实践

背景介绍 Shuffle 演进 随着B站业务的飞速发展,数据规模呈指数级增长,计算集群也逐步从单机房扩展到多机房部署模式。多个业务线依托大数据平台驱动核心业务,大数据系统的高效性与稳定性成为公司业务发展的重要基石。如图1,目前在大数据基础架构下,我们主要采用 Spark、Fl…

第29天:Web开发-PHP应用弱类型脆弱Hash加密Bool类型Array数组函数转换比较

#知识点 1、安全开发-原生PHP-弱类型脆弱 2、安全开发-原生PHP-函数&数据类型 3、安全开发-原生PHP-代码审计案例 一、PHP弱类型对比 1、 和 两个等号是弱比较&#xff0c;使用进行对比的时候&#xff0c;php解析器就会做隐式类型转换&#xff0c;如果两个值的类型不相等就…

Kafaka安装与启动教程

1.下载 先去官网Apache Kafka可以查看到每个版本的发布时间。选择你要安装的版本。 然后进入linux建立要存放的文件夹&#xff0c;用wget命令下载 2.安装 先解压缩&#xff1a; tar -xvzf kafka_2.12-3.5.1.tgz -C ../ 3.配置文件 修改server.properties&#xff1a; cd .…

回归预测 | MATLAB实ELM-Adaboost多输入单输出回归预测

回归预测 | MATLAB实ELM-Adaboost多输入单输出回归预测 目录 回归预测 | MATLAB实ELM-Adaboost多输入单输出回归预测预测效果基本介绍程序设计参考资料 预测效果 基本介绍 一、极限学习机&#xff08;ELM&#xff09; 极限学习机是一种单层前馈神经网络&#xff0c;具有训练速…

1、pycharm、python下载与安装

1、去官网下载pycharm 官网&#xff1a;https://www.jetbrains.com/pycharm/download/?sectionwindows 2、在等待期间&#xff0c;去下载python 进入官网地址&#xff1a;https://www.python.org/downloads/windows/ 3、安装pycharm 桌面会出现快捷方式 4、安装python…

GESP2023年12月认证C++五级( 第三部分编程题(1)小杨的幸运数)

参考程序&#xff1a; #include <iostream> #include <cmath> using namespace std;int nextPerfectSquare(int a) {int sqrt_a (int)sqrt(a);if (sqrt_a * sqrt_a < a) {sqrt_a; // 如果 sqrt(a) 的平方小于 a&#xff0c;那么就需要加 1&#xff0c;找到下…

25年1月更新。Windows 上搭建 Python 开发环境:Python + PyCharm 安装全攻略(文中有安装包不用官网下载)

引言 随着 Python 在数据科学、Web 开发、自动化脚本等多个领域的广泛应用&#xff0c;越来越多的开发者选择它作为首选编程语言。而 PyCharm 作为一个功能强大的集成开发环境&#xff08;IDE&#xff09;&#xff0c;为 Python 开发者提供了极大的便利。本文将详细介绍如何在 …

IDEA配置maven和git并如何使用maven打包和git推送到gitlab

首先找到设置 在里面输入maven然后找到点击 然后点击右边两个选项 路径选择下载的maven目录下的settings文件和新建的repository文件夹 点击apply应用 然后在搜索框里搜git点击进去 此路径为git的exe执行文件所在目录&#xff0c;选好之后点击test测试下方出现git版本号表…

【Rust 知识点杂记】

1、self和Self 在Rust中&#xff0c;self 和 Self 有不同的含义和用法&#xff0c;它们通常出现在结构体、枚举或实现&#xff08;impl&#xff09;块的上下文中。 self: self 是一个关键字&#xff0c;它代表方法调用时实例本身的引用。当在一个方法定义中使用 self 作为第一…

【Vue学习】Vue 组件实例的生命周期(四个阶段,八个钩子)

一、为什么要理解生命周期&#xff1f; 理解生命周期就像是知道了一部电影的剧情走向&#xff0c;能让你在适当的时机做出反应。Vue 生命周期的钩子让你可以在不同的阶段插入你的逻辑&#xff0c;像是提前准备、后期清理或者在数据更新时做点事情。这种“精确控制”的能力会让你…

【Vue】<script setup>和 <script>区别是什么?在使用时的写法区别?

<script setup> 是 Vue 3 引入的一种新的脚本语法&#xff0c;它提供了一种更简洁和声明式的方式来编写组件逻辑。它是为了解决传统 <script> 标签在 Vue 单文件组件&#xff08;SFC&#xff09;中的一些局限性而设计的。 <script setup> 与 <script>…

Kotlin 数据类与密封类

Kotlin 数据类与密封类 引言 在 Kotlin 中&#xff0c;数据类和密封类是两种非常重要的类类型&#xff0c;它们各自具有独特的用途和优势。数据类主要用于存储数据&#xff0c;而密封类则用于表示受限的类层次结构。在本篇文章中&#xff0c;我们将深入探讨 Kotlin 中的数据类…