题解:学而思编程 九宫格键盘

【题目来源】

学而思编程:九宫格键盘

【题目描述】

在手机上输入有一种输入法称为拼音 \(9\) 键,也叫做九宫格键盘,如下图所示:

如果要打出一个 \(n\),就需要按两下 \(6\)。第一次按 \(6\) 号键会出现 \(m\),按第二次才会将 \(m\) 改成 \(n\)。注意 \(0\) 号键的作用是打出一个空格。

现在给定一个仅有小写字母和空格组成的字符序列,请你计算九宫格输入法总计需要按键多少次。

【输入】

一行一个字符串 \(s\),表示给定的字符序列。

【输出】

一行一个整数,表示按键的总次数。

【输入样例】

hello world

【输出样例】

25

【核心思想】

  1. 问题分析:给定一个由小写字母和空格组成的字符串,计算使用九宫格拼音输入法输入该字符串所需的总按键次数。九宫格键盘上每个数字键对应多个字母,按第 \(k\) 次选择该键的第 \(k\) 个字母,空格由 \(0\) 号键输入。这是一个直接映射 + 线性累加问题,关键在于建立字符到按键次数的映射表。

  2. 算法选择

    • 查表法:预定义每个字母所需的按键次数数组 key[26]
    • 线性扫描:遍历字符串,累加每个字符对应的按键次数
  3. 关键步骤

    • 初始化映射表
      • key[0..2] = {1, 2, 3}a, b, c 对应 \(2\) 号键,分别按 \(1, 2, 3\)
      • key[3..5] = {1, 2, 3}d, e, f 对应 \(3\) 号键
      • key[6..8] = {1, 2, 3}g, h, i 对应 \(4\) 号键
      • key[9..11] = {1, 2, 3}j, k, l 对应 \(5\) 号键
      • key[12..14] = {1, 2, 3}m, n, o 对应 \(6\) 号键
      • key[15..18] = {1, 2, 3, 4}p, q, r, s 对应 \(7\) 号键
      • key[19..21] = {1, 2, 3}t, u, v 对应 \(8\) 号键
      • key[22..25] = {1, 2, 3, 4}w, x, y, z 对应 \(9\) 号键
    • 读取字符串 s(含空格,使用 getline
    • 计算总按键次数
      • res = 0
      • 遍历 \(i\)\(0\)s.size() - 1
        • s[i] == ' 'res++(空格按 \(0\) 号键 \(1\) 次)
        • 否则:res += key[s[i] - 'a'](字母按对应次数)
    • 输出 res
  4. 时间/空间复杂度

    • 时间复杂度:\(O(|s|)\),线性遍历字符串
    • 空间复杂度:\(O(1)\),固定大小的映射表
  5. 查表法的核心思想

    • 固定映射关系:九宫格键盘的字母分布是固定的,每个字母的按键次数可预先计算并硬编码
    • 字符编码转换:利用 ASCII 码,s[i] - 'a' 将字母映射到 \(0..25\) 的数组下标,实现 \(O(1)\) 查表
    • 空格特殊处理:空格单独判断,不通过映射表,避免数组越界
    • 逐字符独立累加:每个字符的按键次数相互独立,总次数为各字符次数之和,无状态依赖
    • 适用于"固定规则映射 + 线性累加"类问题,查表法将条件判断转化为数组索引,代码简洁高效

【算法标签】

字符串入门

【代码详解】

#include <bits/stdc++.h>
using namespace std;

// 定义每个字母在九键键盘上需要的按键次数
int key[26] = {1, 2, 3,  // a,b,c
               1, 2, 3,  // d,e,f
               1, 2, 3,  // g,h,i
               1, 2, 3,  // j,k,l
               1, 2, 3,  // m,n,o
               1, 2, 3, 4,  // p,q,r,s
               1, 2, 3,  // t,u,v
               1, 2, 3, 4};  // w,x,y,z

// 计算输入字符串的总按键次数
int get_cnt(string s)
{
    int res = 0;  // 总按键次数
    for (int i = 0; i < s.size(); i++)  // 遍历字符串每个字符
    {
        if (s[i] == ' ')  // 空格键
        {
            res++;  // 空格只需要按一次
        }
        else  // 字母
        {
            res += key[s[i] - 'a'];  // 根据字母计算按键次数
        }
    }
    return res;
}

string s;
int main()
{
    getline(cin, s);  // 读取整行输入(包含空格)
    cout << get_cnt(s) << endl;  // 输出总按键次数
    return 0;
}

【运行结果】

hello world
25
posted @ 2026-07-04 14:50  团爸讲算法  阅读(13)  评论(0)    收藏  举报