Published on

ARTS 第10周

Authors

Algorithm

package org.nocoder.leetcode.solution;

import java.util.HashMap;

/**
 * Roman numerals are represented by seven different symbols: I, V, X, L, C, D and M.
 * <p>
 * Symbol       Value
 * I             1
 * V             5
 * X             10
 * L             50
 * C             100
 * D             500
 * M             1000
 * For example, two is written as II in Roman numeral, just two one's added together. Twelve is written as, XII, which is simply X + II. The number twenty seven is written as XXVII, which is XX + V + II.
 * <p>
 * Roman numerals are usually written largest to smallest from left to right. However, the numeral for four is not IIII. Instead, the number four is written as IV. Because the one is before the five we subtract it making four. The same principle applies to the number nine, which is written as IX. There are six instances where subtraction is used:
 * <p>
 * I can be placed before V (5) and X (10) to make 4 and 9.
 * X can be placed before L (50) and C (100) to make 40 and 90.
 * C can be placed before D (500) and M (1000) to make 400 and 900.
 * Given a roman numeral, convert it to an integer. Input is guaranteed to be within the range from 1 to 3999.
 * <p>
 * Example 1:
 * <p>
 * Input: "III"
 * Output: 3
 * Example 2:
 * <p>
 * Input: "IV"
 * Output: 4
 * Example 3:
 * <p>
 * Input: "IX"
 * Output: 9
 * Example 4:
 * <p>
 * Input: "LVIII"
 * Output: 58
 * Explanation: C = 100, L = 50, XXX = 30 and III = 3.
 * Example 5:
 * <p>
 * Input: "MCMXCIV"
 * Output: 1994
 * Explanation: M = 1000, CM = 900, XC = 90 and IV = 4.
 *
 * @author jason
 * @date 18/9/9.
 */
public class RomanToInteger {
    public int romanToInt(String s) {
        if (s == null || s.length() == 0) {
            return -1;
        }
        HashMap<Character, Integer> map = new HashMap<Character, Integer>();
        map.put('I', 1);
        map.put('V', 5);
        map.put('X', 10);
        map.put('L', 50);
        map.put('C', 100);
        map.put('D', 500);
        map.put('M', 1000);
        if (s.length() == 1) return map.get(s.charAt(0));
        int result = 0;
        for (int i = 1; i < s.length(); i++) {
            if (map.get(s.charAt(i - 1)) >= map.get(s.charAt(i))) {
                result += map.get(s.charAt(i - 1));

            } else {
                result -= map.get(s.charAt(i - 1));
            }
        }
        result += map.get(s.charAt(s.length() - 1));
        return result;
    }
}

Review

Apache Commons Chain https://www.baeldung.com/apache-commons-chain

本教程中,作者以“ATM取款”的场景为例,演示 Apache Commons Chain 的应用。

Context

  • 要提取的总金额
  • 100 面额纸币数量
  • 50 面额纸币数量
  • 10 面额纸币数量
  • 余额

Command

  • Command 实现类将接收 Context,并作相应的逻辑处理
public class HundredDenominationDispenser implements Command {

    @Override
    public boolean execute(Context context) throws Exception {
        intamountLeftToBeWithdrawn = (int) context.get("amountLeftToBeWithdrawn);
        if (amountLeftToBeWithdrawn >= 100) {
            context.put("noOfHundredsDispensed", amountLeftToBeWithdrawn / 100);
            context.put("amountLeftToBeWithdrawn", amountLeftToBeWithdrawn % 100);
        }
        return false;
    }
}

Chain

  • Chain 是一组要顺序执行的 Command 的集合。
public class AtmWithdrawalChain extends ChainBase {

    public AtmWithdrawalChain() {
        super();
        addCommand(new HundredDenominationDispenser());
        addCommand(new FiftyDenominationDispenser());
        addCommand(new TenDenominationDispenser());
        addCommand(new AuditFilter());
    }
}

当Chain中的任何Command返回true时,它会强制Chain结束。

Filter

  • 过滤器也是一个Command,但具有在执行Chain之后调用的postProcess方法。

Chain Catalog

Demo

public class AtmChainTest {

    @Test
    public void givenInputsToContext_whenAppliedChain_thenExpectedContext() throws Exception {
        Context context = new AtmRequestContext();
        context.put("totalAmountToBeWithdrawn", 460);
        context.put("amountLeftToBeWithdrawn", 460);

        Catalog catalog = new AtmCatalog();
        Command atmWithdrawalChain = catalog.getCommand("atmWithdrawalChain");

        atmWithdrawalChain.execute(context);

        assertEquals(460, (int) context.get("totalAmountToBeWithdrawn"));
        assertEquals(0, (int) context.get("amountLeftToBeWithdrawn"));
        assertEquals(4, (int) context.get("noOfHundredsDispensed"));
        assertEquals(1, (int) context.get("noOfFiftiesDispensed"));
        assertEquals(1, (int) context.get("noOfTensDispensed"));
    }
}

Tip

sessionStorage 和 localStorage

sessionStorage 用于本地存储一个会话(session)中的数据,这些数据只有在同一个会话中的页面才能访问,会话结束后数据也随之销毁。

localStorage 用于存储一个域名下的需要永久存在在本地的数据,这些数据可以被一直访问,直到这些数据被删除。

因此sessionStorage 和 localStorage 的主要区别在于他们存储数据的生命周期,sessionStorage 存储的数据的生命周期是一个会话,而 localStorage 存储的数据的生命周期是永久,直到被主动删除,否则数据永远不会过期的。

Share

Chain of Responsibility Pattern

当你想让一个以上的对象有机会能够处理某个请求的时候,就使用责任链模式。

通过责任链模式,你可以为某个请求创建一个对象链。每个对象依次检查此请求,并对其进行处理,或者将它传给链中的下一个对象。

  • 将请求的发送者和接收者解耦
  • 可以简化你的对象,因为它不需要知道链的结构
  • 通过改变链内的成员或调用他们的次序,允许动态的新增或者删除责任。