Java实现通用组合算法

发表于:2011-12-27 09:36

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:未知    来源:51Testing软件测试网采编

#
java
分享:

  Java实现通用组合算法,存在一个类似{31311133,33113330}这样的集合,经过8取5组合,其他位置用非字母数字字符替代,比如使用*号,得到类似{3***1133,***13330,... ...}这样的集合;

  现在有这样的需求:

  存在一个类似{31311133,33113330}这样的集合,经过8取5组合,其他位置用非字母数字字符替代,比如使用*号,得到类似{3***1133,***13330,... ...}这样的集合;

  还要求对于{3***1133,***13330}这样的集合,再次经过5取3组合,其他位置用非字母数字字符替代,比如使用*号,得到类似{*****133,*****330,3***1*3*,... ...}这样的集合。

  对于这样的要求,实现的思路如下:

  首先,主要思想是基于信息编码原理,通过扫描字符串,将10组合变为01组合。

  其次,对于每个数字字符串,设置一个单线程,在单线程类中设置一个List用来存放待处理数字字符串(可能含有*号,或者不含有)中每个数字的(而非*号)索引位置值;

  再次,设置BitSet来标志每个位置是否被*号替换得到新的组合字符串。

  最后,在扫描原始待处理数字字符串的过程中,根据设置的字符列表List中索引,来操作BitSet,对于每一个BitSet得到一个新的组合。

  使用Java语言实现如下:

  1. package org.shirdrn;    
  2. import java.util.ArrayList;    
  3. import java.util.BitSet;    
  4. import java.util.Collection;    
  5. import java.util.Collections;    
  6. import java.util.HashSet;    
  7. import java.util.Iterator;    
  8. import java.util.List;   
  9. /** 
  10. * 通用组合拆分类(基于单线程) 
  11. * 可以完成两种功能: 
  12. * 第一,可以将完全数字串拆分成为含有*号的字符串。 
  13. * 例如:输入集合{31311133,33113330},Splitter类会遍历该集合,对每个字符串,创建一个SplitterThread 
  14. * 线程来处理,如果是2取1组合,即starCount=8-2=6,经过线程处理得到类似******33,*****1*3等结果 
  15. * 第二,根据从带有*号的字符串经过拆分过滤后得到的字符串集合,对其中每一个字符串进行组合 
  16. * 例如:输入集合5取1组合字符串集合{3***1133,***113330} 
  17. * CommonSplitter类会遍历该集合,对每个带有*号的字符串,创建一个SplitterThread 
  18. * 线程来处理,如果是2串1组合,即starCount=8-3-2=3,经过线程处理得到类似******33,*****1*3等结果 
  19. * @author 时延军 
  20. */ 
  21. public class CommonSplitter {  
  22. private int starCount;  
  23. private boolean duplicate;  
  24. private Collection filteredContainer;  
  25. public Collection getFilteredContainer() {  
  26. return filteredContainer;  
  27. }  
  28. /** 
  29. * 构造一个Spilitter实例 
  30. * @param container 输入的待处理字符串集合 
  31. * @param starCount 如果对于长度为N的数字字符串,进行M组合(即N取M),则starCount=N-M 
  32. * @param duplicate 是否去重 
  33. */ 
  34. public CommonSplitter(Collection container, int starCount, boolean duplicate) {  
  35. this.duplicate = duplicate;  
  36. this.starCount = starCount;  
  37. if(this.duplicate) { // 根据指定是否去重的选择,选择创建容器 
  38. filteredContainer = Collections.synchronizedSet(new HashSet());  
  39. }  
  40. else {  
  41. filteredContainer = Collections.synchronizedList(new ArrayList());  
  42. }  
  43. Iterator it = container.iterator();  
  44. while(it.hasNext()) {  
  45. new Thread(new SplitterThread(it.next().trim())).start();  
  46. }  
  47. try {  
  48. Thread.sleep(50);  
  49. catch (InterruptedException e) {  
  50. e.printStackTrace();  
  51. }  
  52. }  
  53. /** 
  54. * 对一个指定的N场比赛的长度为N的单式投注字符串进行组合 
  55. * 输入单式投注注字符串string,例如31311133,组合得到类似******33,*****1*3,... ...结果的集合 
  56. * 
  57. * @author 时延军 
  58. */ 
  59. class SplitterThread implements Runnable {  
  60. private char[] charArray;  
  61. private int len; // 数字字符的个数 
  62. List occupyIndexList = new ArrayList(); // 统计字符串中没有带*的位置的索引 
  63. private List container = new ArrayList();  
  64. private BitSet startBitSet; // 比特集合起始状态 
  65. private BitSet endBitSet; // 比特集合终止状态,用来控制循环 
  66. public SplitterThread(String string) {  
  67. this.charArray = string.toCharArray();  
  68. this.len = string.replace("*""").length();  
  69. this.startBitSet = new BitSet(len);  
  70. this.endBitSet = new BitSet(len);  
  71. // 初始化startBitSet,左侧占满*符号 
  72. int count = 0// 
  73. for (int i=0; i  
  74. if(charArray[i] != '*') {  
  75. if(count < starCount) {  
  76. this.startBitSet.set(i, true);  
  77. count++;  
  78. }  
  79. occupyIndexList.add(i);  
  80. }  
  81. }  
  82. // 初始化endBit,右侧占满*符号 
  83. count =0;  
  84. for (int i = string.length()-1; i > 0; i--) {  
  85. if(charArray[i] != '*') {  
  86. if(count < starCount) {  
  87. this.endBitSet.set(i, true);  
  88. count++;  
  89. }  
  90. ccupyIndexList.add(i);  
  91. }  
  92. }  
  93. // 根据起始startBitSet,构造带*的组合字符串并加入容器 
  94. char[] charArrayClone = this.charArray.clone();  
  95. for (int i=0; i  
  96. if (this.startBitSet.get(i)) {  
  97. charArrayClone[i] = '*';  
  98. }  
  99. }  
  100. this.container.add(new String(charArrayClone));  
  101. }  
  102. public void run() {  
  103. this.split();  
  104. synchronized(filteredContainer) {  
  105. filteredContainer.addAll(this.container);  
  106. }}  
  107. public void split() {  
  108. while(!this.startBitSet.equals(this.endBitSet)) {  
  109. int zeroCount = 0// 统计遇到10后,左边0的个数 
  110. int oneCount = 0// 统计遇到10后,左边1的个数 
  111. int pos = 0// 记录当前遇到10的索引位置 
  112. char[] charArrayClone = this.charArray.clone();  
  113. // 遍历startBitSet来确定10出现的位置 
  114. for (int i=0; i  
  115. if (!this.startBitSet.get(this.occupyIndexList.get(i))) {  
  116. zeroCount++;  
  117. }  
  118. if (this.startBitSet.get(this.occupyIndexList.get(i))  
  119. && !this.startBitSet.get(this.occupyIndexList.get(i+1))) {  
  120. pos = i;  
  121. oneCount = i - zeroCount;  
  122. // 将10变为01 
  123. this.startBitSet.set(this.occupyIndexList.get(i), false);  
  124. this.startBitSet.set(this.occupyIndexList.get(i+1), true);  
  125. break;  
  126. }  
  127. }  
  128. // 将遇到10后,左侧的1全部移动到最左侧 
  129. int count = Math.min(zeroCount, oneCount);  
  130. int startIndex = this.occupyIndexList.get(0);  
  131. int endIndex = 0;  
  132. if(pos>1 && count>0) {  
  133. pos--;  
  134. endIndex = this.occupyIndexList.get(pos);  
  135. for (int i=0; i  
  136. this.startBitSet.set(startIndex, true);  
  137. this.startBitSet.set(endIndex, false);  
  138. startIndex = this.occupyIndexList.get(i+1);  
  139. pos--;  
  140. if(pos>0) {  
  141. endIndex = this.occupyIndexList.get(pos);  
  142. }  
  143. }}  
  144. // 将遇到1的位置用*替换 
  145. for (int i=0; i  
  146. if (this.startBitSet.get(this.occupyIndexList.get(i))) {  
  147. charArrayClone[this.occupyIndexList.get(i)] = '*';  
  148. }  
  149. }  
  150. this.container.add(new String(charArrayClone));  
  151. }  
  152. }}}

21/212>
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号