L1-7 最短字母串【保姆级详细讲解】

0 阅读6分钟

 请你设计一个程序,该程序接受起始字母和目标字母作为输入,通过在字母表中向前或向后移动来计算两个给定字母之间的最短路径。然后,程序会沿着最短路径打印出从起始字母到目标字母的所有字母。例如,如果输入“c”和“k”作为起始字母和目标字母,则程序将计算出在字母表中向前移动的路径为 cdefghijk,它需要 8 个字母,在字母表中向后移动的路径是cbazyxwvutsrqponmlk,它需要 19 个字母。因此,程序将打印 cdefhijk,因为 8 个字母小于 19 个。
注意在字母数相等的情况下,程序将打印字母在字母表中向前移动。

image.png

输入格式:

输入为两个同为大写或同为小写的字母,空格分隔。

输出格式:

输出向前或向后移动的最短字母串。

输入样例1:

H K

输出样例1:

HIJK

输入样例2:

b w

输出样例2:

bazyxw

输入样例3:

Q D

输出样例3:

QRSTUVWXYZABCD

输入样例4:

m m

输出样例4:

m


目录

 完整代码

 计算向前和向后的步数

  选择路径

 输出路径字母

向前移动

 向后移动

 处理相同字母的情况

示例分析

示例 1:H K

示例 2:b w

示例 3:Q D

示例 4:m m

 关键点总结

字母表循环处理

路径选择 


浅说:这道题小假对其思路和解题步骤都做了详细地讲解,方便大家理解 ~


 完整代码

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

int main() {
    char start, end;
    cin >> start >> end;

    int forward = (end - start + 26) % 26;
    int backward = (start - end + 26) % 26;

    if (forward <= backward) {
        for (int i = 0; i <= forward; ++i) {
            char c = start + i;
            if (isupper(start)) {
                if (c > 'Z') c -= 26;
            } else {
                if (c > 'z') c -= 26;
            }
            cout << c;
        }
    } else {
        for (int i = 0; i <= backward; ++i) {
            char c = start - i;
            if (isupper(start)) {
                if (c < 'A') c += 26;
            } else {
                if (c < 'a') c += 26;
            }
            cout << c;
        }
    }

    return 0;
}

 计算向前和向后的步数

int forward = (end - start + 26) % 26;
int backward = (start - end + 26) % 26;

  • forward:从 start 到 end 向前移动的步数。

    • end - start:直接计算字母的 ASCII 差值。
    • + 26:确保差值为正(避免负数)。
    • % 26:因为字母表有 26 个字母,取模后得到实际的步数。
  • backward:从 start 到 end 向后移动的步数。

    • start - end:直接计算字母的 ASCII 差值。
    • + 26 和 % 26:同上,确保步数为正。

  选择路径

if (forward <= backward) {
    // 向前移动
} else {
    // 向后移动
}

  • 如果 forward <= backward,选择向前移动的路径(步数更少或相等)。
  • 否则,选择向后移动的路径(步数更少)。

 输出路径字母

向前移动

for (int i = 0; i <= forward; ++i) {
    char c = start + i;
    if (isupper(start)) {
        if (c > 'Z') c -= 26; // 处理大写字母循环
    } else {
        if (c > 'z') c -= 26; // 处理小写字母循环
    }
    cout << c;
}

  • 从 start 开始,依次输出 start + ii 从 0 到 forward)。
  • 如果字符超出字母表范围(如 start 是大写字母且 start + i > 'Z'),则通过 -= 26 回到字母表开头(如 'Z' + 1 -> 'A')。

 向后移动

for (int i = 0; i <= backward; ++i) {
    char c = start - i;
    if (isupper(start)) {
        if (c < 'A') c += 26; // 处理大写字母循环
    } else {
        if (c < 'a') c += 26; // 处理小写字母循环
    }
    cout << c;
}

  • 从 start 开始,依次输出 start - ii 从 0 到 backward)。
  • 如果字符超出字母表范围(如 start 是小写字母且 start - i < 'a'),则通过 += 26 回到字母表末尾(如 'a' - 1 -> 'z')。

处理相同字母的情况

如果 start == end,则 forward 和 backward 都为 0,直接输出 start

示例分析

示例 1:H K

  • start = 'H' (72), end = 'K' (75)
  • forward = (75 - 72 + 26) % 26 = 3
  • backward = (72 - 75 + 26) % 26 = 23
  • forward < backward,选择向前移动。
  • 输出:H (72), I (73), J (74), K (75) → HIJK

示例 2:b w

  • start = 'b' (98), end = 'w' (119)
  • forward = (119 - 98 + 26) % 26 = 21
  • backward = (98 - 119 + 26) % 26 = 5
  • forward > backward,选择向后移动。
  • 输出:b (98), a (97), z (122), y (121), x (120), w (119) → bazyxw

示例 3:Q D

  • start = 'Q' (81), end = 'D' (68)
  • forward = (68 - 81 + 26) % 26 = 13
  • backward = (81 - 68 + 26) % 26 = 13
  • forward == backward,选择向前移动。
  • 输出:Q (81), R (82), ..., Z (90), A (65), B (66), C (67), D (68) → QRSTUVWXYZABCD

示例 4:m m

  • start = 'm'end = 'm'
  • forward = 0backward = 0
  • 直接输出 m

 关键点总结

字母表循环处理

  • 通过 + 26 和 % 26 确保步数计算正确(避免负数或超出范围)。
  • 在输出时,通过 += 26 或 -= 26 处理字母表的循环(如 'Z' + 1 -> 'A')。

路径选择 

  • 优先选择步数少的路径。
  • 步数相同时,选择向前移动的路径。

 大小写区分

  • 使用 isupper 判断字母大小写,确保正确处理 'A'-'Z' 和 'a'-'z' 的循环。 

 如果小假的内容对你有帮助,请点赞,评论,收藏。创作不易,大家的支持就是我坚持下去的动力!