今日得闲,想起过往一朋友问到的一个排列组合问题,在数组中{1,5,8,9}找出任意组合,所有数字之和累加值小于或等于14。 (即:不需要考虑顺序先后),列举所有的情况,并显示最终个数。现在提出一种思路,编码如下,抛砖引玉,探讨以资更好的方法。
import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; /** * 在数组中{1,5,8,9}找出任意组合,所有数字之和累加值小于或等于14。 (即:不需要考虑顺序先后),列举所有的情况,并显示最终个数。 * 简单思路: 排列组合,快速排序(归并排序) * @author Dennis Zhao * @createdTime:2012-5-24 JDK 1.6.0_17 */ public class AccumulateArith { private volatile String temp = ""; private int[] arr = { 1, 5, 8, 9 }; private volatile static int sum = 0; private volatile static List<String> list = new ArrayList<String>(64);//4 * 4 * 4 * 4 public static void main(String[] args) { for (int i = 0; i < 4; i++) { new AccumulateArith().generateData(i + 1, new AccumulateArith()); } filterCombination(list); System.out.println("符合条件的个数:" + sum); // System.out.println(list.size()); } /** * 产生所有可能数据的排列组合 generateData * * @param int count * @param AccumulateArith * acc * @return the void */ private void generateData(int count, AccumulateArith acc) { for (int i = 0, len = arr.length; i < len; i++) { this.temp = acc.temp + arr[i]; if (count == 1) { // System.out.println(this.temp); // sum++; // 去掉重复的 filterDuplicate(this.temp); } else if (count > 1) { new AccumulateArith().generateData(count - 1, this); } else { continue; } } } /** * 去掉重复字符的 filterDuplicate * * @param String * str * @return the void */ private void filterDuplicate(String str) { if (null != str && !"".equals(str.trim())) { Set<String> set = new HashSet<String>(0); String[] arr = new String[str.length()]; for (int i = 0, len = str.length(); i < len; i++) { arr[i] = (str.charAt(i) + ""); set.add(arr[i]); } if (set.size() > 0 && set.size() == str.length()) { list.add(str); // System.out.println(str); // sum++; } } } /** * 符合组合规则,无顺序 filterCombination * @param List * <String> sList * @return the void */ private static void filterCombination(List<String> sList) { if (null != sList && sList.size() > 0) { Map<String, String> map = new HashMap<String, String>(0); for (String str : sList) { char[] ch = str.toCharArray(); // quickSort(ch,0, ch.length -1);//faster sort mergeSort(ch,0, ch.length -1);//merge sort map.put(String.valueOf(ch), str); } Iterator<String> it = map.keySet().iterator(); for (; it.hasNext();) { String str = it.next(); int accSum = 0; for (int i = 0; i < str.length(); i++) { accSum += Integer.parseInt(str.charAt(i) + ""); } if (accSum <= 14) { System.out.println(str); sum++; } } } } /** * O(nlogn) * @param a * @param low * @param high */ private static void quickSort(char[] a, int low, int high) { if (low < high) { // 如果不加这个判断递归会无法退出导致堆栈溢出异常 int middle = getMiddle(a, low, high); quickSort(a, 0, middle - 1); quickSort(a, middle + 1, high); } } private static int getMiddle(char[] a, int low, int high) { char temp = a[low];// 基准元素 while (low < high) { // 找到比基准元素小的元素位置 while (low < high && a[high] >= temp) { high--; } a[low] = a[high]; while (low < high && a[low] <= temp) { low++; } a[high] = a[low]; } a[low] = temp; return low; } /** * O(NlogN) * @param a * @param left * @param right */ private static void mergeSort(char[] a, int left, int right) { if(left<right){ int middle = (left+right)/2; //对左边进行递归 mergeSort(a, left, middle); //对右边进行递归 mergeSort(a, middle+1, right); //合并 merge(a,left,middle,right); } } private static void merge(char[] a, int left, int middle, int right) { char[] tmpArr = new char[a.length]; int mid = middle+1; //右边的起始位置 int tmp = left; int third = left; while(left<=middle && mid<=right){ //从两个数组中选取较小的数放入中间数组 if(a[left]<=a[mid]){ tmpArr[third++] = a[left++]; }else{ tmpArr[third++] = a[mid++]; } } //将剩余的部分放入中间数组 while(left<=middle){ tmpArr[third++] = a[left++]; } while(mid<=right){ tmpArr[third++] = a[mid++]; } //将中间数组复制回原数组 while(tmp<=right){ a[tmp] = tmpArr[tmp++]; } } } /** * 测试效果如下: 59 58 19 18 15 158 1 5 9 8 符合条件的个数:10 */
2015-09-24
相关推荐
这是一款基于labveiw的累加求和的简易实现
我就废话不多说了,大家还是直接看代码吧! # -*- encoding=utf-8 -*- import pandas as pd data=['abc','abc','abc','asc','ase','ase','ase'] num=[1,2,2,1,2,1,2] df1=pd.DataFrame({'name':data,'num':num}) ...
用MPI实现一维数组求和,可以用任意进程来实现。上课时介绍的,就编了一个简单的代码,用VS生成exe文件,然后用MPICH就可以运行了。
分数累加求和的C程序,很实用。编写的是分数从1+1/2+1/3+1/4+。。。。的和
VB累加求和(函数过程计算)演示源程序,主要练习自定义函数的方法及使用,‘注意格式和参数以及调用函数的程序执行顺序。顺便说一下,调用函数过程,到这里后要跳到函数处执行函数,然后回来继续往下执行。这里定义了...
主要介绍了JS数组求和的常用方法,结合实例形式总结分析了5种数组求和的常见操作方法与相关处理技巧,需要的朋友可以参考下
实例20_函数过程_累加求和
JavaBean累加求和
包含 //声明一个整形数组 ...//求整形数组的累加和 //定义整形数组 //从键盘接收数据,为数组元素赋值 //求数组元素的累加和 //求数组元素的最大值 如何对变量a,b的值进行交换 //冒泡排序 //内重循环控制每趟排序
利用Excel MMULT函数实现数组累加.rar,本例主要利用了行序号与列序号的比较判断法,再将比较结果转换为数值后,再利用MMULT函数实现数组累加。
阶乘累加求和.py
382281206315985累加求和.exe
也许用高级语言实现累加求和难不倒谁但是,你想到过用最低级的汇编做过吗,你必须考虑到数制的转换,每个变量如何存储,所有东东都得自己去管理 本软件在Masm for Windows 集成实验环境 2008.3中开发
累加数组中的值
累加求和算pi.cpp
js 遍历数组取出字符串用逗号拼接;js 如何获取循环出来的最后一个i或者取i的最大值
主要介绍了Java lambda 循环累加求和代码,具有很的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
本章主要介绍数组的概念及定义,并简单介绍了数组的引用传递,及数组的动态、静态初始化及二维数组的定义和使用。
内容索引:VB源码,其它类别,函数,累加,算法 VB累加求和(函数过程计算)演示源程序,主要练习自定义函数的方法及使用,‘注意格式和参数以及调用函数的程序执行顺序。顺便说一下,调用函数过程,到这里后要跳到函数...