[一天一项目] 获取m个数中和等与k的n个数
2017-08-04 13:26
344 查看
今天在CSDN问答看到一个关于递归算法的求值题。觉得很有意思。现在把题目和我自己的答案写下来。
如果这题不考虑重复数据的话会简单很多,在初始值生成的时候,用set接受排除重复数据影响就行,之后的操作就很简单了。为了重复数据for到快吐了~~很难受。
查了资料这个题可以用递归算法和回溯算法(对此没有研究,所以知其然而不知其所以然)。同样难受
解题方法很多很多,如果你有更多的更好的解决方法,欢迎交流!谢谢
代码合集:https://github.com/FanceTsui/Project.git
——Fance Tsui
a6f1
有m个数(有重复值),如果其中的n(n不固定,即可设定)个数的值为k(可设定,不固定)。那么这样的n组合有哪些?
package com.project.GetNNumCount; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Scanner; public class getNNumCount { private static int NUM = 0; private static int count = 0; //因为项目中存在重复数据,所以没有办法用set存储,导致最后生成的list会出现重复数据 public static void main(String[] args) { Scanner input = new Scanner(System.in); System.out.println("请输入X个数,用逗号分割:"); String str = input.nextLine(); String[] datas = str.split(","); System.out.println("请输入数字M:"); NUM = input.nextInt(); System.out.println("请输入数字N:"); count = input.nextInt(); if (NUM > datas.length) { System.out.println("输入的Y必须小于等于X!"); return; } combine(Arrays.asList(datas)); } private static void combine(List<String> datas) { List<String> list = new ArrayList<String>(); String tmp; //对初始数组进行排序,为后续结果集筛选做准备 /** * 排序前后差别 * 排序前:比如 1,3,1,3 2个数相加 得到 4 * 有[1,3],[1,3],[3,1],[3,1],[1,3]几种可能 * 排序后:1,1,3,3 有[1,3],[1,3],[1,3],[1,3]几种可能 * 对后面的重复list判断帮助很大 * */ for (int i = 0; i < datas.size() - 1; i++) { for (int j = 1; j < datas.size() - i; j++) { int data_1 =Integer.parseInt(datas.get(j)); int data_2 =Integer.parseInt(datas.get(j-1)); if (data_2 > data_1) { tmp = datas.get(j); datas.set(j,datas.get(j-1)); datas.set(j-1,tmp); } } } for(String str : datas) { list.add(str); //查看排序后的值 //System.out.println(str); } ArrayList<List<String>> subset = getSubset(list); getNumCount(subset,count); } public static String[] getBinaryValue(List<String> datas) { int size = datas.size(); int m = (int) Math.pow(2, size) - 1; String[] result = new String[m + 1]; for (int i = m; i > -1; i--) { StringBuffer sb = new StringBuffer(Integer.toBinaryString(i)); int length = sb.length(); if (length < size) { for (int j = 0; j < size - length; j++) { sb.insert(0, "0"); } } result[i] = sb.toString(); } return result; } public static ArrayList<List<String>> getSubset(List<String> datas) { ArrayList<List<String>> result = new ArrayList<List<String>>(); String[] items = new String[datas.size()]; int i = 0; for (String item : datas) { items[i++] = item; } String[] binaryValue = getBinaryValue(datas); for (int j = 0; j < binaryValue.length; j++) { String value = binaryValue[j]; List<String> subset = new ArrayList<String>(); for (int k = 0; k < value.length(); k++) { if (value.charAt(k) == '1') subset.add(items[k]); } if (subset.size() == NUM) result.add(subset); } return result; } //获取到最后的list,需要进行最后的筛选 public static void getNumCount(ArrayList<List<String>> subset, int count) { int count_new = 0; List<List<String>> list = new ArrayList<List<String>>(); for (List<String> ts : subset) { count_new = 0; for (String num : ts) { count_new += Integer.parseInt(num); } //判断是否符合所要求的总和 if (count_new == count) { //如果list长度大于0,就开始与后一个list进行比较 if(list.size() == 0){ list.add(ts); }else{ //如果两个list内容不相同,就添加到list中 if(!list.get(list.size()-1).equals(ts)){ list.add(ts); } } } } for(List<String> list1 : list){ System.out.println(list1); } System.out.println("break"); } }
如果这题不考虑重复数据的话会简单很多,在初始值生成的时候,用set接受排除重复数据影响就行,之后的操作就很简单了。为了重复数据for到快吐了~~很难受。
查了资料这个题可以用递归算法和回溯算法(对此没有研究,所以知其然而不知其所以然)。同样难受
解题方法很多很多,如果你有更多的更好的解决方法,欢迎交流!谢谢
代码合集:https://github.com/FanceTsui/Project.git
——Fance Tsui
a6f1
相关文章推荐
- [一天一项目]获取当前天气——获取某个地区当前的天气情况。
- [一天一项目]获取当前天气——获取某个地区当前的天气情况。
- 代码空间项目 -- 获取当前时间之前的某一天-Calender类的使用
- 项目供参考Asp.net C# 获取本周上周本月上月本年上年第一天最后一天时间大全
- c# 获取某日期所在周的第一天和最后一天
- iOS获取当前时间及前一天或后一天时间
- WEB 获取项目部署根目录
- Web项目中JSP获取MY SQL数据库简单例子
- 在JAVA web中获取该项目的相对路径和绝对路径
- javascript获取某月最后一天(公历)
- java中类加载路径和项目根路径获取的几种方式
- Java获取月份第一天和最后一天日期
- js获取项目根路径
- 获取Web项目路径
- 安卓如何做到当在未来的某一天触发一些事件,获取网络时间
- web项目的servlet和filter中获取spring上下文
- java取得项目工程---获取文件的相对路径问题---getResource()和getResourceAsStream以及路径问题
- js获取当月的最后一天
- “无法从web服务器获取项目文件” 解决方案(转)
- 获取当前月的第一天和最后一天...