小蓝正在学习一门神奇的语言,这门语言中的单词都是由小写英文字母组成,有些单词很长,远远超过正常英文单词的长度。小蓝学了很长时间也记不住一些单词,他准备不再完全记忆这些单词,而是根据单词中哪个字母出现得最多来分辨单词。
给了一个单词后,帮助他找到出现最多的字母和这个字母出现的次数。
输入描述
输入一行包含一个单词,单词只由小写英文字母组成。
对于所有的评测用例,输入的单词长度不超过1000
输出描述
输出两行:第一行包含一个英文字母,表示单词中出现得最多的字母是哪个。如果有多个字母出现的次数相等,输出字典序最小的那个。
? ? ? ? ? ? ? ? ? 第二行包含一个整数,表示出现得最多的那个字母在单词中出现的次数。
分析习题:简单暴力——直接按照题意做
要解决这个问题,可以使用一个长度为26的整型数组来记录每个字母出现的次数。数组的索引表示字母在字母表中的位置,初始值都为0。
1.读取输入的单词。?阿拉伯数字
2.遍历单词的每个字母,对应更新字母出现的次数。
3.找到出现次数最多的字母和对应的出现次数。
4.如果有多个字母出现次数相等,选择字典序最小的字母作为结果。
5.输出结果。
#include <iostream>
#include <string>
using namespace std;
int main() {
string word;//声明字符串
cin >> word;
int maxCount = 0;//出现最多次数的字母
char maxChar = 'a';//出现次数
// 'a' 遍历到字母 'z'
for (char c = 'a'; c <= 'z'; c++) {
int count = 0;//当前字母 c在单词中出现的次数
for (int i = 0; i < word.size(); i++) {
if (word[i] == c) {
count++;
}
}
//比较当前字母c的出现次数count和记录的最大次数maxCount的大小
if (count > maxCount) {
maxCount = count;
maxChar = c;
}
}
cout << maxChar << endl;
cout << maxCount << endl;
return 0;
}
上述这段代码中的"暴力"体现在双重嵌套循环的使用上。具体来说,它通过遍历字母表中的每个字母,然后在内部循环中遍历给定字符串中的每个字符,以统计每个字母在字符串中出现的次数。
这种方法被称为"暴力",是因为它通过逐个检查每个字符并计算出现次数来解决问题,而没有使用更高效的数据结构或算法来优化。
当谈到暴力算法时,它通常指的是通过穷举所有可能的解来解决问题,而不是使用更高效的优化方法。暴力算法可以看作是一种简单直接的、朴素的解决方案。
下面是一些常见的例子,展示了暴力算法的应用:
1.子集生成:给定一个集合,暴力算法会生成该集合的所有可能的子集。例如,对于一个包含 n 个元素的集合,暴力算法会生成 2^n 个子集。
#include <iostream>
#include <vector>
using namespace std;
// 生成子集的函数
vector<vector<int>> generateSubsets(vector<int>& nums)
{
vector<vector<int>> subsets; // 创建存储子集的二维向量
int n = nums.size(); // 获取原始向量的大小
for (int i = 0; i < (1 << n); i++) // 通过位运算生成子集的所有可能性
{
vector<int> subset; // 创建存储单个子集的向量
for (int j = 0; j < n; j++) //遍历原始向量的元素
{
if ((i >> j) & 1) // 判断当前位是否为1,即该元素是否属于当前子集
{
subset.push_back(nums[j]); // 将符合条件的元素加入子集向量中
}
}
subsets.push_back(subset); // 将当前子集加入所有子集的向量中
}
return subsets; // 返回所有子集的向量
}
int main() {
vector<int> nums; // 创建存储原始向量的向量
nums.push_back(1); // 向原始向量中添加元素1
nums.push_back(2); // 向原始向量中添加元素2
nums.push_back(3); // 向原始向量中添加元素3
// 调用生成子集的函数,将结果保存在二维向量中
vector<vector<int>> subsets = generateSubsets(nums);
// 使用范围-based for 循环遍历所有子集
for (const auto& subset : subsets)
{
// 使用范围-based for 循环遍历子集中的元素
for (int num : subset)
{
cout << num << " "; // 输出子集中的元素
}
cout << endl;
}
return 0;
}
?①.if ((i >> j) & 1)??这个代码的意思是看当前位是否为1,该元素是否属于当前子集
? 1)i
是一个整数,表示子集的编码。每个子集可以用一个二进制数来表示,其中每个位表示对应原始向量中的元素是否包含在子集中。
? 2)j
是一个循环变量,用于遍历每个位的位置
? 3)>>
是右移位运算符。表达式(i >> j)
?将?i
?向右移动?j
位。
? 4)&
是按位与运算符。表达式(i >> j) & 1
将右移后的结果与二进制数1
进行按位与运算。
②? ? ? for (const auto& subset : subsets)
? ?const auto& subset
:这部分声明了一个循环变量?subset
,它是一个常量引用,用于存储?subsets
中的每个元素。
? ?:?
这个冒号表示循环的开始。
? ?subsets
:这是要遍历的向量,即存储了所有子集的向量。
? ? ? ? for (int num : subset)
? ?int num
:这部分声明了一个循环变量?num
,它是一个整数,用于存储subset
中的每个元素。
? ? ? ? ?:这个冒号表示循环的开始。
? ?subset
:这是要遍历的容器,即当前子集。
2.排列组合:暴力算法可以用来生成所有可能的排列或组合。例如,在一个由 n 个元素组成的集合中,暴力算法可以生成 n!个排列。
3.搜索算法:在某些搜索问题中,暴力算法会遍历所有可能的解空间,直到找到目标解。例如,穷举搜索算法可以用于解决八皇后问题。
4.字符串匹配:在字符串匹配问题中,暴力算法会通过遍历主串和模式串的所有可能位置来查找匹配。例如,朴素的字符串匹配算法(也称为暴力算法)会检查主串中的每个位置是否与模式串完全匹配。
预告一波~明日代码讲解洛谷练习哦~
#include <iostream>
#include <queue>
using namespace std;
int main() {
int n;//读一个整数
cin >> n;
//qaq用于记录输入数字中非零数字的个数
int x, qaq = 0;
char a;
queue<char> q, qq;
cin >> a;
while (a != '0') {
q.push(a);
qaq += (a - '0');//非零字符的个数累加到变量 qaq
cin >> a;
}
//输出队列q中存储的每个位数
cout << "输入数字的每个位数:" << endl;
while (!q.empty()) {
cout << q.front() << " ";
qq.push(q.front());
q.pop();
}
cout << endl;
x = qq.size();//计算队列qq的大小
cout << "输入数字的非零位数个数:" << qaq << endl;
cout << "输入数字的位数:" << x << endl;
cout << "转换为十进制表示的式子:" << endl;
while (!qq.empty()) {
x--;
if (qq.front() != '0') {
qaq--;
cout << qq.front() << '*' << n << '^' << x;
if (x != 0 && qaq != 0)
cout << '+';
}
qq.pop();
}
cout << endl;
return 0;
}