好久不见。
最近忙于校园招聘会,有招聘会自然就有笔试了。因此我在这里就分享某企业笔试中一道编程题。描述如下:
假定有一命令编辑框,可以接受两种命令:【type x】和【undo n】。x代表输入文本,n代表秒数。type命令用于当输入文本,而undo命令用于撤销操作。输入undo 1,表示向前撤销1秒。撤销操作可以指定撤销到当前时间之前操作的时间,并且撤销操作对自身同样有效。
举几个例子,
命令输入的时间 | 命令 | 显示结果 |
1 | type a | a |
2 | type b | ab |
3 | undo 1 | a |
命令输入的时间 | 命令 | 显示结果 |
1 | type a | a |
2 | type b | ab |
3 | type c | abc |
4 | undo 2 | a |
5 | undo 1 | abc |
命令输入的时间 | 命令 | 显示结果 |
1 | type a | a |
2 | type b | ab |
3 | type c | abc |
5 | undo 1 | abc |
要求设计一个函数,可以接收命令和输入时间,返回最终结果。
当我看到这道题时,首先想到的是正则表达式匹配命令格式,使用map管理命令和输入时间,但是对操作与结果的缓存存在疑虑,最终还是没有完成。
今天又想起这题目,于是决定结束这未完成的命运:
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 package com.lly.receivecomd;
2
3 import java.util.HashMap;
4 import java.util.Map;
5
6 public class CommandEditor {
7
8 public String cmdEdit(String[] cmds, int[] times) {
9 //Regex to match two commands
10 String type = "^type\\s\\w+$";
11 String undo = "^undo\\s\\d$";
12 //Store the currently result
13 Map<Integer, String> map = new HashMap<Integer, String>();
14 String str = "";
15 for (int i = 0; i < cmds.length; i++) {
16 String[] text = cmds[i].split(" ");
17 if (cmds[i].matches(type)) {
18 //Different string object
19 str += text[text.length - 1];
20 map.put(times[i], str);
21 } else if (cmds[i].matches(undo)) {
22 int toUndoTime = Integer.parseInt(text[text.length - 1]);
23 if (toUndoTime > times[i]) {
24 return "Error Command!";
25 }
26 int rollbackTime = times[i] - toUndoTime - 1;
27 //Find the nearly rollback time
28 for (;!map.containsKey(rollbackTime); ) {
29 rollbackTime--;
30 }
31 map.put(times[i], map.get(rollbackTime));
32 } else {
33 return "Error Command!";
34 }
35
36 }
37 return map.get(times[times.length - 1]).toString();
38 }
39 }
完成后经一番调试得到以上代码。
思路与之前大体相同,关键点在于:1. 使用map缓存了每次操作后的时间和结果;2. 同一字符串引用改变后是不同的字符串对象。
测试代码如下:
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 package com.lly.test;
2
3 import static org.junit.Assert.*;
4
5 import org.junit.Test;
6 import com.lly.receivecomd.CommandEditor;
7
8 public class CmdEditorTest {
9
10 @Test
11 public void testCmdEdit() {
12 CommandEditor cmdEditor = new CommandEditor();
13 String[] cmds = { "type a", "type b", "type c", "undo 1", "undo 1" };
14 int[] times = { 1, 2, 3, 4, 5 };
15 String result = cmdEditor.cmdEdit(cmds, times);
16 assertEquals("abc", result);
17 }
18 }