一、黑马2013年java学科开班查询工具(论坛上得技术分的题目)
1.要求:
实现代码如下:
- import java.awt.Button;
- import java.awt.Color;
- import java.awt.FlowLayout;
- import java.awt.Frame;
- import java.awt.TextArea;
- import java.awt.TextField;
- import java.awt.event.ActionEvent;
- import java.awt.event.ActionListener;
- import java.awt.event.MouseAdapter;
- import java.awt.event.MouseEvent;
- import java.awt.event.WindowAdapter;
- import java.awt.event.WindowEvent;
- import java.io.BufferedReader;
- import java.io.IOException;
- import java.io.InputStream;
- import java.io.InputStreamReader;
- import javax.swing.ButtonGroup;
- import javax.swing.JRadioButton;
- import com.itheima.bbs.querytime.ClassStartingTimeQuery;
- public class ClassStartingDateQuery {
- private Frame frame;
- private Button button;
- private TextField textField;
- private TextArea textArea;
- private JRadioButton cloudRadButton;
- private JRadioButton androidRadioButton;
- public ClassStartingDateQuery(){
- init();
- }
- private void init() {
- //初始化窗口
- frame = new Frame("2013年黑马Java学科开班日期查询");
- frame.setBounds(300, 300, 400, 280);//设置窗口大小
- frame.setLayout(new FlowLayout());
- frame.setResizable(false);//窗口大小固定
- //初始化输入区和显示区
- textField=new TextField(30);
- textField.setText("请安“第xx期”格式输入");
- textArea = new TextArea("",10, 50,TextArea.SCROLLBARS_VERTICAL_ONLY);
- textArea.setEditable(false);//显示区设为不可编辑
- textArea.setBackground(Color.WHITE);//显示区背景色改为白色。
- //初始化查询按钮
- button=new Button("查询");
- //定义单选按钮,并将安卓课程定义为默认选项
- cloudRadButton=new JRadioButton("JavaEE+物联云计算课程");
- androidRadioButton = new JRadioButton("JavaEE+Android课程");
- androidRadioButton.setSelected(true);
- //定义单选按钮互斥区
- ButtonGroup buttonGroup = new ButtonGroup();
- buttonGroup.add(cloudRadButton);
- buttonGroup.add(androidRadioButton);
- //将以上组件添加到窗口上。
- frame.add(androidRadioButton);
- frame.add(cloudRadButton);
- frame.add(textField);
- frame.add(button);
- frame.add(textArea);
- myEvent();
- frame.setVisible(true);
- }
- private void myEvent() {
- frame.addWindowListener(new WindowAdapter() {
- public void windowClosing(WindowEvent e) {
- //关闭窗口
- System.exit(0);
- }
- });
- textField.addMouseListener(new MouseAdapter() {
- public void mousePressed(MouseEvent e){
- //鼠标进入输入区时,输入区内容清空,并在显示区提示要查询的期数限制
- textField.setText("");
- textArea.setText("2013年黑马训练营有:\n" +
- "JavaEE+物联云计算课程\t第02期~第10期\n" +
- "JavaEE+Android课程 \t第17期~第24期\n");
- }
- });
- button.addActionListener(new ActionListener() {
- @Override
- public void actionPerformed(ActionEvent e){
- //判读field输入的询格式是否正确
- String editionName = null;
- if(textField.getText().matches("第\\d{2,}期")){//判断输入格式是正确
- editionName = textField.getText();
- }else{
- textArea.setText("查询格式错误!请按“第**期”输入,如“第04期”");
- return;//格式不正确就直接返回。
- }
- //获取选定的是哪个个课程
- String courseName =null;
- if(cloudRadButton.isSelected()){
- courseName=cloudRadButton.getText();
- }else{
- courseName=androidRadioButton.getText();
- }
- //根据上边的两个条件查询日期,并显示在显示区
- String classStartingTime = queryTime(editionName,courseName);
- textArea.setText(classStartingTime);
- }
- });
- }
- private String queryTime(String editionName,String courseName) {
- BufferedReader bufr=null;
- try {
- //通过该类的类加载器加载资源文件。
- InputStream is=ClassStartingTimeQuery.class.getResourceAsStream("data.txt");
- //定义缓冲区
- bufr=new BufferedReader(new InputStreamReader(is));
- String buf =null;
- while((buf=bufr.readLine())!=null){
- //判断改行有没有要查询的两个条件,有则返回该行包含的日期
- if(buf.contains(editionName)&&buf.contains(courseName)){
- //得到该行包含的日期
- String [] strs = buf.split(" ");
- return strs[0]; //其实return buf,也可以,但既然前边都判断过了,这里还是处理下。
- }
- }
- } catch (Exception e) {
- e.printStackTrace();
- }finally{
- try {
- //关闭资源
- if(bufr!=null)
- bufr.close();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- //如果没有查询到,则提示没有该期的课程
- return courseName+"2013年没有该期("+editionName+")的黑马培训班";
- }
- public static void main(String[] args) {
- new ClassStartingDateQuery();
- }
- }
3、运行结果:
二、
1.题 目:给定一个数t,以及n个整数,在这n个整数中找到相加之和为t的所有组合, 例如t = 4,n = 6,这6个数为[4, 3, 2, 2, 1, 1], 这样输出就有4个不同的组合,它们的相加之和为 4:4, 3+1, 2+2, and 2+1+1。 请设计一个高效算法实现这个需求。
2.解题思路:
1.判断这n个数之和是否为t,是在将其打印
2.从n个数中取出一个数,判断剩余数之和是否为t,循环n次;
3.每个循环内部又转到1,当求和元素只有两个时退出(求和最少得有2个元素)。
进一步分析:
从上边得到打印出的结果,会出现重复,所以,将每次筛选出的组合存入TreeSet中,最后再打印TreeSet集合。
3.代码实现:
- import java.util.ArrayList;
- import java.util.Arrays;
- import java.util.List;
- import java.util.TreeSet;
- public class NumberGroup {
- private static TreeSet<String> ts = new TreeSet<String>();
- public static void main(String[] args) {
- Integer [] arr = {15,16,17,18,-1,-2,-3,0};
- int key = 15;
- //先对数组排序,以使其打印结果有序。
- Arrays.sort(arr);
- //一开始用List的时候,filterNumGroup会报错,故转成ArrayList
- List<Integer> list=Arrays.asList(arr);
- ArrayList<Integer> nums=new ArrayList<Integer>(list);
- //筛选组合
- filterNumGroup(nums, key);
- //打印结果
- for(String str:ts){
- System.out.println(str);
- }
- }
- public static void filterNumGroup(ArrayList<Integer> nums,int key){
- if(key==getSum(nums)){
- ts.add(getNumbers(nums));
- }else{
- if(nums.size()>2){//此处如果2改为1,则会筛选出跟key(即t)相等的元素。
- //思路中的第2步。
- for(int index=0;index<nums.size();index++){
- //此处,不能写成numsClone=nums,因为这样做它们指向的是同一个元素。
- ArrayList<Integer> numsClone=new ArrayList<Integer>(nums);
- numsClone.remove(index);
- filterNumGroup(numsClone,key);//递归调用
- }
- }
- }
- }
- //求和
- public static int getSum(List<Integer> nums){
- int sum=0;
- for(Integer num:nums ){
- sum+=num;
- }
- return sum;
- }
- //将每一个组合转成String
- public static String getNumbers(List<Integer> nums) {
- StringBuilder sb = new StringBuilder();
- for(Integer num:nums){
- sb.append(num+" ");
- }
- return sb.toString();
- }
- }
小 结:上面的代码只是实现了功能,算不上高效。其实上边的题目和求多元方程(某一范围内)解的题目,都可以归为从M个数中取出N个数并进行排列组合的问题,利用穷举法举出所有的组合,然后让计算机根据判断条件(方程式)进行筛选。