[一天一项目] 获取m个数中和等与k的n个数
来源:互联网 发布:c语言 表达式的值 编辑:程序博客网 时间:2024/06/05 18:33
今天在CSDN问答看到一个关于递归算法的求值题。觉得很有意思。现在把题目和我自己的答案写下来。
有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
阅读全文
0 0
- [一天一项目] 获取m个数中和等与k的n个数
- m个数分成n个数的和
- N个数求最大的k个数
- n 个数中最小的 k 个数
- hdu3415 Max Sum of Max-K-sub-sequence(单调队列求n个数中和的最大值)
- 等概率无重复的从n个数中选取m个数
- 等概率无重复的从n个数中选取m个数
- 想一想如何从M个数中随机等可能的取出N个数
- 等概率无重复的从n个数中选取m个数
- 从M个数中随机选出N个数的所有组合,无序,(一)
- 从n个数挑k个,和等于m
- n个数中选m个数的全组合...
- 求n个数选m个数的组合数
- 从m个数中选n个数的排列
- 在m个数中寻找最大的n个数
- n个数中随机产生不重复的m个数
- 从m个数中任意去n个数的组合
- 从1-n中选择m个数的组合个数
- 最全Pycharm教程(2)——代码风格
- java SimpleDateFormat类介绍
- download chromedriver from mirror website
- Android图片处理总结四:双击图片,保持点击位置不变放大
- Java实现2048
- [一天一项目] 获取m个数中和等与k的n个数
- java用递归算法求1~100的和
- source insight 4 破解版可用
- Python3 异常处理
- 素数筛法打表
- linux下root用户以及非root用户忘记密码的解决方案
- CodeForces
- HDU 6069 Counting Divisors -质因子个数-2017多校联盟4 第3题
- 万维链的原生币万维币在万维链上线后有什么作用?