C ++ (Data Structures and Algorithms) 78: --- divide and rule

First, the idea of ​​divide and rule

  • Modular methods of divide and rule and software design is very similar
  • Divide and conquer is usually not used for small instances to solve the problem, but to solve a problem of great examples. The general steps are:
    • The example ① a large into two or more smaller Examples
    • ② Address each small example
    • ③ The solution composition of these small examples to the original instance large Solution

Second, find out the practical application of the counterfeit money

Problem Description

  • A bag with 16 coins, of which only one is counterfeit, the counterfeit lighter than other real coin weight (the weight of all other real currency are the same), and now to find out the counterfeit money

Common solution

  • The general approach is to compare one by one, in the event of quality lighter to find the counterfeit money
  • Steps:
    • ① Comparison of the coin 1 and 2 coin, if a coin is light, then the light of the coin is counterfeit, termination looking for; otherwise the next step
    • ② continue to compare 2 coin and the coin 3, if a coin is light, then the light of the coin is counterfeit, termination looking for; otherwise the next step
    • ...... and so on, until you find the counterfeit looking termination

Solution of divide and rule

  • Divide and conquer the big idea is an example of a problem is decomposed into two or more small example, and then compare
  • Here we will break down into two great examples of small instance, the steps are:
    • ① the coin 16 into two groups A and B, each group of eight coins, calculate the total mass of each of the coin and compares the lighter sure that group comprising counterfeit
    • ② The packet continues lighter that group, divided into A and B, each group of four coins, and then calculate the total mass of each of the coin and compares the same token, the lighter sure that group comprising counterfeit
    • ③ The packet continues lighter that group, divided into A and B, of two coins, and then calculate the total mass of each of the coin and compares the same token, the lighter sure that group comprising counterfeit
    • ④ eventually leaving only two coins, and therefore do not need to be grouped, and a direct comparison, the lighter it is certainly a counterfeit coin

Third, the practical application of bullion problem

Problem Description

  • The boss has a bag of gold, bullion each weight is different, and now want to find the gold bullion with the heaviest and lightest

Common solution

  • Common solution is to compare apples to apples, find the lightest and heaviest gold
  • General steps are:
    • N is the total number of gold assumed
    • The first one by comparing each nugget to identify the heaviest gold
    • After the heaviest gold find, from the n-1 remaining in gold bullion and then find the lightest
  • The number of comparisons: Because the number of comparisons to find the heaviest gold is n-1 times, the gold from the remaining re-used to find the lightest gold n-2 times, so the total number of comparisons is 2n-3
template<typename T>
bool find_max_min(T arr[], int n,int &maxIndex,int &minIndex)
{
    if (n <= 0)
        return false;

    //先找出最大的
    maxIndex = 0;
    for (int i = 1; i < n; ++i) {
        if (arr[maxIndex] < arr[i])
            maxIndex = i;
    }

    //再从剩余的当中找出最小的
    minIndex = 0;
    for (int j = 1; j < n; j++) {
        if (j == maxIndex)
            continue;
        if (arr[minIndex] > arr[j])
            minIndex = j;
    }
    
    return true;
}


int main()
{
    int arr[] = { 1,4,2,5,1,8,5 };
    int maxIndex, minIndex;

    if (find_max_min(arr, sizeof(arr) / sizeof(int), maxIndex, minIndex)) {
        std::cout << "max:" << arr[maxIndex] << endl;
        std::cout << "min:" << arr[minIndex] << endl;
    }

    return 0;
}

Solution of divide and rule

  • When n <= 2, a comparison is sufficient
  • When n> 2, the following general steps:
    • ① The nugget is divided into two parts A and B
    • ② A and B respectively identify the heaviest and the lightest and heaviest A set of gold were lightest and Ha La, A is the lightest and heaviest nuggets were Hb and Lb (which step can be implemented using recursion)
    • ③ compare Ha and Hb can identify the heaviest, La and Lb can compare to find the lightest
  • Case presentation:
    • ① assumed that n = 8, there are eight gold
    • ② The eight gold divided into two sections A and B, each with four gold
    • A ③ Since there are four gold, which we subdivided into two portions A1 and A2, each section has two gold
      • Then a comparison can identify A1 heavier gold Ha1 and La1
      • By comparison once again to find the lesser of bullion Ha2 A2 and La2
      • And then through a comparison with Ha1 A Ha2 find the heaviest gold Ha, through a comparison La1 and La2 find in the lightest A La bullion
    • ④ Since B has four gold, we will be subdivided into two portions B1 and B2, each section has two gold
      • Then a comparison can identify B1 heavier gold Hb1 and Lb1
      • By comparison once again find B2 lesser of bullion Hb2 and Lb2
      • And then through a comparison with Hb1 A Hb2 find the heaviest gold Hb, through a comparison of Lb1 and Lb2 to find the lightest A gold Lb
    • ⑤ Finally, a comparison of Ha and Hb to find the heaviest gold , and then conduct a comparison of La and Lb to find the lightest gold . Step end
  • As can be seen above the divide and rule among a total of 10 times compare

  • Provided c (n) is the number of comparisons needed . For convenience, assume that n is a power of 2:
    • If a divide and conquer method: when n = 2, c (n) = 1; for large n, c (n) = 2c (n / 2) +2
    • If the method is compared one by one: c (n) = 3n / 2-2
    • Thus, using the divide and conquer method than the one by way of comparison with the less number of comparisons 25%

Divide and conquer Coding

  • If recursion, the following steps:
    • ① In the binary tree on the figure, along the path from root to leaf, the example of a large size is divided into a plurality of small instance 1 or 2,
    • ② In each instance the size of 2, a comparison determines which of which heavier and lighter. In node D, E, F, G accomplish this comparison. 1 is an example of the size of a nugget only, It is the lightest and most important of
    • ③ lighter of gold compared to determine which one of the lightest of the heavier gold compared to determine a security heaviest. Nodes A, B, C the comparison is performed
  • If a non-recursive method, as follows:
    • Complexity Analysis: When n is an even number, and again for comparison outside the loop, internal 3 (n / 2-1) comparisons. The total number of comparisons is 3n / 2. When n is odd, there is no comparison for the outer loop, internal n (n-1) / 2 comparisons. Thus, no matter where n is odd or even, when n> 0, the total number of comparisons is [3n / 2] -2. This is the earliest Max Min algorithm, the minimum number of comparisons algorithm
template<typename T>
bool find_max_min(T arr[], int n,int &maxIndex,int &minIndex)
{
    //如果数组大小小于等于0,直接退出
    if (n <= 0)
        return false;
    //如果只有一个金块,那么它既是最重的也是最轻的
    if (n == 1) {
        maxIndex = minIndex = 0;
        return true;
    }
    //如果金块数量大于等于2,开始下面的部分

    int s = 0;//用于标识比较的开始起点
    if (n % 2 == 1) {
        //如果金块数量为奇数,设定最大索引与最小索引为0,然后从s=1索引处开始进行比较
        maxIndex = minIndex = 0;
        s = 1;
    }
    else {
        //如果金块数量为偶数,从前两个元素中提取出较小元素与较大元素的索引,然后从s=2索引处开始比较
        if (arr[0] > arr[1]) {
            maxIndex = 0;
            minIndex = 1;
        }
        else {
            maxIndex = 1;
            minIndex = 0;
        }
        s = 2;
    }

    //从s开始进行比较,每两个元素比较一次
    for (int index = s; index < n; index += 2) {
        if (arr[index] > arr[index +1]) {
            if (arr[index] > arr[maxIndex])
                maxIndex = index;
            if (arr[index + 1] < arr[minIndex])
                minIndex = index + 1;
        }
        else {
            if (arr[index] < arr[minIndex])
                 minIndex = index;
            if (arr[index + 1] > arr[maxIndex])
                maxIndex = index + 1;
        }
    }

    return true;
}


int main()
{
    int arr[] = { 1,4,2,5,0,1,8,3,8 };
    int maxIndex, minIndex;

    if (find_max_min(arr, sizeof(arr) / sizeof(int), maxIndex, minIndex)) {
        std::cout << "max:" << arr[maxIndex] << endl;
        std::cout << "min:" << arr[minIndex] << endl;
    }

	return 0;
}

Fourth, the practical application of the matrix multiplication

  • to be continued
Released 1525 original articles · won praise 1085 · Views 450,000 +

Guess you like

Origin blog.csdn.net/qq_41453285/article/details/104474366