题目要求我们计算在普通手机键盘上输入一个句子所需要的最少按键次数。每个数字键对应多个字母,而按下相同数字键的次数决定了字符的输出。比如,要输入字母 x
,就需要按数字键 9 两次。输入空格时,按键 0 一次即可。
给定输入的句子,我们需要计算出在键盘上打出这个句子所需的按键总数。
输入格式:
输出格式:
输入:
i have a dream
输出:
23
题目中的手机键盘布局如下所示:
键盘上每个数字键下有多个字母。对于输入的每个字母,我们要计算它所需要的按键次数。空格对应数字键 0
,按一次即可。
我最初的做法使用了一个逐步推算字符按键次数的方法,采用了基于字符范围判断来计算按键次数。具体做法如下:
a
, b
, c
,按 1 次键 2;d
, e
, f
,按 1 次键 3;p
, q
, r
, s
,按 4 次键 7;我的方法中使用了条件语句来逐步判断每个字符属于哪个数字键,然后根据字母在该键中的位置来推算按键次数。然而,这种方法对于字母的映射并不直观,容易出错,尤其是在处理字母范围时,代码的可维护性较差。
#include <iostream>
#include <string>
using namespace std;
int main()
{
string s;
int count = 0;
getline(cin, s);
for(int i = 0; i < s.size(); i++)
{
if(s[i] >= 'a' && s[i] <= 'o')
{
count += (((s[i] - 'a') % 3) + 1);
}
else if(s[i] >= 'p' && s[i] <= 's')
{
count += ((s[i] - 'o') % 5);
}
else if(s[i] >= 't' && s[i] <= 'v')
{
count += ((s[i] - 's') % 4);
}
else if(s[i] >= 'w' && s[i] <= 'z')
{
count += ((s[i] - 'v') % 5);
}
else
{
count += 1;
}
}
cout << count << endl;
return 0;
}
老师的做法则采用了更简洁且高效的解决方案。通过定义一个数组 count
来映射每个字母到它所需的按键次数。每个字母的按键次数在数组中已经预先设定好。
count[26]
来记录每个字母的按键次数,字母的索引是通过 c - 'a'
计算的。count
数组的值进行累加。#include <iostream>
#include <string>
using namespace std;
int count[26] = {1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 4, 1, 2, 3, 1, 2, 3, 4};
int main()
{
string s;
int sum = 0;
getline(cin, s);
for(auto c : s)
{
if(c == ' ')
sum += 1; // 空格只需按一次0
else
sum += count[c - 'a']; // 字母的按键次数
}
cout << sum << endl;
return 0;
}
count
预设每个字母的按键次数,避免了多次条件判断,使得代码更加简洁。count
数组即可,不需要修改逻辑代码,维护起来更加方便。如果问题中要求更复杂的键盘布局(例如支持大写字母、符号等),可以通过扩展 count
数组的大小,或者使用哈希表来存储字符到按键次数的映射。
如果字符集较大,count
数组可能会变得非常庞大。可以考虑使用哈希表来存储字符到按键次数的映射,这样可以避免不必要的空间浪费。
通过这次对比与分析,我们可以看到,尽管两种方法最终都能解决问题,但老师的做法由于其简洁高效,减少了冗余的条件判断,更具可读性与维护性。因此,在编程实践中,采用更简洁直接的方法,不仅能提高代码的执行效率,还能使代码更容易理解和维护。
希望这篇文章能够帮助你深入理解该问题的解决思路,并通过优化思路提升编程能力。