欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

范式理论的程序设计(二)

程序员文章站 2022-05-08 11:22:51
...

关于数据库范式理论的程序设计 - SequenceUtils

这里我使用的工具类全部都是使用接口,public interface SequenceUtils是本程序中所有算法的基类。就是后面的算法都会用到该接口中的默认实现方法,继承关系如下:
范式理论的程序设计(二)

SequenceUtils的default方法

里面都是一些关于后面算法会用到的字符序列的方法,里面的方法的参数基本都是用CharSequence接口声明,CharSequence的实现类主要有StringStringBufferStringBuilder。所有方法都是便于组合使用。
范式理论的程序设计(二)

isEmpty(),deDuplicate(),sort()方法

1. 方法代码

    /**
     * 描述:字符序列是否为空
     * @param sequence String
     * @return boolean
     */
    default boolean isEmpty(CharSequence sequence) {
        return sequence == null || "".equals(sequence.toString());
    }


    /**
     * 描述:对字符序列进行排序
     *      ABC = sort(CAB);
     * @param sequence 字符串
     * @return 排序(升序)的String
     */
    default CharSequence sort(CharSequence sequence) {
        final char[] array = sequence.toString().toCharArray();
        Arrays.sort(array);
        return String.valueOf(array);
    }

    /**
     * 描述:消除字符序列的重复字符,保留第一次出现的子串
     * @param sequence CharSequence
     * @return 去重后的String
     */
    default CharSequence deDuplicate(CharSequence sequence) {
        final StringBuffer sb = new StringBuffer();
        final Set<Character> set = new HashSet<>();
        for (int i = 0; i < sequence.length(); i++) {
            final char c = sequence.charAt(i);
            if (set.add(c)) {
                sb.append(c);
            }
        }
        return sb;
    }

    /**
     * 描述:Collection<Character>转换为字符序列
     * @param characters Character
     * @return CharSequence
     */
    default CharSequence collectionToSequence(Collection<Character> characters) {
        final StringBuffer buffer = new StringBuffer();
        characters.forEach(buffer::append);
        return buffer;
    }

2. 测试代码(Junit)

import com.ruoxing.dbs.util.SequenceUtils;
import org.junit.Test;
import java.util.*;
/**
 * 描述:对SequenceUtils的测试
 */
public class Test1 implements SequenceUtils {

}
    @Test
    public void test01() {
        String s1 = "ADDCBB";
        String s2 = "";
        String s3 = null;
        System.out.println("isEmpty(s1)=" + isEmpty(s1));//isEmpty(s1)=false
        System.out.println("isEmpty(s2)=" + isEmpty(s2));//isEmpty(s2)=true
        System.out.println("isEmpty(s3)=" + isEmpty(s3));//isEmpty(s3)=true
        System.out.println("------------------------------");
        System.out.println("deDuplicate(s1)=" + deDuplicate(s1));//deDuplicate(s1)=ADCB
        System.out.println("sort(s1)=" + sort(s1));//sort(s1)=ABBCDD
        //sort()和deDuplicate()组合,在函数依赖、闭包等定义中很方便
        System.out.println("s1去重、排序后:" + sort(deDuplicate(s1)));//s1去重、排序后:ABCD

    }

intersect(),union(),except()交并补方法

这些方法后面函数依赖,属性闭包,范式分解等都会用到

1. 方法代码

    /**
     * 描述:两个字符序列的并集(不考虑顺序和重复)
     *    等价于:sort(deDuplicate(StringA + StringB));
     * @param sequenceA CharSequence
     * @param sequenceB CharSequence
     * @return CharSequence
     */
    default CharSequence union(CharSequence sequenceA, CharSequence sequenceB) {
        final Set<Character> set = new HashSet<>();
        for (int i = 0; i < sequenceA.length(); i++) {
            set.add(sequenceA.charAt(i));
        }
        for (int i = 0; i < sequenceB.length(); i++) {
            set.add(sequenceB.charAt(i));
        }
        return collectionToSequence(set);
    }


    /**
     * 描述:两个字符序列的差集A-B(不考虑顺序和重复)
     *    等价于:String temp = sort(deDuplicate(StringA)).replace(sort(deDuplicate(StringB)), "") + StringA
     *           sort(deDuplicate(temp));
     * @param sequenceA CharSequence
     * @param sequenceB CharSequence
     * @return CharSequence
     */
    default CharSequence except(CharSequence sequenceA, CharSequence sequenceB) {
        final Set<Character> setA = new HashSet<>();
        for (int i = 0; i < sequenceA.length(); i++) {
            setA.add(sequenceA.charAt(i));
        }
        for (int i = 0; i < sequenceB.length(); i++) {
            setA.remove(sequenceB.charAt(i));
        }
        return collectionToSequence(setA);
    }

    /**
     * 描述:两个字符序列是否含有相同字符(不考虑顺序和重复)
     *     等价于:sort(deDuplicate(StringA)).equals(sort(deDuplicate(StringB)))
     * @param sequenceA CharSequence
     * @param sequenceB CharSequence
     * @return boolean
     */
    default boolean equals(CharSequence sequenceA, CharSequence sequenceB) {
        final Set<Character> setA = new HashSet<>();
        final Set<Character> setB = new HashSet<>();
        for (int i = 0; i < sequenceA.length(); i++) {
            setA.add(sequenceA.charAt(i));
        }
        for (int i = 0; i < sequenceB.length(); i++) {
            setB.add(sequenceB.charAt(i));
        }
        return setA.equals(setB);
    }

2. 测试代码

    @Test
    public void test02() {
        String A = "DCCBB";
        String B = "ABCC";
        //A与B都包含的字符
        System.out.println("A ∩ B=" + intersect(A, B));//A ∩ B=BC
        //A和B共同包含的字符
        System.out.println("A ∪ B=" + union(A, B));//A ∪ B=ABCD
        //A中包含但B中不包含的字符
        System.out.println("A - B=" + except(A, B));//A - B=D
    }

equals(),contains()方法

1. 方法代码

/**
     * 描述:两个字符序列是否含有相同字符(不考虑顺序和重复)
     *     等价于:sort(deDuplicate(StringA)).equals(sort(deDuplicate(StringB)))
     * @param sequenceA CharSequence
     * @param sequenceB CharSequence
     * @return boolean
     */
    default boolean equals(CharSequence sequenceA, CharSequence sequenceB) {
        final Set<Character> setA = new HashSet<>();
        final Set<Character> setB = new HashSet<>();
        for (int i = 0; i < sequenceA.length(); i++) {
            setA.add(sequenceA.charAt(i));
        }
        for (int i = 0; i < sequenceB.length(); i++) {
            setB.add(sequenceB.charAt(i));
        }
        return setA.equals(setB);
    }

    /**
     * 描述:sequenceA的序列是否包含了sequenceB的序列(不考虑顺序问题)
     *      等价于:sort(deDuplicate(sequenceA)).contains(sort(deDuplicate(sequenceB)))
     *          或:sort(deDuplicate(sequenceA)).startsWith(sort(deDuplicate(sequenceB)))
     * @param sequenceA CharSequence
     * @param sequenceB CharSequence
     * @return boolean
     */
    default boolean contains(CharSequence sequenceA, CharSequence sequenceB) {
        for (int i = 0; i < sequenceB.length(); i++) {
            final char c = sequenceB.charAt(i);
            boolean temp = true;
            for (int j = 0; j < sequenceA.length(); j++) {
                if (c == sequenceA.charAt(j)) {
                    temp = false;
                    break;
                }
            }
            if (temp) return false;
        }
        return true;
    }

    /**
     * 描述:字符集Collection<Character>是否包含了组成CharSequence的所有字符
     * @param characters Collection<Character> 字符集
     * @param sequence 字符序列
     * @return boolean
     */
    default boolean contains(Collection<Character> characters, CharSequence sequence) {
        for (int i = 0; i < sequence.length(); i++) {
            if (!characters.contains(sequence.charAt(i))) return false;
        }
        return true;
    }

2. 测试代码

    @Test
    public void test03() {
        String A = "ABCC";
        String B = "ABBCCAA";
        String C = "ADC";
        String D= "ADCE";
        //A中的字符B中都有并且B中字符A中都有???
        System.out.println("equals(A, B)=" + equals(A, B));//equals(A, B)=true
        //A中的字符C中都有并且C中字符A中都有???
        System.out.println("equals(A, C)=" + equals(A, C));//equals(A, C)=false

        //C中的字符D中都有???
        System.out.println("contains(D, C)=" + contains(D, C));//contains(D, C)=true
        //D中的字符C中都有???
        System.out.println("contains(C, D)=" + contains(C, D));//contains(C, D)=false
    }

permutation(),combination()排列与组合方法

permutation()方法主要用于间接实现combination()方法。
combination()方法再后面的算法中等价于属性集R的的子集,会非常有用。

1. 方法代码

    /**
     * 描述:字符序列的[排列]的Collection
     * @param sequence CharSequence 字符序列
     * @return Collection<String>
     */
    default Collection<String> permutation(CharSequence sequence) {
        final Collection<Character> source = new ArrayList<>();
        for (int i = 0; i < sequence.length(); i++) {
            source.add(sequence.charAt(i));
        }
        final List<String> target = new ArrayList<>();
        permutationByRecursion(source, "", target);
        return target;
    }

    /**
     * 描述:字符序列的[组合]的Collection
     * @param sequence CharSequence 字符序列
     * @return Collection<String>
     */
    default Collection<String> combination(CharSequence sequence) {
        final Collection<String> target = new HashSet<>();
        permutation(sequence).forEach(s -> target.add(sort(s).toString()));
        return target;
    }

    /**
     * 描述:递归求字符集合的排列
     * @param source 字符集
     * @param s 当前递归的字符串
     * @param target 存放排列的List集合
     */
    default void permutationByRecursion(Collection<Character> source, String s, List<String> target) {
        for(int i = 0; i <source.size() ; i++){
            List<Character> temp = new ArrayList<>(source);
            final String kind = s + temp.remove(i);
            target.add(kind);
            permutationByRecursion(temp , kind, target);
        }
    }

2. 测试代码

@Test
    public void test04() {
        String A = "CBA";
        System.out.println("A中字符的排列方式有:");
        final Collection<String> permutation = permutation(A);
        System.out.println(permutation);//[C, CB, CBA, CA, CAB, B, BC, BCA, BA, BAC, A, AC, ACB, AB, ABC]

        System.out.println("A中字符的组合(相当于A的子集)方式有:");
        final Collection<String> combination = combination(A);
        System.out.println(combination);//[BC, AB, A, ABC, AC, B, C]
    }

上一篇: 女人的名字 

下一篇: 请走后门