范式理论的程序设计(二)
程序员文章站
2022-05-08 11:22:51
...
关于数据库范式理论的程序设计 - SequenceUtils
这里我使用的工具类全部都是使用接口,public interface SequenceUtils是本程序中所有算法的基类。就是后面的算法都会用到该接口中的默认实现方法,继承关系如下:
SequenceUtils的default方法
里面都是一些关于后面算法会用到的字符序列的方法,里面的方法的参数基本都是用CharSequence接口声明,CharSequence的实现类主要有String,StringBuffer,StringBuilder。所有方法都是便于组合使用。
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]
}
推荐阅读
-
PHP 面向对象程序设计(oop)学习笔记 (二) - 静态变量的属性和方法及延迟绑定
-
PHP 面向对象程序设计(oop)学习笔记 (二) - 静态变量的属性和方法及延迟绑定
-
关系型数据库理论——范式的分类与判断
-
国家自然奖二等奖:基于不充分信息的机器学习理论与方法研究
-
USB驱动程序设计之二(Linux USB架构及相关的USB协议)
-
JavaScript高级程序设计(第四版)学习笔记(第二章 HTML中的JavaScript)
-
深度学习入门基于Python的理论与实现_第二章_感知机
-
高二学生爆肝10个月!在《我的世界》里打造理论最快计算器
-
PHP 面向对象程序设计(oop)学习笔记 (二) - 静态变量的属性和方法及延迟绑定_php实例
-
javascript高级程序设计第二版第十二章事件要点总结(常用的跨浏览器检测方法)_javascript技巧