【华为机考】【字符串加解密】Jave Python C++ C

这篇博客详细介绍了如何使用C++、C、Java和Python实现字符串的加解密算法。加密方法涉及字母大小写的交替变换和数字加1,解密则是加密的逆过程。博客提供了输入输出描述、示例以及每种语言的解题思路。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

描述:

对输入的字符串进行加解密,并输出。
加密方法为:
当内容是英文字母时则用该英文字母的后一个字母替换,同时字母变换大小写,如字母a时则替换为B;字母Z时则替换为a;当内容是数字时则把该数字加1,如0替换1,1替换2,9替换0;其他字符不做变化。
解密方法为加密的逆过程。
数据范围:输入的两个字符串长度满足
1≤n≤1000 ,保证输入的字符串都是只由大小写字母或者数字组成

输入描述:

第一行输入一串要加密的密码
第二行输入一串加过密的密码
输出描述:
第一行输出加密后的字符
第二行输出解密后的字符****

示例1

输入:

abcdefg
BCDEFGH

输出:

BCDEFGH
abcdefg

知识点:

字符串,模拟过程

Python 版本

解题思路:

使用num1和num2做大小写数字的转换,使用s接受num1和num2加解密后的字符,如果不属于num1和num2的字符保持不变即可

def cherk(a, b):
    num1 = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'
    num2 = 'BCDEFGHIJKLMNOPQRSTUVWXYZAbcdefghijklmnopqrstuvwxyza1234567890'
    s = []
    if b == 1:
        for i in a:
            if i in num1:
                s.append(num2[num1.index(i)]) //按照num1中i的索引在num2中取出对应的值,存入s中。
            else:
                s.append(i)  //如果不属于num1,即是特殊字符,不在处理直接存入s中即可;解密和加密逻辑一样
        return ''.join(s)
    if b == 0:
        for i in a:
            if i in num2:
                s.append(num1[num2.index(i)])
            else:
                s.append(i)
        return ''.join(s)
 
 
while True:
    try:
        m1 = input()
        m2 = input()
        print(cherk(m1, 1))
        print(cherk(m2, 0))
    except:
        break

Jave版本

解题思路:

用多分支判断将字符对应转换

import java.util.Scanner;
 
public class Main{
    public static void main(String[] args){
        Scanner in = new Scanner(System.in);
        while(in.hasNext()){
            System.out.println(encode(in.nextLine()));
            System.out.println(decode(in.nextLine()));
        }
    }
 
    //加密函数
    private static String encode(String code){
        char[] t = code.toCharArray();    //将String对象转换为字符数组
        for(int i=0; i < t.length; i++){
            if(t[i]>='a' && t[i]<'z')
                t[i] = (char)(t[i] - 'a' + 'A' + 1);
            else if(t[i] == 'z')
                t[i] = 'A';
            else if(t[i]>='A' && t[i]<'Z')
                t[i] = (char)(t[i] - 'A' + 'a' + 1);
            else if(t[i] == 'Z')
                t[i] = 'a';
            else if(t[i]>='0' && t[i]<'9')
                t[i] = (char)(t[i]+1);
            else if(t[i] == '9')
                t[i] = '0';
        }
        return String.valueOf(t);
    }
 
    //解密函数
    private static String decode(String password){
        char[] t = password.toCharArray();
        for(int i=0; i < t.length; i++){
            if(t[i]>'a' && t[i]<='z')
                t[i] = (char)(t[i] - 'a' + 'A' - 1);
            else if(t[i] == 'a')
                t[i] = 'Z';
            else if(t[i]>'A' && t[i]<='Z')
                t[i] = (char)(t[i] - 'A' + 'a' - 1);
            else if(t[i] == 'A')
                t[i] = 'z';
            else if(t[i]>'0' && t[i]<='9')
                t[i] = (char)(t[i]-1);
            else if(t[i] == '0')
                t[i] = '9';
        }
        return String.valueOf(t);
    }
}

C++ 版本

解题思路:

构建哈希表

#include <iostream>
using namespace std;
int main(){
    string str1, str2;
    cin >> str1 >> str2;
    string a("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789");
    string b("BCDEFGHIJKLMNOPQRSTUVWXYZAbcdefghijklmnopqrstuvwxyza1234567890");
    for(int i = 0; i < str1.size(); ++i)
        str1[i] = b[a.find_last_of(str1[i])];
    for(int i = 0; i < str2.size(); ++i)
        str2[i] = a[b.find_last_of(str2[i])];
    cout << str1 << endl << str2;
}

C 语言版本

解题思路:

用多分支判断将字符对应转换

#include <string.h>
 
int main()
{
    int i;
    char str[1002]={0},str2[1002]={0};
    scanf("%s",str);
    scanf("%s",str2);
     
    for(i=0;i<strlen(str);i++)
    {
        if(str[i]<90&&str[i]>=65)
            str[i]+=33;
        else if(str[i]=='Z')
            str[i]='a';
        else if(str[i]<122&&str[i]>=97)
            str[i]-=31;
        else if(str[i]=='z')
            str[i]='A';
        else if(str[i]<57&&str[i]>=48)
            str[i]+=1;
        else if(str[i]=='9')
            str[i]='0';
    }
    for(i=0;i<strlen(str2);i++)
    {
        if(str2[i]<=90&&str2[i]>65)
            str2[i]+=31;
        else if(str2[i]=='A')
            str2[i]='z';
        else if(str2[i]<=122&&str2[i]>97)
            str2[i]-=33;
        else if(str2[i]=='a')
            str2[i]='Z';
        else if(str2[i]<=57&&str2[i]>48)
            str2[i]-=1;
        else if(str2[i]=='0')
            str2[i]='9';
    }
    printf("%s\n",str);
    printf("%s\n",str2);
}
<think>好的,我需要帮助用户理解华为机考中计算字符串最后一个单词长度的算法。首先,用户的问题是关于这个题目使用了哪种算法,我需要结合提供的引用内容来回答。 先看一下用户提供的引用,共有五个引用。引用1到5都是关于华为机试的题目,特别是HJ1,也就是计算字符串最后一个单词的长度。例如,引用3中提到了C++的代码,引用4是Python的代码,引用5讨论了输入函数的使用。这些引用中的代码和描述应该能帮助我分析所用的算法。 首先,题目要求是输入一个字符串,由多个单词组成,以空格分隔,要求输出最后一个单词的长度。注意字符串末尾没有空格。例如输入"hello nowcoder",输出8,因为最后一个单词是"nowcoder"。 接下来,我需要确定这个问题使用的算法。一般来说,处理这种字符串问题,常用的方法有两种:一种是分割字符串,直接取最后一个元素计算长度;另一种是从字符串末尾反向遍历,统计字符直到遇到空格或开头为止。这两种方法在时间和空间复杂度上可能有所不同。 查看引用中的代码示例,例如引用3的C++代码,它从字符串的末尾开始向前遍历,直到遇到第一个空格为止,统计非空格字符的数量。这说明他们使用的是反向遍历的方法,而不是分割字符串。引用4中的Python代码可能更简洁,可能用的是split方法,但用户提供的引用4中的代码片段不完整,不过根据常见的Python实现,可能使用了类似的方法。例如,用户提到的函数get_last_string_len可能内部用了split,但需要具体看代码。不过引用3的C++代码明显是反向遍历,所以这可能更接近华为机考的解法。 另外,引用5提到了使用scanf函数来读取输入,可能考虑到输入中有多个空格的情况,但具体到这个问题,无论输入中有多少空格,最后一个单词都是最后一个非空格字符序列。因此,反向遍历是更高效的方法,因为它不需要处理整个字符串,只需要从后往前找到第一个空格的位置即可,这在最坏情况下时间复杂度是O(n),但避免了分割整个字符串带来的O(n)空间复杂度。 总结一下,华为机考可能主要考察反向遍历的算法,因为它更高效,尤其是在处理大字符串时,不需要额外的存储空间。而像Python这样的语言可能因为split的简洁性而采用不同的方法,但核心思路是一样的。因此,可以回答用户该算法是反向遍历,统计最后一个单词的长度。 接下来,我需要确保回答符合用户的要求,即结构清晰,分步骤解释,引用相关引用。同时,要生成相关问题,并正确标注引用来源。 可能的问题点:需要确认是否所有引用的代码都采用相同的方法。例如,引用3的C++代码是反向遍历,引用4的Python代码如果是split的话则是另一种方法,但根据问题中的引用,华为机试可能有多种解法,但主要考察的是算法效率,因此反向遍历可能更被推荐。不过,用户的问题是关于华为机考使用了哪种算法,所以需要根据提供的引用内容来判断。 查看引用中的代码,引用3的C++代码是明确的反向遍历,而引用4的Python代码可能用split,但根据用户给出的引用4中的代码,可能没有给出具体实现,所以可能split也是一种方法。不过,根据引用3的例子,华为的官方题解可能更倾向于反向遍历,因为这样更高效,尤其是考虑到字符串可能很长的情况下。 因此,在回答中应该说明两种可能的思路,但指出华为机考中可能更倾向于使用反向遍历的方法,并引用相应的例子,如引用3中的C++代码。 最后,生成相关问题,例如分割字符串的方法与反向遍历的优缺点,如何处理特殊情况,或者不同编程语言中的实现差异等。</think>### 字符串最后一个单词长度的算法解析 华为机考题目要求计算字符串中最后一个单词的长度,其核心算法可归纳为以下两种实现思路: #### 方法1:反向遍历(推荐) **算法步骤**: 1. **从字符串末尾开始向前遍历**,忽略末尾可能的连续空格(若题目允许末尾有空格,需先处理) 2. **统计连续非空格字符的数量**,直到遇到第一个空格或遍历到字符串开头 3. **输出统计结果** **代码示例(C++)**: ```cpp #include <iostream> #include <string> using namespace std; int main() { string str; getline(cin, str); int count = 0; for (int i = str.length() - 1; i >= 0; i--) { if (str[i] != ' ') count++; else if (count > 0) break; // 遇到空格且已统计到字符时终止 } cout << count << endl; return 0; } ``` **优势**: - **时间复杂度为$O(n)$**,仅需一次遍历 - **空间复杂度为$O(1)$**,无需额外存储[^3] --- #### 方法2:分割字符串(适用于短字符串) **算法步骤**: 1. **按空格分割字符串**为单词列表 2. **取列表最后一个元素**并计算其长度 **代码示例(Python)**: ```python s = input().strip() words = s.split() print(len(words[-1]) if words else 0) ``` **注意**: - 需处理输入全为空格的特殊情况[^4] - **时间复杂度为$O(n)$**,但分割操作需要额外空间存储所有单词[^4] --- ### 华为机考的实际应用 根据引用中的C++实现,华为机考**更倾向于反向遍历方法**。这种算法直接操作字符串,避免内存浪费,尤其适合处理长字符串(题目限制字符串长度<5000)[^3]。 ---
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

DFCED

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值