# [animation notes] rolling Division — find the maximum common divisor and the minimum common multiple

Time：2022-5-6

Recently, I touched up the C language and tried to write a calculation tool in combination with the recently learned operations research. On the way, I met a demand: score reduction.

• How to get the score in one step? The answer is to find the denominator and numeratorgreatest common divisor

• So how to calculate the greatest common divisor as soon as possible? I checked the Internet and found an algorithm:Rolling Division

This note simply and intuitively records the algorithm. ## greatest common divisor

The word is very close to the scoreDivideThe so-called maximum common divisor isDivisor common to multiple integersinmaximumThe numerator and denominator when dividingAnd divide by the greatest common divisor, can getSimplest fraction

Because the process mentioned above isDivision operationSo the greatest common divisor is also calledMaximum common factor

To put it more directly,A common factor is a common divisor

There are two points to note about the definition of the greatest common divisor:

1. Common factor / common divisor is forintegerYes.

2. general provisions greatest common divisorbypositive integer, that is, the following formula is satisfied: When you want to calculate a value with a negative sign, you can put an absolute value on it and calculate it again.

## Manual calculation

In reality, when calculating the maximum common divisor of multiple integers, you can list the factors of these numbers to find the common factors, or you can use short division: I think these methods actually depend on our previous experience, such as seeing`36,405,72`Zhongyou`6,5,2`, you may soon think of the common factor`3`。 (I feel that all possible factors are enumerated in my brain at this time)

If this process is abstracted into the algorithm in the programming language and implemented in code, it is probably`One cycle`+`Judge whether the remainder of all numbers divided by factors is 0`Yes, the time complexity is`O(n)`, as the number of operations increases, the number of code executions increases linearly.

In order to optimize the time complexity, this time is the protagonist of this note——Rolling DivisionYes.

## Rolling Division

It is mentioned above to find the maximum common divisor of multiple integers. Before that, you have to look atTwo integersBinary algorithm

### formula

Rolling division is also known asEuclidean algorithm(Euclidean algorithm), how did you “toss around”? Let’s start with the formula: `A`representativeDivisor(Dividend)；
`B`representativeDivisor(Divisor)；
`A mod B`On behalf of aTake moldB. That is`The remainder of a divided by B`, the expression in C language can be written as`A % B`

there`gcd`Represents`Greatest Common Divisor`, that is`greatest common divisor`。 The meaning of this formula is:

• `The greatest common divisor of [divisor] and [divisor]` = `Maximum common divisor of [divisor] and [remainder]`

This is the whole“Toss and turn”The core of the process. The specific proof will not be repeated here. You can see the at the end of the articleRelated articles

### Toss and turn

Let’s demonstrate this“Toss and turn”Process, calculate`36`and`405`Maximum common factor of: So calledToss and turnActually refers to aIterative operationThe embodiment of iterative operation in programming language is actually the repeated execution of a piece of code in each execution processOperation performed last timeBased on the result value of, after calculating the new valueSubstitute into the next operation, keep usingNew value from old valueUntilUntil the termination conditions are met

The abstract description of rolling division process is as follows:

1. initialization:Two integersMedium`Larger value a`AsDivisor`Smaller value b`AsDivisor

2. Operations: pair`A`and`B`conductModulo (remainder) operation, get`Remainder C`

3. Iteration: divide the original divisor`B`AsDivisor, remainder`C`AsDivisor, repeat the operation in step 2.

4. Iteration termination: when an operation is in progress`remainder`When it is 0, the operation cannot be continued. The algorithm ends and the last operation is completedDivisorIs the first two integersgreatest common divisor

### Intuitive understanding

At first, I thought for a while, but I didn’t think how to understand this kind of division. I didn’t understand the ancient wisdom method – geometric expression until I checked the data.

It can be thought that two integers can actually be regarded asTwo dimensions, it can be expressed by a graph in a two-dimensional space. Obviously, the most suitable figure isrectangleThe opposite sides of the rectangle are equalLength and widthTwo parameters correspond to exactly two integers.

What about the process of division? ActuallyrectangleIt’s both long and wideintegerIn the case where the aspect ratio is a rational number, it is certain to beFinite squaresFull. The process of division is actuallyInsert as large a square as possible into the rectangle

The following is a visual display of the rolling division method`100`and`245`Maximum common divisor of: For the first operation, take the short side 100 as the length to construct a square and fill it (as large as possible). It can be seenThe remaining rectangleThe aspect ratio is`100:45`That’s exactly the next operationDivisorandDivisor In the first iteration, a square is constructed with the short side 45 as the side length, and the remaining rectangular area is`45:10`, corresponding to the next iterationDivisorandDivisor In the second iteration, a square is constructed with the short side 10 as the side length, and the remaining rectangular area is`10:5` In the third iteration, a square is constructed with the short side 5 as the side length,It just fills the remaining rectangular area, the algorithm ends, and the maximum common divisor of the first two integers is`5`

• That is, a certain number of`5×5`Square ofJust enough to fill`100×245`Rectangle (side of a square)`5`Just divisible`100`and`245`）。

It can be seen that the whole process of the algorithm is intuitively reflected, that is, every timeRemaining rectangular spaceInsert inSquare as large as possibleUntilThe square is just enough to fill the remaining rectangular space
(this is why the first operation divides the larger value by the smaller value)

### Concrete implementation

Here, the rolling division algorithm is implemented in C language:

``````// #include
long int GCD(long int num1, long int num2) {
//Finding the greatest common divisor of two numbers (Euclidean algorithm)
//Formula GCD (divisor, divisor) = GCD (divisor, remainder)
//Here, in order to understand the complexity of writing, three local variables are newly defined
long int dividend; //  Divisor
long int divisor; //  Divisor
long int remainder; //  remainder
num1 = labs(num1); //  Set two numbers with absolute values
num2 = labs(num2);
If (num1 > num2) {// use the smaller number as the divisor
dividend = num1;
divisor = num2;
} else {
dividend = num2;
divisor = num1;
}
do {
remainder = dividend % divisor;
dividend = divisor; //  Replace the divisor with the divisor
If (remain) {// if the remainder is not 0, replace the divisor with the remainder
divisor = remainder;
}
} while (remainder != 0);
return divisor;
}``````

### Time complexity

It is found that the core operation of the algorithm is“Take mold”(Modulo)。 The whole algorithm may depend on multiple iterations, and the modular operation will be carried out in each iteration, and the amount of data left for the next operation after each modular operation will be relatively reducedMore than half

Why cut it by more than half? Because every division operationremainderThe absolute value of is certainLess than half the absolute value of the divisor`|Remainder | < 0.5 | divisor|`

The following is a text explanation (all numbers in this picture arepositive integer）： Anyway, mentionData halved, I can’t help thinking of two-point search. Each iteration of binary search only processes the data in the last operationhalfData. In this way, we can calculate its time complexity`O(log2(n))`Level (I tried before)calculationI’ve been through this.

go back toRolling Division:  (a is the divisor and B is the divisor)

twiceiterationin, a and B, respectivelyReduced by half, that is: For divisor`B`For example, every timeHalveWhen in this range:`1； Therefore, the number of iterations is at most 2log (min {a, B}) (here the divisor is B, i.e. 2log (b)).`

Why`min{A,B}`(take the smaller value of a and b) because of the complexity of the algorithmTermination conditionsyesThe remainder is 0, it can also be understood asDivisor is 0, and the algorithm will chooselessValue of asDivisor

So the time complexity of rolling division is`O(logn)`Level.

For twopositive integerofRolling DivisionFor example:

• Best case scenario

First operationremainderThat is 0, one-step completion, and time complexity • Worst case scenario

Iterate untilDivisorby`1`(1 is the common factor of all integers),The remainder is 0, the time complexity level is ## Find the maximum common divisor of multiple integers

Rolling division is aimed atTwo integersBinary algorithm.

If the greatest common divisor of multiple integers is required, it only needs to be transformed intoMultiple binary rolling division operationJust.

### C language implementation

``````#include
#include

//GCD is the binary rolling division function mentioned above

long int ArrGCD(long int *arr, int arrLen) {
long int temp = arr;
int i;
for (i = 1; i < arrLen; i++)
temp = GCD(temp, arr[i]); //  Use the maximum common divisor of the previous time and the current number for rolling and dividing
return temp;
}

int main() {
long int testArr[] = {405, 45,180,210};
int arrLen = sizeof(testArr) / sizeof(int);
printf("%ld\n", ArrGCD(testArr, arrLen));
return 0;
}``````

Core method: useThe maximum common divisor of the previous pair of values is divided by the current number, iterate through the array.

### Time complexity

The time complexity level of the previous rolling division of two integers is 。 Here, you need to traverse the array elements once, andEach traversal of an element requires a rolling division algorithm

The time complexity of the algorithm for finding the maximum common divisor of multiple integers is: ## Find the least common multiple The first is to find the greatest common divisorDivideThe concept of. In addition to fraction reduction, there is a very important operation skill in fraction operationGeneral points

All points are looking forLeast common multiple

### On the least common multiple

Common multipleIs two integers`A`,`B`Common multiple, i.eCommon multipleCan be`A`and`B`to be divisible by.

Of two integersCommon multipleThere are infinite numbers, and among these common multiplesExcept 0The smallest one isLeast common multiple`Least Common Multiple`）。

Note: like the greatest common divisor,Least common multipleThe general rule ispositive integer ### Calculate the least common multiple with the maximum convention number

After finding the greatest common divisor, finding the least common multiple is a piece of cake ~ becauseLeast common multipleandgreatest common divisorThere is one property: Namely`Least common multiple × Maximum common divisor = product of two integers`

When the maximum common divisor is known, use`Product of two integers / maximum common divisor`Can calculate`Least common multiple`

PS: I won’t say much about the proof of this formula

### C language implementation

The implementation here is very simple. You can call the above function for finding the maximum common divisor once.

But there is one thing to pay attention to in the program. It’s best not to write it in English`Product of two integers / maximum common divisor`Form of. If two integersThe values are very large, it is easy to happen in the process of calculationdata overflow Question.

In order to avoid overflow as much as possible, it can be written as`A / maximum common divisor * B`Form of.

``````long int LCM(long int num1, long int num2) {
long int divisor = GCD(num1, num2); //  GCD is the function of finding the greatest common divisor mentioned above
num1 = labs(num1); //  Generally, LCM is also limited to positive integer
num2 = labs(num2);
return (num1 / divisor) * num2; // A/GCD * B
}``````

### Time complexity

Because the above writing is actuallyThe rolling division algorithm is appliedTherefore, the time complexity is the same: ## Find the least common multiple of multiple integers

andFind the maximum common divisor of multiple integersSimilarly, it can be realized by multiple binary iterative operations.

### C language implementation

``````long int ArrLCM(long int *arr, int arrLen) {
long int temp = arr;
int i;
For (I = 1; I < arrlen; I + +) // traverse from the second element
temp = LCM(temp, arr[i]); //  LCM is the function of finding the least common multiple mentioned above
return temp;
}``````

### Time complexity

Consistent with the above method for finding the maximum common divisor of multiple integers: ## summary When my head was hot, I wrote such a note. In the process of writing, I deeply realized my lack of ability in proving formulas Keep going!

In addition, I may have some problems in my understanding of the time complexity of the rolling division method. I hope you can correct it.

## Big data Hadoop — spark SQL + spark streaming

catalogue 1、 Spark SQL overview 2、 Sparksql version 1) Evolution of sparksql 2) Comparison between shark and sparksql 3）SparkSession 3、 RDD, dataframes and dataset 1) Relationship between the three 1）RDD 1. Core concept 2. RDD simple operation 3、RDD API 1）Transformation 2）Action 4. Actual operation 2）DataFrames 1. DSL style syntax operation 1) Dataframe creation 2. SQL […]