Java algorithm foundation and design patterns

table of Contents

Array sort

    Bubble Sort

    Select sort

    Find the maximum/minimum value

    Sort in ascending order (smallest to largest)

    Reverse output

    Copy sort

   Array lookup algorithm (search)

   Linear search algorithm (sequence)

   Binary search

   Array insertion sort

   Quick sort

Design Patterns

    Singleton mode (including lazy and hungry)

    Factory mode (including ordinary factory mode, multiple factory modes, static factory mode, abstract factory mode)

    

    

    

 

Array sort

Remember to mark the key points in the code

 

Bubble Sort

The most basic operation algorithm for arrays (shown here to sort from small to large), Arrasy.sort is relatively stable

Write picture description here

Idea: It is to compare one by one. Subscript 0 starts to compare with subscript 1, and a total of 6 cycles. Each cycle is replaced if the conditions are met, such as 23>12, the two will exchange positions, and so on.

Every 6 small cycles is a small cycle. Every 6 cycles can find a maximum value (the boss), the second big cycle can find the second maximum value (the second), and so on, A total of 7 cycles (length 7)

Probably like this:

This code is too much, we simplify

import java.util.Scanner;
public class MaoPaoPaiXu{
  public static void main(String[] args){
    int[] arr={23,12,45,24,37,65,12,14};

  /*重点:冒泡排序需要两个循环,这就是冒泡排序*/
    for(int i=0;i<arr.length-1;i++){//大循环,每次都能找出一个最大值
      for(int j=0;j<arr.length-1;j++){//嵌套小循环,如6次

         if(arr[j]>arr[j+1]){//一个值跟下一个值对比,这里演示从小到大冒泡排序,反之换<
           //一个值arr[j]>下一个值arr[j+1]交换位置
           int t=arr[j];
           arr[j]=arr[j+1];
           arr[j+1]=t;
         }

      }

    }
   //冒泡后输出该数组内容
   for(int i=0;i<arr.length;i++){
     System.out.println(arr[i]);
   }


  }
}

Select sort

Write picture description here

Idea: First choose a challenger, and then compare it one by one. If you find the biggest one, replace it

First choose a challenger, for example, 4 is the largest. After choosing the boss, go outside to rest. After choosing the second child, remove the second child, and so on!

Every time one is found, one is less, no more comparison (bubble is to keep repeating the comparison)

 

public class XuanZePaiXu{
  public static void main(String[] args){
    int[] arr={34,54,6,87,98,54,3432,1};

/*重要:需要记忆,也是循环嵌套*/
    for(int i=0;i<arr.length-1;i++){
      for(int j=j+1;j<arr.length;j++){//第一轮第一个擂主跟后面一个个的值比,
        if(arr[i]>arr[j]){//擂主>和我挑战的人,我就跟他互换
          //擂主arr[i]和挑战者arr[j]互换
          int t=arr[i];
          arr[i]=arr[j];
          arr[j]=t;
       
        }

      }
    }
//输出替换后的
    for(int i=0;i<arr.length;i++){
     System.out.println(arr[i]);

    }       

  }
}

 

Bubble sort is very selective sort comparison:

More efficient than the bubble sort algorithm; comparison of the two sorts

Bubbling: the comparison of two adjacent subscripts, the number of times the array length is looped

Choice: Choose one ring to compare with the following one, and then continue to change to other ring

Bubbling:                                                                    Choose:

 

Find the maximum/minimum value

Question: There is a group (a string of) numbers, find the maximum value of this group of numbers;

Idea: The easiest way is to set up a ring, first put a number on the ring, and compare the next number with the ring, if it is satisfied, replace the ring with the number to be compared, and know the end;

 

import java.util.Scanner;
public class MAXtest{


  public static void main(){

/*非重点:这里是由用户输入一组数字,有些题目是直接给出的一组数字,如:int[] arr={5,2.6.3.1}*/
    Scanner in=new Scanner(System.in);//由用户输入一组数字
    int[] arr=new int[5];//一组数字有五个数
    for(int i=0;i<arr.length;i++){//循环输入一组数字到数组中
      System.out.println("请输入第"+(i+1)+"个数字");
      arr[i]=in.nextInt();//数组接收用户的内容 

    }


/*下面才是重点:“打擂台”的算法*/
     int max=arr[0];//这里就是设置一个擂台max,然后擂台先站一个人arr[0];

     //下面就是让其他的数一个个跟擂台上的数比大小咯,若满足条件,擂台就换人
     for(int i=0;i<arr.length;i++){//循环对比

   //擂台max跟下一个数arr[i]进行对比,如果擂台<下一个数,就替换,这里是找最大值,最小值要换下>
       if(max < arr[i]){
         max=arr[i];//把下一个数字换到擂台上
         
       }

     }
    
System.out.println("所以最大值就是:"+ max );  

   }


}

Linear/sequential search algorithm

The method of searching one by one in order;-similar to the above method of fighting

Under the main test:

If you want to call find and () methods, you need the newFINDTest object first. If you don’t want to add it, add static before find()

-1 means the search failed because the array has no subscript -1

Sort in ascending order (smallest to largest)

Topic: There is a group (a string of) numbers, let this group of numbers sort in ascending order;

Idea: Use the Arrays method provided in java to achieve;

import java.util.Arrays;//java.uril中的方法
import java.util.Scanner;
public class ShengXuPaiLie{

   public static void main(String[] args){

 /*非重点:这里是由用户输入一组数字,有些题目是直接给出的一组数字,如:int[] arr={5,2.6.3.1}*/
    Scanner in=new Scanner(System.in);//由用户输入一组数字
    int[] arr=new int[5];//一组数字有五个数
    for(int i=0;i<arr.length;i++){//循环输入一组数字到数组中
      System.out.println("请输入第"+(i+1)+"个数字");
      arr[i]=in.nextInt();//数组接收用户的内容 
    }


/*下面才是重点:使用Arrays方法来实现升序的方法*/
     Arrays.sort(arr);//这就是自动升序的方法,这个要记住

     //接下来循环输出升序后的内容
     for(int i=0;i<arr.length;i++){
       System.out.println(arr[i]);//循环输出升序后arr[i]的内容
     }

   }

}

Three, reverse output

abcd is the positive order (from small to large), dcba is the reverse order (from large to small)

Idea: Arrange these messy characters first, and now arrange them from small to large (ascending order). The subscript is very fixed and the smallest is first. In reverse order, put the largest subscript first.

                                                                                                                   

import java.util.Arrays;//java.uril中的方法
import java.util.Scanner;
public class NiXuPaiLie{

   public static void main(String[] args){

 /*非重点:这里是由用户输入一组数字,有些题目是直接给出的一组数字,如:int[] arr={5,2.6.3.1}*/
    Scanner in=new Scanner(System.in);//由用户输入一组数字
    int[] arr=new int[5];//一组数字有五个数
    for(int i=0;i<arr.length;i++){//循环输入一组数字到数组中
      System.out.println("请输入第"+(i+1)+"个数字");
      arr[i]=in.nextInt();//数组接收用户的内容 
    }


     Arrays.sort(arr);//先把杂乱的字符升序。

/*下面才是重点:使用Arrays方法来实现升序的方法*/
     //接下来逆序输出,逆序就是把最大的坐标在前面先输出,这个for循环要记住
     for(int i=arr.leng-1;i>=0;i--){
/**arr.leng-1这个就是最大的下标,(数组长度-1=最大下标),比如有2个数组就是0,1,1就是最大的下标(2-1=1)
**i>=0这个是数组最少是1个数组;
**i--这个就是逆序不能是++,逻辑要弄清
**/
       System.out.println(arr[i]);//逆序输出
     }

   }

}

Java also provides a reverse order method, reverse(),

The content of the collection https://blog.csdn.net/bbs11007/article/details/89467148


import java.util.ArrayList;
import java.util.Coliections;
import java.util.List;
import java.util.Scanner;
public class Test11
{
    public static void main(String[] args)
    {
        Scanner input=new Scanner(System.in);//由用户输入内容
        List students=new ArrayList();//创建集合
        System.out.println("******** 商品信息 ********");
        for(int i=0;i<5;i++)
        {
            System.out.println("请输入第 "+(i+1)+" 个商品的名称:");
            String name=input.next(); //获取用户的输入内容
            students.add(name);    //将录入的商品名称存到List集合中
        }
        Collections.reverse(students);    //调用reverse()方法对集合元素进行反转排序
        System.out.println("按录入时间的先后顺序进行降序排列为:");
        for(int i=0;i<5;i++)
        {
            System.out.print(students.get(i)+"\t");
        }
    }

 

Copy sort

Topic: Copy the contents of one array to another array

Idea: Assign the value of the subscript of a group number to the corresponding subscript, such as: assign the value of an array 0 subscript 2 to the value of the following array 0 subscript

public class Fuzhi{

  public static void main(String[] args){
      int[] arrA={1,2,3,4,5,6,7,8};//一个数组的值
      int[] arrB=new int{arrA.length}//新建一个数组的长度跟arrA一样
     
/*重点来了:下面就开始一个个把arrA的值赋值给arrB中,对应下标*/
      for(int i=0;i<arrA.length;i++){//循环arrA的长度下标
         arrB[i]=arrA[i];//把arrA的下标i赋值给arrB的下标i,如:arrA[0]的值赋值给arr[0]

      }

  }


}

Java also provides a copy method, copy()

The content of the collection https://blog.csdn.net/bbs11007/article/details/89467148


public class Test12
{
    public static void main(String[] args)
    {
        Scanner input=new Scanner(System.in);
        List srcList=new ArrayList();
        List destList=new ArrayList();
        destList.add("苏打水");
        destList.add("木糖醇");
        destList.add("方便面");
        destList.add("火腿肠");
        destList.add("冰红茶");
        System.out.println("原有商品如下:");
        for(int i=0;i<destList.size();i++)
        {
            System.out.println(destList.get(i));
        }
        System.out.println("输入替换的商品名称:");
        for(int i=0;i<3;i++)
        {
            System.out.println("第 "+(i+1)+" 个商品:");
            String name=input.next();
            srcList.add(name);
        }
        //调用copy()方法将当前商品信息复制到原有商品信息集合中
        Collections.copy(destList,srcList);
        System.out.println("当前商品有:");
        for(int i=0;i<destList.size();i++)
        {
            System.out.print(destList.get(i)+"\t");
        }
    }
}

Array lookup algorithm (search)

Title: There is an array of names, find a classmate (such as gecko)

Idea: Start with 0 subscript to find one by one, and find until the end. If you still can't find it at the end, judge no. (Note, here is to find out if there is this person, if there are two the same name, it doesn't matter, it is only responsible for judging whether there is this person)

import java.util.Scanner;
public class SouSuo{
  public static void main(String[] args){
    Scanner in = new Scanner(System.in);
    System.out.println("请输入你要找的学生的姓名:");
    String name = in.next();//由用户输入要找的人,比如用户输入:壁虎
    String[] arr={"张三","李四","王二","麻子","壁虎"};//若是有重名,下面就判断输出两次就没意义

    boolean flag=false;//这里做个标记,防止有重名,不要输出多次
  
 /*重点:开始在数组里面一个个找,判断是不是要找的人*/
   for(int i=0;i<arr.length;i++){//循环数组里面的人
     if(name.equals(arr[i])){
       flag=true;//我们就判断flag
       break;//如果找到了,下面就不用再找了,就跳出for循环
     }

   }
   
   if(flag==true){//如果有这个学生,就提示找到了,后面就没有找了
    System.out.printl(“找到了”);  

   }else{//否则整个数组都没有该学生
    System.out.printl(“没有找到该学生”);
   }

  }

}

 

Binary search

Must be arranged from small to large, ordered array can use this method;

Topic: Use binary search to find a number in an array

Binary search, also known as binary search, binary search, and binary search, is a search algorithm for finding a particular element in an ordered array. The search process starts from the middle element of the array. If the middle element happens to be the element to be searched, the search process ends; if a particular element is greater than or less than the middle element, search in the half of the array that is greater or less than the middle element , And start the comparison from the middle element just like the beginning. If the array is already empty at a certain step, it means that the specified element cannot be found. This search algorithm reduces the search range by half each time it compares, and its time complexity is O(logN).

The idea is as follows: the premise of binary search is to be in an ordered array, so first use the Arrays.sort() method to sort first, and use the method provided by java

import java.util.Arrays;

public class ErFenPaiXu{
  public static void main(String[] args){
    int data= new int[]{1,4,64,65,34,23,21312,2};
    java.uitl.Arrays.sort(data);//先进行排序
    System.out.println(Arrays.binarySearch(data,23));//二分查找binarySearch()方法

  }

}

The second non-recursive implementation:

public static int biSearch(int []array,int a){
        int lo=0;
        int hi=array.length-1;
        int mid;
        while(lo<=hi){
            mid=(lo+hi)/2;
            if(array[mid]==a){
                return mid+1;
            }else if(array[mid]<a){
                lo=mid+1;
            }else{
                hi=mid-1;
            }
        }
        return -1;
    }

The third recursive way

public static int sort(int []array,int a,int lo,int hi){
        if(lo<=hi){
            int mid=(lo+hi)/2;
            if(a==array[mid]){
                return mid+1;
            }
            else if(a>array[mid]){
                return sort(array,a,mid+1,hi);
            }else{
                return sort(array,a,lo,mid-1);
            }
        }
        return -1;
    }

 

High compulsion

import java.util.Comparator;
 
public class MyUtil {
 
   public static <T extends Comparable<T>> int binarySearch(T[] x, T key) {
      return binarySearch(x, 0, x.length- 1, key);
   }
 
   // 使用循环实现的二分查找
   public static <T> int binarySearch(T[] x, T key, Comparator<T> comp) {
      int low = 0;
      int high = x.length - 1;
      while (low <= high) {
          int mid = (low + high) >>> 1;
          int cmp = comp.compare(x[mid], key);
          if (cmp < 0) {
            low= mid + 1;
          }
          else if (cmp > 0) {
            high= mid - 1;
          }
          else {
            return mid;
          }
      }
      return -1;
   }
 
   // 使用递归实现的二分查找
   private static<T extends Comparable<T>> int binarySearch(T[] x, int low, int high, T key) {
      if(low <= high) {
        int mid = low + ((high -low) >> 1);
        if(key.compareTo(x[mid])== 0) {
           return mid;
        }
        else if(key.compareTo(x[mid])< 0) {
           return binarySearch(x,low, mid - 1, key);
        }
        else {
           return binarySearch(x,mid + 1, high, key);
        }
      }
      return -1;
   }
}
/*
说明:上面的代码中给出了折半查找的两个版本,一个用递归实现,一个用循环实现。需要注意的是计算中间位置时不应该使用(high+ low) / 2的方式,因为加法运算可能导致整数越界,这里应该使用以下三种方式之一:low + (high – low) / 2或low + (high – low) >> 1或(low + high) >>> 1(>>>是逻辑右移,是不带符号位的右移)
*/

 

Array insertion algorithm

Topic: Insert a number

 

Idea: The largest subscript is 100. If I want to insert 33, I replace 100 for a long time, but the order of the entire array is disrupted (sorted from small to large), so we have to insert 33 in front, which will follow slowly The previous comparison size, if it is satisfied, replace it.

Sort from smallest to largest:

Insert 33 (replace the last array 100): arr(arr.length-1)=num;

final result:

import java.util.Scanner;
public class ChaRu{
  public static void main(String[] args){
    Scanner in = new Scanner(System.in);
    int arr={1,32,45,65,67,76,100};
    System.out.println("请输入你要插入的数值:");//由用户输入,如:33
    int num = in.next();

/*重点:插入数字后,要对数字进行排序*/
    arr(arr.length-1)=num;//33把最后数组100给替换了
//接下来就对33插入在哪个位置更合适,也就是进行排列。
    for(int i=arr..length-1;i>0;i--){//下面从后写起都是这样
      if(arr[i]<arr[i-1]){//如果插入的数值比前面的小,那就进行替换,如:33<76两者替换
         //两个值交换
         int t=arr[i];
         arr[i]=arr[i-1];
         arr[i-1]=t
      }else{//如果不小于就不往下面执行了
        break;
       
       }

    }
   
    //输出排列后的数组
   for(int i=0;i<arr.length;i++){
      System.out.println(arr[i]);
   }

  }
}

There are other insertion sorts

Write picture description here

The code is implemented as follows:

   /**
    *插入排序
    */
    public static void chaRu(int []array) {
        int temp;
        System.out.println("\n插入排序:");
        for(int i=1;i<array.length;i++) {
            int j=i;
            temp = array[i];
            while( j>0 && temp < array[j-1]) {
                array[j] = array[j-1];
                j--;
            }
            array[j] = temp;
            System.out.print("第"+i+"次:");
            show(array);
        }

Quick sort

Features: High efficiency, time complexity is nlogn. 
Principle: Adopt the idea of ​​divide and conquer: first set an intermediate value, and then divide the sequence to be sorted into two parts larger than the value and smaller than the value based on this intermediate value, and then perform quick sorting on the two parts respectively 
until There is only one element left in the sequence

Write picture description here

/**快速排序
     * */
    public static void kuaiSu(int []array,int left,int right){
        if(left < right) {
            int i=left,j=right;
            int pivot = array[left];//选择最左边的元素作为中间值

        /**
         * 分治
         */
        while(i < j) {
            while(i < j && array[j] >= pivot) {
                j--;
            }
            if(i < j) {
                array[i] = array[j];
                i++;
            }
            while(i < j&& array[i] < pivot){
                i++;
            }
            if(i < j) {
                array [j] =array [i];
                j--;
            }
        }
        array [i]=pivot;
        //递归
        kuaiSu(array,left,i-1);
        kuaiSu(array,i+1,right);
        }
    }

 

Design Patterns

 

 

Singleton mode:

    The singleton class can only have one instance of the entire program. This class is responsible for creating its own objects and ensuring that only one class is created.

 A class has only one instance, that is, a class has only one object instance.

Code points:

1. Private constructor

2. Hold the attributes of the class

3. Provide static methods to obtain instances

 

     Lazy man singleton mode:

                 Thread is not safe, the fatal thing is that it does not work properly in multiple threads and is instantiated at the first call 

Unsafe threads, lazy loading (two types plus synchronization, low efficiency)

public class Singleton {
    private static Singleton instance = null;
    private Singleton() {}
    public static synchronized Singleton getInstance(){
        if (instance == null) instance = new Singleton();
        return instance;
    }
}

 

     Hungry man singleton mode:

   To avoid the synchronization problem of multi-thread, when the class is initialized, it has been instantiated by itself 

Thread safety, reflection and deserialization are not safe;

public class Singleton {
    private Singleton(){}
    private static Singleton instance = new Singleton();
    public static Singleton getInstance(){
        return instance;
    }
}

 

Factory mode

The advantage of the factory method pattern is to improve scalability and maintainability. Experience for yourself.

A Xiaomi and Huawei do not build their own factories, but outsource them to Foxconn.

Ordinary factory method pattern

Write the code according to the class diagram. I will not introduce how to read it here. The writing steps are as follows:

Write the one on the right first, first create a new sender interface

Sender has no return value (so use void)

Then write two implementation classes according to the class diagram

The first implementation class , create a new class, this one needs to override the send method to simulate sending mail

 

The second implementation class , create a new class, this one needs to override the send method to simulate sending SMS

Finally, write the factory class:, create this class,

The factory produces two objects, and returns null if there are none;

Write a main test:

If you want to call the method Produce() of the factory class, first refer to the SendrFacetory class (new it), as shown in the figure below

operation result:

This framework is finished, a Send interface, two implementation classes that implement the interface, and a factory (one method in it is equivalent to a product produced on a production line),

The above effect is equivalent, rather troublesome. Obviously it can be realized by new objects, and a factory needs to be built. Why is it so complicated to build it?

This method is simpler and more concise than above;

An object can’t be seen. If you create an object at a time, and create one at a time, it takes 200. This kind of object requires 200 new objects, but the advantage of using a factory.

If you output the same sentence System.out.print ("helloworld) before s2 new, you must write this every time the new object is changed. If the client wants to change it, you have to change it two hundred times

 

There is a scenario, if in the main function, Sender s = sf.produce("maill");//hand shake adds an extra l

Anything passed to the factory class judges that the condition is not met, so return null; then the null value is given to s, so a null pointer exception will occur when s.send() is called;

To solve this problem, use the following multiple factory method patterns;

 

Multiple factory method patterns

The right side is the same as the normal factory model, the left side has changes and a class is added, so just add it

The original one method to produce 200 kinds of products is split into two methods to produce one product each. The advantage is that there is no need to pass strings again, and it doesn’t take into account that user strings are passed incorrectly.

problem;

The main function is also modified, the benefits of not having to pass parameters

run:

 

This mode is not good enough, it was created to call the produce method;

We can use the following static factory method, you can skip this step (the code can be as simple as possible)

 

Static factory method pattern

 

Simply add static static, this is static, it is easy to understand

There is no need to create objects in main, which is even better.

Write static factory mode without special requirements;

A factory class and two factory models to produce different products, if you need to add a new package, you must add a method, add a method to modify the factory class, which violates the principle of opening and closing, so the following abstract factory is used

 

Abstract factory method pattern

The factory mode emphasizes the principle of opening and closing, that is, it does not modify the tested code in the factory class, which violates the principle of opening and closing (that is, the code that passes the test in the factory mode can be modified without modification). This is to quote the abstract factory method. mode

The class diagram on the right is the same as the above, there is no change, the left side provides the Provider interface, the produce method...

Write the code according to the class diagram, the new factory class interface on the left

This is an abstract behavior. The abstract concept is equivalent to a template. For example, we know the behavior of an object, but which behavior should be defined by ourselves. We first write the format of this behavior and put it there (such as: animal It’s all about eating behavior, but I don’t care how to eat, whether sitting or lying down, I don’t care. I will put this behavior there first). If you don’t understand, look at abstract concepts. After the abstract is written, because there is no concrete realization, it is generally not modified later.

 

Then write the interface of the implementation class

 

Finally write the second implementation class interface

The two public interfaces of the two factory classes are finished.

We write a main function test:

run:

Same function as above

 

 

summary:

 Ordinary factory mode: write code according to the framework class diagram, the disadvantage is that it is easy to misinform the value according to the parameter, so the following multiple factory modes are used

Multiple factory mode: write more methods, instead of using one method to be responsible for all production, you can each be responsible for each; the advantage is that there is no need to pass parameters, and no need to worry about passing wrong parameters

Static factory mode: add static modification before the methods of multiple factory modes, no new object is needed, and no new factory can be called before the method can be called, simplifying the code

                         The disadvantage is that if you want to add a method, you must modify the factory class, and you must modify it after all the tests pass;

Abstract factory mode: The factory mode follows the principle of opening and closing, that is, you cannot change the code of the factory class (especially after the test is passed). Abstraction is equivalent to a template.

                         The advantage is to add a method without modifying the factory class, add one, and it does not affect each other.

Guess you like

Origin blog.csdn.net/bbs11007/article/details/100136297
Recommended