题目1.字符串匹配
有一个字符串它的构成是词+空格的组合,如“北京 杭州 杭州 北京 上海”, 要求输入一个匹配模式(简单的以字符来写), 比如 aabb, 来判断该字符串是否符合该模式, 举个例子:
1.pattern = “abbac”, str=“北京 杭州 杭州 北京 上海” 返回 ture
2.pattern = “aacbb”, str=“北京 北京 上海 杭州 北京” 返回 false
3.pattern = “baabcc”, str=“北京 杭州 杭州 北京 上海 上海” 返回 ture
public class Solution { public boolean wordPattern(String pattern, String str) { } }
我的答案:
package exam; import java.util.HashMap; import java.util.Map; public class Solution { // pattern = "abbac", str="北京 杭州 杭州 北京 上海" 返回 ture public boolean wordPattern(String pattern, String str) { Map<Character, String> map = new HashMap<>(); String[] strs = str.split(" "); if(pattern.length() != strs.length){ return false; } int n = pattern.length(); for(int i = 0; i < n; i ++){ char c = pattern.charAt(i); String temp = strs[i]; if(!map.containsKey(c) && !map.containsValue(temp)){ map.put(c, temp); }else{ if(!temp.equals(map.get(c))){ return false; } } } return true; } public static void main(String[] args) { Solution s = new Solution(); // String pattern = "abbac"; // String str = "北京 杭州 杭州 北京 上海"; // String pattern = "aacbb"; // String str = "北京 北京 上海 杭州 北京"; String pattern = "aabb"; String str = "北京 北京 北京 北京"; System.out.println(s.wordPattern(pattern, str)); } }
这里要感谢读者qq_36922084的提醒,上一版代码是通过不了所有的测试用例的,因为没有考虑map中会重复添加相同的value,而这些value恰恰可能是对应不同的key,举个例子:如果输入 str = "北京 北京 北京 北京"和parten = "aabb"的话,原本的代码会输出一个true,但这显然是错误的,现已纠正,在判断!map.containsKey(c)的同时加入!map.containsValue(temp)即可,保证集合中的键值对不重复。
题目2.接口限流实现
有一个API网关,出于对API接口的保护,需要建立一个流控功能,根据API名称,每分钟最多只能请求指定的次数(如1000次),超过限制则这分钟内返回错误,但下一分钟又可以正常请求。
public class API { /* 超时时间 */ private long time; /* 请求API的次数 */ private int count; public long getTime() { return time; } public void setTime(long time) { this.time = time; } public int getCount() { return count; } public void setCount(int count) { this.count = count; } public boolean isValid(){ System.out.println(System.currentTimeMillis()/1000); // 没有超时 if(System.currentTimeMillis()/1000 < time){ if(this.count < 10){ // 请求小于10次则表示请求成功(为了测试方便没有设为题意的1000) this.count ++; System.out.println("执行成功"); return true; }else{ System.out.println("请求超出1000次,失败"); return false; } }else{ // 触发限流则重置 System.out.println("----------重置----------"); this.count = 1; this.setTime(System.currentTimeMillis()/1000 + 1); return true; } } }
import javax.sound.midi.Soundbank; import java.util.HashMap; import java.util.Map; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; /** * 2 * @Author: 小王同学 * 3 * @Date: 2021/3/3 16:12 * 4 */ public class UseApi { /* * 用一个map来记录请求的名字和频次 */ private static Map<String, API> map = new HashMap<>(); public boolean invoke(String name){ if (name.isEmpty()){ return false; } synchronized (map){ System.out.println(map.containsKey(name)); // 第一次请求该命令 if(!map.containsKey(name)){ API api = new API(); api.setTime(System.currentTimeMillis()/1000 + 1); api.setCount(1); map.put(name, api); return true; }else{ API api = map.get(name); return api.isValid(); } } } // 测试方法,线程里面请求10次同一个方法 method1 public static Runnable getThread(){ return new Runnable() { @Override public void run() { for(int i = 0; i < 10; i ++){ try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } UseApi useApi = new UseApi(); System.out.println(useApi.invoke("method1")); } } }; } public static void main(String[] args) { ExecutorService executorService = Executors.newFixedThreadPool(10); // 开10个线程进行测试 for (int i = 0; i < 10; i++) { executorService.submit(getThread()); try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } } executorService.shutdown(); } }
关于这个1分钟计时的方法应该还有更好的,欢迎大家留言分享~