• 奇妙的算法【8】筹钱种数、定时找出最高频次的数据、三子棋落点判断


    1,筹钱种数

      有几种不同币值的钱币,求有多少种可能情况凑成m元钱

      咔咔,直接递归调用超级简单。

    package com.cnblogs.mufasa.Main1;
    
    import java.util.Arrays;
    import java.util.Scanner;
    
    public class Solution {
    
        public static int RecuDeal(int[] nums,int sum,int index){
            int cont=0;
            if(index==nums.length-1){//1,退出条件:只有最后一个数据选项
                if(sum%nums[index]==0){//1,1可以匹配上,余数为0
                    cont= 1;
                }else {//1,2 无法匹配上,余数不为零
                    cont= 0;
                }
            }else {//2,还有多个数据可以选择,进一步进行拆分递进递归
                int temp=sum/nums[index];
                for(int i=0;i<=temp;i++){
                    cont+=RecuDeal(nums,sum-nums[index]*i,index+1);//递归节点
                }
            }
            return cont;
        }
    
        public static void main(String[] args) {
    
            //1,测试
            int[] nums=new int[]{5,2,1};
            int sum=10;
    
            //2,输入
    //        Scanner sc=new Scanner(System.in);
    //        String[] strs=sc.nextLine().split(" ");
    //        int sum=sc.nextInt();
    //        int[] nums=new int[strs.length];
    //        for(int i=0;i<strs.length;i++){
    //            nums[i]=Integer.valueOf(strs[i]);
    //        }
    
            //3,输出
            System.out.println(RecuDeal(nums,sum,0));//输出结果为10正确
        }
    }
    /*
    5 2 1
    10
    
     */

    2,计算机日志报告使用频次

      输出每五分钟内使用频次最大的数据频次及其名称

      咔咔,①使用Node节点类型将这个对象进行实例化,方便计算时间,存储名称;②使用hashMap来进行频次的统计,key为我们定义的数据

    package com.cnblogs.mufasa.Main2;
    
    import java.util.*;
    
    class myDate{
        int year;
        int month;
        int day;
        int hour;
        int min;
        int sec;
        public myDate(String str){
            this.year=Integer.valueOf(str.substring(0,4));
            this.month=Integer.valueOf(str.substring(5,7));
            this.day=Integer.valueOf(str.substring(8,10));
            this.hour=Integer.valueOf(str.substring(11,13));
            this.min=Integer.valueOf(str.substring(14,16));
            this.sec=Integer.valueOf(str.substring(17,19));
        }
    
        //用于判断是否超过5分钟
        public boolean subDate(myDate o){
            if(o.year>year){
                return true;
            }
            if(o.month>month){
                return true;
            }
            if(o.day>day){
                return true;
            }
            if(o.hour>hour){
                return true;
            }
            if(o.min-min>5){
                return true;
            }else if(o.min-min==5){//分钟时刻刚好相差5min,需要使用秒时快进一步比较
                if(o.sec>sec){//秒时刻多输出true
                    return true;
                }
            }
            return false;//其他所有情况,都输出false:没有超过5min
        }
    }
    
    public class Solution {
        private static HashMap<String,Integer> hm=new HashMap();//统计频次
        private static myDate staTime=null;//基准时刻
    
        public static void SinInput(String str){
            String time=str.substring(0,19);
            String intName=str.substring(20);
    
            myDate preDate=new myDate(time);
    
            if(staTime==null){
                staTime=preDate;
                hm.put(intName,1);//将这个数据添加进hm
                return;
            }
    
            if(!staTime.subDate(preDate)){//1,没有超过5分钟,直接在hashMap中添加或者累积
                if(hm.containsKey(intName)){//1,1hm中有原始的数据
                    hm.put(intName,hm.get(intName)+1);
                }else {//1,2hm中没有原始的数据
                    hm.put(intName,1);
                }
    
            }else {//2,超过5分钟,将本轮数据的 最大频数及名称输出
                int num=0;
                String name="";
                for(String key:hm.keySet()){
                    if(num<hm.get(key)){
                        name=key;
                        num=hm.get(key);
                    }
                }
                System.out.println(num+" "+name);
                hm.clear();
                hm.put(intName,1);
            }
        }
    
        public static void FinWork(){//主动退出,并且处理,清空hm中剩余数据
            int num=0;
            String name="";
            for(String key:hm.keySet()){
                if(num<hm.get(key)){
                    name=key;
                    num=hm.get(key);
                }
            }
            System.out.println(num+" "+name);
            hm.clear();
        }
    
        public static void main(String[] args) {
            //1,测试
            ArrayList<String> arr=new ArrayList<>();
            arr.add("2019-09-10T10:00:01 /api/a");
            arr.add("2019-09-10T10:00:01 /api/a");
            arr.add("2019-09-10T10:00:01 /api/b");
            arr.add("2019-09-10T10:06:00 /api/a");
    
            //2,输入
            Scanner sc=new Scanner(System.in);
    
            //3,输入&处理
            for(int i=0;i<arr.size();i++){
                SinInput(arr.get(i));
            }
            FinWork();//主动退出,并处理剩余数据
    
        }
    }
    /*
    2 /api/a
    1 /api/a
     */

    3,找出三子棋最有利的落点

      有一种3x3大小的正方形棋盘,类似五子棋玩法横竖斜着三种颜色相连就胜利,求出下一个棋子的最佳落点,默认黑子先手

      咔咔,这个是一个二维的问题!直接在水平、竖直、斜向进行检测,并且将检测结构存于hashMap中,其实这里可以进一步推广,变成动态的自动下棋软件。

    package com.cnblogs.mufasa.Main3;
    
    import java.util.ArrayList;
    import java.util.HashMap;
    
    public class Solution {
        private static HashMap<Integer, ArrayList<int[]>> hm=new HashMap<>();
    
        public static void findX(int[][] map,int type){//直接横向的进行遍历
            int lenX=map.length;
            int lenY=map[0].length;
    
            ArrayList<int[]> arr=new ArrayList<>();
            int sum;
            for(int i=0;i<lenX;i++){
                sum=lenY;
                for(int j=0;j<lenY;j++){
                    if(map[i][j]==-1*type){//1,1是另外颜色的落子,本行无法取胜,直接清空数据跳出
                        arr.clear();
                        break;
                    }else if(map[i][j]==type){//1,2是该颜色的落子,胜率加大
                        sum--;
                    }else {//1,3是空位点,可以落子
                        arr.add(new int[]{i,j});
                    }
                }
    
                if(arr.size()!=0){//1,4有可能的位点
                    if(hm.containsKey(sum)){//1,4,1原始hm中有相关sum数据
                        arr.addAll((ArrayList<int[]>)hm.get(sum).clone());
                        hm.put(sum,(ArrayList<int[]>)arr.clone());
                        arr.clear();
                    }else {//1,4,2原始hm中没有相关sum数据
                        hm.put(sum,(ArrayList<int[]>) arr.clone());
                        arr.clear();
                    }
                }
    
            }
        }
    
        public static void findY(int[][] map,int type){//直接纵向的进行遍历
            int lenX=map.length;
            int lenY=map[0].length;
            ArrayList<int[]> arr=new ArrayList<>();
            int sum;
            for(int i=0;i<lenX;i++){
                sum=lenY;
                for(int j=0;j<lenY;j++){
                    if(map[j][i]==-1*type){//1,1是另外颜色的落子,本行无法取胜
                        arr.clear();
                        break;
                    }else if(map[j][i]==type){//1,2是该颜色的落子,胜率加大
                        sum--;
                    }else {//1,3是空位点,可以落子
                        arr.add(new int[]{j,i});
                    }
                }
    
                if(arr.size()!=0){//1,4有可能的位点
                    if(hm.containsKey(sum)){//1,4,1原始hm中有相关sum数据
                        arr.addAll((ArrayList<int[]>)hm.get(sum).clone());
                        hm.put(sum,(ArrayList<int[]>)arr.clone());
                        arr.clear();
                    }else {//1,4,2原始hm中没有相关sum数据
                        hm.put(sum,(ArrayList<int[]>) arr.clone());
                        arr.clear();
                    }
                }
    
            }
        }
    
        public static void findZ(int[][] map,int type){//进行斜向的遍历
            int lenX=map.length;
            int lenY=map[0].length;
            int len=Math.min(lenX,lenY);
    
            ArrayList<int[]> arr=new ArrayList<>();
            int sum=len;
    
            for(int i=0;i<len;i++){//左上至右下
                if(map[i][i]==-1*type){
                    arr.clear();
                    break;
                }else if(map[i][i]==type){
                    sum--;
                    if(sum==0){
                        break;
                    }
                }else {
                    arr.add(new int[]{i,i});
                }
            }
    
            if(arr.size()!=0){
                if(hm.containsKey(sum)){
                    arr.addAll((ArrayList<int[]>)hm.get(sum).clone());
                    hm.put(sum,(ArrayList<int[]>)arr.clone());
                    arr.clear();
                }else {
                    hm.put(sum,(ArrayList<int[]>) arr.clone());
                }
                arr.clear();
            }
    
            sum=len;
            for(int i=0;i<len;i++){//右上至左下
                if(map[i][len-1-i]==-1*type){
                    arr.clear();
                    break;
                }else if(map[i][len-1-i]==type){
                    sum--;
                    if(sum==0){
                        break;
                    }
                }else {
                    arr.add(new int[]{i,len-i-1});
                }
            }
    
            if(arr.size()!=0){
                if(hm.containsKey(sum)){
                    arr.addAll((ArrayList<int[]>)hm.get(sum).clone());
                    hm.put(sum,(ArrayList<int[]>)arr.clone());
                    arr.clear();
                }else {
                    hm.put(sum,(ArrayList<int[]>) arr.clone());
                }
                arr.clear();
            }
        }
    
        public static void toOut(int type){//数据输出
            for(int i=0;i<=3;i++){
                if(hm.containsKey(i)){
                    if(type==-1){
                        System.out.print("B:");
                    }else {
                        System.out.print("W:");
                    }
                    for(int[] temp:hm.get(i)){
                        System.out.print("("+temp[0]+","+temp[1]+")");
                    }
                    System.out.println();
                    hm.clear();
                    break;
                }
            }
        }
    
        public static void main(String[] args) {
    
            //1,测试
            int[][] map=new int[][]{{0, 1, 0},
                                    {0,-1, 0},
                                    {0, 0, 0}};//-1表示黑子,1表示白子,0表示空位
    
            //2,输入
    //        Scanner sc=new Scanner(System.in);
    
            //3,处理输出
            int bNum=0;
            int wNum=0;
            for(int i=0;i<3;i++){
                for(int j=0;j<3;j++){
                    if(map[i][j]==-1){
                        bNum++;
                    }else if(map[i][j]==1){
                        wNum++;
                    }
                }
            }
    
            int type=(bNum==wNum?-1:1);
            findX(map,type);
            findY(map,type);
            findZ(map,type);
            toOut(type);
    
        }
    }
  • 相关阅读:
    多线程设计的要素—任务线程确定
    https://www.neroxie.com/2019/01/22/深入理解GCD之dispatch-group/
    性能、指标、监控、数据大盘
    iOS PhotoKit 笔记
    多线程的核心问题是控制共享变量的无序访问(读写)
    objective-c arc -对象、变量、变量修饰符、赋值
    大幅降低存储成本,Elasticsearch可搜索快照是如何办到的?
    压测利器:TarsBenchmark正确打开方式
    跨国合作:Serverless Components 在腾讯云的落地和实践
    前端视角谈物联网三部曲:连接智能、交互智能、数据智能
  • 原文地址:https://www.cnblogs.com/Mufasa/p/11534223.html
Copyright © 2020-2023  润新知