OpenJudge-1.7.11:潜伏者

一、题目链接

http://noi.openjudge.cn/ch0107/11/

二、解题思路(Java)

三、解题思路(C++)

四、Java程序

import java.util.Scanner;

public class Main {
    /**
     * 判断26个大写字母是否全部出现在给定字符串中
     *
     * @param text String类型的对象,代表给定字符串
     * @return 逻辑量,true当且仅当26个大写字母全部出现在text中,否则false
     */
    public boolean containsAllUpperLetters(String text) {
        char[] chars = text.toCharArray(); // 存储text中的每个字符
        int[] occur = new int[128]; // 存储text中每个字符出现的次数
        /* 利用foreach循环遍历获取text中的每个字符c */
        for (char c : chars) {
            occur[c]++; // 当前字符c出现的次数增加1次
        }
        /* 从大写字母A开始,到大写字母Z为止 */
        for (char c = 'A'; c <= 'Z'; c++) {
            if (occur[c] == 0) { // 如果有一个大写字母未出现
                return false; // 则返回false
            }
        }
        return true; // 以上没有返回false,说明26个大写字母全部出现,返回true
    }

    /**
     * 判断加密信息和原信息之间是否存在字符唯一编码关系
     *
     * @param info   String类型的对象,代表加密信息
     * @param source String类型的对象,代表原信息
     * @return 逻辑量,true当且仅当info和source之间存在字符唯一编码关系,否则false
     */
    public boolean isSameCoded(String info, String source) {
        int n = info.length();
        char[] code = new char[128]; // 存放编码
        boolean[] isCoded = new boolean[128]; // 标记字符是否已经编码,默认false
        /* 从第一个字符开始,到最后一个字符为止 */
        for (int i = 0; i < n; i++) {
            if (!isCoded[info.charAt(i)]) { // 如果info的当前字符尚未编码
                code[info.charAt(i)] = source.charAt(i); // 则用source的当前字符为其编码
                isCoded[info.charAt(i)] = true; // 标记当前字符已经编码
            }
            else { // 否则,info的当前字符已经编码                
                if (code[info.charAt(i)] != source.charAt(i)) { // 如果这个编码不是source的当前字符
                    return false; // 则说明info和source之间唯一编码关系不成立,返回false
                }
            }
        }
        return true; // 以上没有返回false,说明info和source存在字符唯一编码关系,返回true
    }

    /**
     * 根据给定的加密信息和原信息,对字符串进行解密
     *
     * @param info     String类型的对象,代表给定的加密信息
     * @param source   String类型的对象,代表给定的原信息
     * @param required String类型的对象,代表待解密的字符串
     * @return String类型的对象,根据info和source的编码关系,对required进行解密
     */
    public String decryption(String info, String source, String required) {
        // 如果给定的加密信息和原信息不符合题目要求
        if (!containsAllUpperLetters(source) || !isSameCoded(info, source)) {
            return "Failed"; // 则返回Failed
        }
        int n = info.length();
        int m = required.length();
        char[] code = new char[128]; // 存放加密信息info与原信息source对应的编码
        char[] ans = new char[m]; // 存放待解密的字符串required对应的所有解密字符
        /* 从第一个字符开始,到最后一个字符为止 */
        for (int i = 0; i < n; i++) {
            code[info.charAt(i)] = source.charAt(i); // 利用原信息字符对加密信息字符进行编码
        }
        /* 从第一个字符开始,到最后一个字符为止 */
        for (int i = 0; i < m; i++) {
            ans[i] = code[required.charAt(i)]; // 利用编码表对required字符进行解密
        }
        return String.valueOf(ans);
    }

    public static void main(String[] args) {
        Main test = new Main();
        Scanner input = new Scanner(System.in);
        String info = input.next();
        String source = input.next();
        String required = input.next();
        System.out.print(test.decryption(info, source, required));
    }
}

五、C++程序

#include <iostream>
using namespace std;

int main()
{
    string info; // 小C掌握的一条加密信息
    string source; // info对应的原信息
    string required; // 待解密的信息
    cin >> info;
    cin >> source;
    cin >> required;
    int m = source.length(); // 加密信息info和原信息source的长度
    int n = required.length(); // 待解密的信息required的长度
    char ans[n]; // 对required解密后形成的信息
    char code[128] = {'\0'};  // 存放info和source字符对应的编码,初始时均为'\0'
    int occur[128] = {0}; // 存储source中每个字符出现的次数,初始时均为0
    /* 利用foreach循环遍历获取source中的每个字符c */
    for (char c: source)
    {
        occur[c]++; // 当前字符c出现的次数增加1次
    }
    /* 从大写字母A开始,到大写字母Z为止 */
    for (char c = 'A'; c <= 'Z'; c++)
    {
        if (occur[c] == 0) // 如果有一个大写字母在source中未出现
        {
            cout << "Failed"; // 则说明source不符合要求,输出Failed
            return 0; // 直接退出程序
        }
    }
    /* 从第一个字符开始,到最后一个字符为止 */
    for (int i = 0; i < m; i++)
    {
        if (code[info[i]] == '\0') // 如果当前info的字符尚未编码
        {
            code[info[i]] = source[i]; // 则通过对应的source字符为其编码
        }
        else // 否则,当前info的字符已经编码
        {
            if (code[info[i]] != source[i]) // 如果该编码不是对应的source字符
            {
                cout << "Failed"; // 则说明info和source之间唯一编码关系不成立,输出Failed
                return 0; // 直接退出程序
            }
        }
    }
    /* 以上均为退出程序,说明可以正常解密 */
    for (int i = 0; i < n; i++)
    {
        ans[i] = code[required[i]]; // 通过编码表对required各字符进行解密
        cout << ans[i]; // 输出解密后的字符
    }
    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

江苏科技大学_计算机学院_潘磊

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

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

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

打赏作者

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

抵扣说明:

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

余额充值