Data structure and algorithm -- 22 Violent matching algorithm, kmp algorithm, greedy algorithm

Posted by kemper on Mon, 27 Dec 2021 16:45:23 +0100

1.

1. Violence matching algorithm

String matching problem:

1) There is a string str1 = "" Silicon Valley is still Silicon Valley, you are still Silicon Valley, you are still Silicon Valley, you are still Silicon Valley, you are still silicon hello "", and a substring str2 = "still Silicon Valley, you are still silicon you"

2) Now it is necessary to determine whether str1 contains str2. If it exists, it returns the first occurrence position. If not, it returns - 1

Violence matching algorithm

If we use the idea of violent matching and assume that str1 is now matched to position i and substring str2 is matched to position j, there are:

1) If the current character matches successfully (i.e. str1[i] == str2[j]), I + +, j + +, continue to match the next character

2) If mismatch (i.e. str1[i]! = str2[j]), let i = i - (j - 1), j = 0. It is equivalent to I backtracking and J being set to 0 every time a match fails

3) If violence is used to solve the problem, there will be a lot of backtracking. Only move one bit at a time. If it doesn't match, move to the next bit and judge. It wastes a lot of time. (not feasible!)

4) Implementation of violence matching algorithm

Code implementation:

public class ViolenceMatch {
    public static void main(String[] args) {

        String str1 = "Silicon valley still Silicon Valley you still Silicon Valley you still Silicon Valley you still Silicon Valley you still silicon hello";
        String str2 = "Shang Silicon Valley you Shang Silicon Valley you";

        int index = violenceMatch(str1, str2);
        System.out.println(index);
    }

    public static int violenceMatch(String str1,String str2){

        char[] char1 = str1.toCharArray();
        char[] char2 = str2.toCharArray();

        int s1Len = char1.length;
        int s2Len = char2.length;

        int i=0;//Point to char1
        int j=0;//Point to char2

        while (i<s1Len&&j<s2Len){

            if (char1[i]==char2[j]){
                i++;
                j++;
            }else {
                i=i-(j-1);
                j=0;
            }
        }

        if (j==s2Len){

            return i-j;
        }else {
            return -1;
        }
    }
}

2.kmp algorithm

11. Compare bit by bit until C and D do not match. Therefore, move the number of bits = 6-2, and continue to move the search term backward by 4 bits.

 

 

 

Code implementation:

public class KmpAlgorithm {
    public static void main(String[] args) {

        String str1="BBC ABCDAB ABCDABCDABDE";
        String str2="ABCDABD";

        int[] kmpNext = kmpNext(str2);

        int index = kmpSearch(str1, str2, kmpNext);

        System.out.println(index);
    }

    //kmp search algorithm

    /**
     *
     * @param str1 Source string
     * @param str2 Substring
     * @param next Partial matching table
     * @return If it is - 1, there is no match. Otherwise, the first matching position is returned
     */
    public static int kmpSearch(String str1,String str2,int[] next){

        for (int i = 0,j=0; i < str1.length(); i++) {

            //STR1. Needs to be processed charAt(i)!= str2.charAt(j), to adjust the size of j
            // Core points of KMP algorithm
            while (j>0&&str1.charAt(i)!=str2.charAt(j)){

                j=next[j-1];
            }

            if (str1.charAt(i)==str2.charAt(j)){

                j++;
            }

            if (j==str2.length()){

                return i-j+1;
            }
        }
        return -1;
    }

    //Gets a table of partial matching values for a string
    public static int[] kmpNext(String dest){

        //Create a next array to hold some matching values
        int[] next=new int[dest.length()];

        next[0]=0;//If the string is a length of 1, the matching value is 0

        for (int i = 1,j=0; i < dest.length(); i++) {

            //When dest charAt(i)!= dest. Charat (J), we need to get a new j from next[j-1]
            while (j>0&& dest.charAt(i)!=dest.charAt(j)){

                j=next[j-1];
            }

            if (dest.charAt(i)==dest.charAt(j)){

                j++;
            }
            next[i]=j;
        }
        return next;
    }
}

3. Greedy algorithm

Introduction to greedy algorithm

1) Greedy algorithm (greedy algorithm) refers to the algorithm that takes the best or optimal (i.e. the most favorable) choice in each step when solving the problem, so as to lead to the best or optimal result

2) The results obtained by greedy algorithm are not necessarily the optimal results (sometimes the optimal solution), but they are relatively approximate (close) to the optimal solution

Application scenario - set coverage problem

It is assumed that there are the following broadcasting stations that need to pay and the areas that can be covered by the broadcasting station signal. How to select the least number of broadcasting stations so that all regions can receive signals.

At present, there is no algorithm that can quickly calculate the prepared value. Using greedy algorithm, we can get a very close solution with high efficiency. In terms of policy, the minimum set covering all regions is required:

1) Traverse all radio stations and find a station that covers the most uncovered areas (this station may contain some covered areas, but it doesn't matter)

2) Add the radio station to a collection (such as ArrayList) and try to remove the areas covered by the radio station in the next comparison.

3) Repeat step 1 until all areas are covered

 

Code implementation:

import java.util.*;

public class GreedyAlgorithm {
    public static void main(String[] args) {

        //Create a radio and television station
        Map<String, HashSet<String>> broadcasts=new HashMap<>();

        HashSet<String> hashSet1=new HashSet<>();
        hashSet1.add("Beijing");
        hashSet1.add("Shanghai");
        hashSet1.add("Tianjin");

        HashSet<String> hashSet2=new HashSet<>();
        hashSet2.add("Guangzhou");
        hashSet2.add("Beijing");
        hashSet2.add("Shenzhen");

        HashSet<String> hashSet3=new HashSet<>();
        hashSet3.add("Chengdu");
        hashSet3.add("Shanghai");
        hashSet3.add("Hangzhou");

        HashSet<String> hashSet4=new HashSet<>();
        hashSet4.add("Shanghai");
        hashSet4.add("Tianjin");

        HashSet<String> hashSet5=new HashSet<>();
        hashSet5.add("Hangzhou");
        hashSet5.add("Dalian");

        broadcasts.put("k1",hashSet1);
        broadcasts.put("k2",hashSet2);
        broadcasts.put("k3",hashSet3);
        broadcasts.put("k4",hashSet4);
        broadcasts.put("k5",hashSet5);

        //Store all areas
        Set<String> allAreas=new HashSet<>();
        allAreas.add("Beijing");
        allAreas.add("Shanghai");
        allAreas.add("Tianjin");
        allAreas.add("Guangzhou");
        allAreas.add("Shenzhen");
        allAreas.add("Chengdu");
        allAreas.add("Hangzhou");
        allAreas.add("Dalian");

        //Store selected stations
        List<String> selects=new ArrayList<>();

        //Define a temporary set. In the traversal process, the intersection of the area covered by the radio station and the area not covered at present
        Set<String> tempSet=new HashSet<>();

        //Define maxKey and save the key corresponding to the radio stations that can cover the most uncovered areas in one traversal
        String maxKey=null;

        while (allAreas.size()!=0){

            //maxKey needs to be set to empty for each cycle
            maxKey=null;

            //Traverse broadcasts
            for (String key : broadcasts.keySet()) {
                //Every time for is performed, the temp should be cleared
                tempSet.clear();
                //Areas currently covered by key
                HashSet<String> areas = broadcasts.get(key);
                //Add to temporary collection
                tempSet.addAll(areas);
                //Find the intersection of tempSet and allAreas set, and the intersection will be assigned to tempSet
                tempSet.retainAll(allAreas);
                //If the current set contains more uncovered areas than the set pointed to by the maxKey, reset the maxKey at this time
                if (tempSet.size()>0&&(maxKey==null||tempSet.size()>broadcasts.get(maxKey).size())){
                    maxKey=key;
                }
            }

            //At this time, the value of maxKey is not empty and is added to selections
            if (maxKey!=null){
                selects.add(maxKey);
                //Remove the area covered by the radio station executed by maxKey from allAreas
                allAreas.removeAll(broadcasts.get(maxKey));
            }
        }

        System.out.println(selects);
    }
}

Topics: Java data structure