题解 | #配置文件恢复#

配置文件恢复

http://www.nowcoder.com/practice/ca6ac6ef9538419abf6f883f7d6f6ee5

描述

题目描述

输入描述:

多行字符串,每行字符串一条命令

输出描述:

执行结果,每条命令输出一行

示例

输入:
reset
reset board
board add
board delet
reboot backplane
backplane abort
输出:
reset what
board fault
where to add
no board at all
impossible
install first

知识点:字符串,模拟,正则表达式

难度:⭐⭐⭐


题解

方法一:模拟

图解

image-20211209144332943

image-20211209144341871

算法流程

  • 两个变量分别记录匹配成功的命令数量、匹配成功后在map的key
  • 分输入命令的长度,分情况遍历每个命令进行前缀的匹配
  • 匹配成功后更新两个变量
  • 最后判断匹配成功的次数,结果为1才表示匹配上

Java 版本代码如下:

import java.util.*;
public class Main{
    public static void main(String[]args){
        Scanner sc=new Scanner(System.in);
        while(sc.hasNext()){
            String s=sc.nextLine();
            recover(s);
        }
    }
    public static void recover(String s){
        String[] strings = {"reset","reset board","board add","board delete","reboot backplane","backplane abort"};
        Map<String,String>map=new HashMap<>();
        map.put("reset","reset what");
        map.put("reset board","board fault");
        map.put("board add","where to add ");
        map.put("board delete","no board at all");
        map.put("reboot backplane","impossible");
        map.put("backplane abort","install first");
        String ERROR = "unknown command";
        String[] inputArr = s.split(" ");
        // 输入的命令长度为1
        if (inputArr.length==1){
            String input = inputArr[0];
            String cmd = strings[0].substring(0, input.length());
            if (cmd.equals(input)){
                System.out.println("reset what");
            }else {
                System.out.println(ERROR);
            }
        }else { 
        	// 匹配成功的命令数量
        	int count = 0;
            // 匹配成功后在map的key
            String key = "";
            // 穷举二字串的命令
            for (int i = 1 ; i < strings.length ; i++){
                String input1 = inputArr[0], input2 = inputArr[1];
                String command = strings[i];
                String[] cmd = command.split(" ");
                if (cmd.length==2){
                    String cmd1 = cmd[0], cmd2 = cmd[1];
                    // 输入的命令长度天长,不匹配该命令
                    if (cmd1.length() < input1.length() || cmd2.length() < input2.length()){
                        continue;
                    }
                    String s1 = cmd1.substring(0, input1.length());
                    String s2 = cmd2.substring(0, input2.length());
                    // 匹配前缀
                    if (s1.equals(input1) && s2.equals(input2)){
                    	// 匹配成功后的
                        key = command;
                        // 统计匹配成功的次数
                        count++;
                    }
                }
            }
            // 只能匹配成功一个
            if (count == 1){
                System.out.println(map.get(key));
            }else {
                System.out.println(ERROR);
            }
        }
    }

}

复杂度分析

时间复杂度O(1)O(1), 每个输入最多需要进行5次处理判断

空间复杂度O(1)O(1), 只用到常数级别的空间

方法二:正则表达式匹配

解题思路

借助正则表达式,对每个命令进行匹配

算法流程

  • 两个变量记录有多少match的指令、最后一个match的指令的下表
  • 将输入的字符串与每个命令进行匹配
    • 在输入的字符串后面加上 “.*”,就可进行模糊匹配
  • 最后根据匹配的次数是否为1,来获取结果

Java 版本代码如下:

import java.util.*;
import java.util.regex.*;

public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        String[] commands = {"reset", "reset board", "board add", "board delete", 
                                 "reboot backplane", "backplane abort"};
        String[] responses = {"reset what", "board fault", "where to add", 
                                  "no board at all", "impossible", "install first", "unknown command" };
        while (in.hasNextLine()) { 
            String input = in.nextLine();
            if(input.isEmpty()){//阻止最后一行的空行输出unknown command
                continue;
            }
            int match_num = 0;//记录有多少match的指令
            int index = 6;//记录最后一个match的指令的下表
            for(int i=0;i<commands.length;i++){
                if(match(input, commands[i])){
                    match_num++;
                    index = i;
                }
            }
            if(match_num!=1){
                index = 6;
            }
            System.out.println(responses[index]);

        }
    }
	
	// 正则表达式匹配
    public static boolean match(String input, String command){
        if(input.isEmpty()){//空白输入不应该有符合的结果
            return false;
        }
        String[] inputs = input.split(" ");
        String[] commands = command.split(" ");
        if(inputs.length==1 && commands.length==1){
            String pattern = input+".*";
            return Pattern.matches(pattern, command);
        }else if(inputs.length==2 && commands.length==2){
            String pattern_1 = inputs[0]+".*";
            String pattern_2 = inputs[1]+".*";
            return Pattern.matches(pattern_1, commands[0]) && Pattern.matches(pattern_2, commands[1]);
        }
        return false;
    }
}

复杂度分析

时间复杂度O(1)O(1), 每个输入最多需要进行5次处理判断

空间复杂度O(1)O(1), 只用到常数级别的空间

华为机试 文章被收录于专栏

华为机试题解

全部评论

相关推荐

2025-12-08 16:04
门头沟学院 Java
本人本科末9,今年大三。大一大二一直玩,什么都没学到,在大学混日子混了两年,每天不是在打农就是在steam。大三开学时一个和自己玩的好的同学去实习了,才发现自己白白浪费了两年的时间,如果真不冲一下就真去京东,阿里,美团送外卖了今年9月份开始学Java,一开始一直跟着黑马视频看,后面发现看视频效率太低了,时间根本不够,就开始主要看文档和看书了。这几个月一直在学,真的尽力了,希望暑期前能找一份好点的实习。我简历上面的项目大多没有指标,但是实际上我是真没多少时间去做项目,我基本主要是动手只做了外卖和天机,黑马点评和12306我都是只是看了项目。主要是自己的时间真的不多,但是这样子自己的代码能力确实比较差。而且自己也没有做过实际的工程,我顶多用jmeter测试一下接口tps啥的,比如使用Redis管道提升了一点性能,减少Redis交互,这种值得写上去吗?需不需要具体到某些数字求求各位佬给一些建议,看看简历怎么优化?项目介绍是不是不够详细?没有具体到业务方面。项目会不会提到大致实现原理导致面试官一看简历就知道怎么实现就没有问的欲望?专业技能一些字段是不是要加粗,是不是写太啰嗦了?有没有必要压缩内容变成一页?两页的话是不是都要把两页填地满满的。
给秋招一个交代:一页简历最好,网上做的项目放面试官眼里都是玩具,简历上不需要强调有什么难点,记住就行防止真的问。然后背八股,多投多面试就行
点赞 评论 收藏
分享
迷茫的大四🐶:都让开,我tm来啦
点赞 评论 收藏
分享
评论
1
1
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务