【卡码网Python基础课 16.出现频率最高的字母】

目录

  • 题目描述与分析
    • 描述
    • 2.分析
  • 一、哈希表
  • 二、代码编写


题目描述与分析

描述

题目描述:
给定一个只包含小写字母的字符串,统计字符串中每个字母出现的频率,并找出出现频率最高的字母,如果最高频率的字母有多个,输出字典序靠前的那个字母。

输入描述
包含多组测试数据,每组测试数据占一行。

输出描述
有多组输出,每组输出占一行。

输入示例:

2
abcdeef
aabbccddeeff

输出示例:

e
a

2.分析

之前学习的数组(列表)、字符串、链表等数据结构,如果想找到其中某个元素或某个节点,需要从索引为0的位置或者链表头节点开始,逐一进行比较,直到找到相等的位置或者末尾才会结束。

要想避免之前的比较,直接通过查找记录找到存储位置可以通过哈希表来实现。哈希表是根据关键码key的值而直接进行访问的数据结构。

哈希表的作用是快速判断一个元素是否出现在集合里,它的核心思想是在关键码和存储位置之间建立一个确定的对应关系f, 使得每个关键字key对应一个存储位置,而这个对应关系,称之为散列函数(哈希函数)。

其实数组(列表)就是一张哈希表,哈希表中关键码就是数组(列表)的索引下标,然后通过下标直接访问数组(列表)中的元素。

哈希表来解决问题的时候,一般选择以下三种数据结构:
数组(列表)
集合
映射

一、哈希表

哈希表(也称为散列表)是一种使用哈希函数组织数据以支持快速插入和搜索的数据结构。哈希表在平均时间复杂度上提供快速的数据访问,通常为O(1)。哈希表通过将键通过哈希函数转换为数组索引来直接访问内存存储位置。

哈希表的原理:
哈希表的核心是哈希函数,它将输入(通常是键)转换为一个整数,这个整数则被用作数组的索引。理想情况下,哈希函数应该将键均匀分布在哈希表的索引中,但实际上总会有一些碰撞(即不同的键产生相同的索引)。

处理哈希表中的碰撞有几种常见的方法:

1.开放寻址(Open Addressing):当发生碰撞时,通过某种探测方法(如线性探测、二次探测或双重哈希)寻找另一个空槽来存储值。
2.链表法(Chaining):每个数组索引处存储一个指向键和值列表(通常是链表)的指针。如果多个键映射到相同的索引,它们都可以存储在这个位置的列表中。

在Python中,字典(dict)是哈希表的一种实现。Python的字典允许以键值对的形式存储数据,其中键必须是不可变类型,如整数、浮点数、字符串或元组。

# 创建一个字典
my_dict = {'apple': 'red', 'banana': 'yellow', 'cherry': 'red'}# 访问字典
print(my_dict['apple'])  # 输出: red# 添加一个新的键值对
my_dict['orange'] = 'orange'# 检查键是否存在
if 'banana' in my_dict:print("Banana is in the dictionary.")# 遍历字典
for key, value in my_dict.items():print(f"{key}: {value}")# 删除一个元素
del my_dict['cherry']

哈希表可以将其比喻为一个大抽屉,抽屉里面有很多小格子。每个格子可以用来存放一些东西。

抽屉编号: 抽屉有编号,这个编号就是数据的key,我们通过这个key来找到对应的抽屉。
散列函数: 哈希表使用一种特殊的函数(哈希函数),来决定数据应该放在哪个抽屉里。这个函数将数据的名字key转换成一个数字,然后根据这个数字来选择一个抽屉。
抽屉里的物品: 在每个抽屉里,可以放一些东西,这些东西就是我们要存储的数据。
解决冲突: 有时候不同的key经过散列函数后可能会得到相同的编号,这就是冲突。哈希表有方法来处理这些冲突。
快速查找: 当我们需要找到某个数据时,哈希表可以通过名字key快速地找到对应的抽屉,然后取出里面的数据,这个操作非常快速,就像从抽屉中拿出东西一样。

二、代码编写

首先,需要接收整数 n 的输入,表示共有 n 行测试数据 ,然后进行 n 次循环迭代,接收一行字符串作为输入, 将字符串经过处理后,统计输出最高频率的字母。

# n 表示
n = int(input())for _ in range(n):s = input()

统计字符串中各个字符的频率可以定义一个长度为26的列表,列表的元素代表着各位字符的频率,初始频率都为0,列表的索引 0 对应着字符 a, 索引 1 对应着字符 b, 依次类推,索引 25 对应着 字母 z。

然后遍历整个字符串,如果遇到字符 a, 则对应的 索引0 的元素值 + 1, 表示频率 + 1,当字符串遍历完毕,各个字符的频率也都统计完毕了。

示例图如下:在 字符串 "abceef"当中,字符 a 对应索引0,所在位置元素的值为1,字符 b、c、f类似,字符 e 对应索引 4, 所在位置元素的值为2,表示频率为2。
在这里插入图片描述
当字符串遍历过程中,假设 char 表示当前字符,只需要计算 ord(char) - ord(‘’)就可以计算出当前字符和字符 'a’之间的 Unicode 码值,这个差值就是列表元素的索引。

假设字符 char 为’a’, ord(‘a’) - ord(‘a’)为 0, 索引 0 所在的位置的计数 + 1,假设字符 c 为’b’, ord(‘b’) - ord(‘a’)的值为 1,索引 1 所在的位置的计数 + 1,其他字符依次类推。

# 列表复制,将 0 这个元素复制了26次,从而创建了包含26个 0 的列表
temp = [0] * 26
# 遍历字符串    
for char in s:# ord(char) - ord('a') 表示当前字符和字符'a'之间的 Unicode码值,也是对应列表的索引a = ord(char) - ord('a')# tem[索引]处的值 + 1temp[a] += 1

经过一轮遍历之后已经完成统计,数组中各位的元素已经是a-z字母的频次了,但是如果想要找到最大值,还是需要重新遍历一遍,那我们如何找到这个最大值呢?

这需要先初始化一个字符的最大出现频率,然后头开始遍历,逐一比对当前字符出现的频次和最大频率的大小,如果当前字符出现的频次大于最大值,则更新最大值为当前字符出现的频次,这样完整遍历一遍后,就能找到字符的最大出现频率。

# 初始化字符的最大出现频率为0
maxFreq = 0
# 循环迭代处理列表中的其他字符
for i in range(26):# 如果当前字母的出现频率大于 maxFreqif temp[i] > maxFreq:# 更新 maxFreq 为当前字母的出现频率maxFreq = temp[i]

但是上面的操作只统计了最大频率,并没有记录最大频率所在的索引i

maxFreq = 0
# 在还没有遍历temp列表之前,不知道哪个字符是出现频率最高的,用-1来表示“尚未找到”。
maxFreqChar = -1for i in range(26):# 如果当前字母的出现频率大于 maxFreqif temp[i] > maxFreq:maxFreq = temp[i]# 记录当前字母的索引maxFreqChar = i

当循环结束后,已经找到出现频率最大字符的频次以及对应的索引i,将 'a’对应的 Unicode 码值 加上 索引值,就是出现频率最大的字符的 Unicode 码值,再经过chr()函数转换,就能得到最终的结果。

# ord('a') + maxFreqChar 表示 出现频率最大的字符的 Unicode 码值
# chr() 将 Unicode 码值转为对应的字符
res = chr(ord('a') + maxFreqChar)
print(res)

本道题的完整代码如下:

n = int(input())for _ in range(n):s = input()# 创建一个 长度为26,元素都为0的列表temp = [0] * 26for char in s:# 计算字符在列表中对应的索引a = ord(char) - ord('a')# 索引对应的值 + 1temp[a] += 1maxFreq = 0maxFreqChar = -1# 遍历列表,找到最大频率字符的索引for i in range(26):if temp[i] > maxFreq:maxFreq = temp[i]# maxFreqChar为对应的索引maxFreqChar = i# 根据索引转换对应的字符res = chr(ord('a') + maxFreqChar)print(res)

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

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

相关文章

Nginx--虚拟机配置

前言:本博客仅作记录学习使用,部分图片出自网络,如有侵犯您的权益,请联系删除 1、什么是虚拟主机 虚拟主机是一种特殊的软硬件技术,它可以将网络上的每一台计算机分成多个虚拟主机,每个虚拟主机可以独立对…

字符串函数!!!(续)(C语言)

一. strtok函数的使用 继续上次的学习,今天我们来认识一个新的函数strtok,它的原型是char* strtok(char* str,const char* sep),sep参数指向了一个字符串,定义了用作分隔符的字符合集,第一个参数指定⼀个字符串&#…

基于C# winform部署图像动漫化AnimeGANv2部署onnx模型

【界面截图】 【效果演示】 【部分实现代码】 using System; using System.Diagnostics; using System.Windows.Forms; using OpenCvSharp;namespace FIRC {public partial class Form1 : Form{Mat src null;public Form1(){InitializeComponent();}private void button1_Cli…

消息系统-WebSocket消息推送

消息系统-WebSocket消息推送 接口层使用消息通知 1.数据库设计: 1.消息通知表 2.消息记录表 3.用户表和角色表及用户角色记录表 2.设计: 未使用消息中间件 ,利用接口层调用消息通知接口工具类 3.前端:消息通知页面 1.消息通知列表 2.消息通知标签 3.消息通知未读抽屉列表 一.…

Ubuntu离线安装库并解决依赖关系

(1)起因 安装插件出现库未找到的错误 configure: error: curses library is required but not found.(2)解决方法 手动到Ubuntu的库发布网页下载 http://packages.ubuntu.com/ 选择系统对应架构的版本下载,然后上传…

django(REST_FRAMEWORK)+swagger+Apifox 集成

1.reset_framework 1.1安装rest_framework 1.2使用rest_framework 在django框架中setting文件中注册rest_framework INSTALLED_APPS [rest_framework, ]2.reset_frameworkswagger 2.1.安装drf_yasg 2.2.在django框架中setting文件中注册drf_yasg INSTALLED_APPS [drf_…

滴滴开源新项目Unify:聚焦Flutter与原生通信难题,助力跨端应用落地

引言 在移动开发领域,移动跨端技术因其提效收益,逐渐成为业界趋势之一。Flutter 作为近年来热门的跨端技术,以高性能、自渲染、泛跨端著称,得到广泛应用。在滴滴国际化业务中,我们大量应用 Flutter。目前已在滴滴国际化…

【大模型部署及其应用 】RAG检索技术和生成模型的应用程序架构:RAG 使用 Meta AI 的 Llama 3

目录 RAG检索技术和生成模型的应用程序架构1. **基本概念**2. **工作原理**3. **RAG的优势**4. **常见应用场景**5. **RAG的挑战**6. **技术实现**参考RAG 使用 Meta AI 的 Llama 3亲自尝试运行主笔记本与文档应用聊天关键架构组件1. 自定义知识库2. 分块3. 嵌入模型4. 矢量数据…

PHP多商家营销活动平台系统小程序源码

解锁营销新境界!「多商家营销活动平台」让你的品牌火出圈✨ 🚀【聚合力量,共创辉煌】🚀 在这个竞争激烈的市场中,单打独斗早已不是最佳选择!「多商家营销活动平台」横空出世,它像一座桥梁&…

关于Python3项目中依赖包管理问题

背景:最近在使用Python3.11编写脚本来获取google play中app的用户评论,脚本中需要安装多个依赖包,在本地Pycharm调试通过以后,上传到github,然后在linux服务器拉取脚本来运行,发现存在几个问题。本文将面临…

Qt登录窗口设计

widget.h #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QIcon> //图标类 #include <QPushButton> #include <QLineEdit> //行编辑 #include <QLabel> #include <QTextEdit> #include <QMovie>class Widge…

django中的MESSAGE组件

文章目录 message组件1 使用配置2 设置值3 读取值4 源码分析 message组件 1 使用配置 INSTALLED_APPS [# django.contrib.admin,# django.contrib.auth,# django.contrib.contenttypes,# django.contrib.sessions,django.contrib.messages,django.contrib.staticfiles,"…

vuex的原理和使用方法

简介 Vuex 是 Vue.js 应用的状态管理模式&#xff0c;它为应用内的所有组件提供集中式的状态&#xff08;数据&#xff09;管理。可以帮我们管理 Vue 通用的数据 (多组件共享的数据)。 Vuex的构成 state&#xff1a;state 是 Vuex 的数据中心&#xff0c;也就是说state是用来…

修改系统启动环境变量

修改系统启动环境变量 查看uboot默认env 首先连接好开发板的串口终端&#xff0c;在开发板上后&#xff0c;一直快速短按 空格键 即可进入 uboot的 shell 交互命令行内。在命令行内输入 print 命令&#xff0c;可以看到当前系统的所有环境变量。 > print aw-ubi-spinand…

[DL]深度学习_针对图像恢复的高效扩散模型DiffIR

DiffIR: Efficient Diffusion Model for Image Restoration Abstract 扩散模型(DM)通过将图像合成过程建模为去噪网络的顺序应用&#xff0c;实现了SOTA的性能。然而&#xff0c;与图像合成不同的是&#xff0c;图像恢复(IR)对生成符合ground-truth的结果有很强的约束。因此&am…

【Linux基础】Linux中的开发工具(1)--yum和vim

目录 ✈️前言一&#xff0c;Linux 软件包管理器 yum1. 什么是软件包2. 如何安装软件3. 如何卸载软件 二&#xff0c;Linux编辑器-vim使用1. vim的基本概念1.1 命令/正常/普通模式1.2 插入模式1.3 底行模式 三&#xff0c;vim命令模式命令集1. 移动光标2. 删除字符3. 复制4. 替…

用python制作88键赛博钢琴(能用鼠标键盘进行弹奏)

用python制作88键赛博钢琴 前言 恭喜这位博主终于想起了自己的账号密码&#xff01; 时光荏苒&#xff0c;转眼间已逾一年未曾在此留下墨香。尽管这一年间&#xff0c;博主投身于无尽的忙碌与挑战之中&#xff0c;但令人欣慰的是&#xff0c;那份初心与热情似乎并未因岁月的流…

Django后台数据获取展示

​ 续接Django REST Framework&#xff0c;使用Vite构建Vue3的前端项目 1.跨域获取后台接口并展示 安装Axios npm install axios --save 前端查看后端所有定义的接口 // 访问后端定义的可视化Api接口文档 http://ip:8000/docs/ // 定义的学生类信息 http://ip:8000/api/v1…

Ubuntu下交叉编译器工具链的安装方法

本篇文章记录Ubuntu下交叉编译器工具链的安装方法。 目录 一、交叉编译器 1、交叉编译器简介 2、获取交叉编译器 3、安装交叉编译器 4、安装相关库 二、结语 一、交叉编译器 1、交叉编译器简介 交叉编译器是一种编译器&#xff0c;它在一种平台上运行&#xff0c;但生成…

如何获取VS Code扩展的版本更新信息

获取VS Code 扩展的版本更新的需求 因为企业内部有架设私有扩展管理器的要求&#xff0c;但是对于一些官方市场的插件&#xff0c;希望可以自动获取这些扩展的更新并上传至私有扩展管理器。于是就有了本篇介绍的需求&#xff1a; 通过API的方式获取VS Code 扩展的更新。 关于…