[Sword Finger Offer]-implement specific library functions pow, atoi

In the interview questions, there are often functions for processing numeric values ​​and strings. In this article, we mainly explain the implementation of a pow and atoi function ~

One, pow function

Topic requirements

Implement the function double Power (double base, int exponent), find the exponent power of base. Do not use library functions and do not need to consider large numbers.

Topic analysis

Because there is no need to consider the problem of large numbers, first of all, when we get this problem, the idea that came out of our brain is realized as follows:

double Power(double base, int exponent)
{
	double result = 0;
	for (int i = 0; i <= exponent; i++)
	{
		result *= base;
	}
	return result;
}

But writing like this is definitely wrong. There are many shortcomings

Improvement 1: Consider the case where the base is 0 and the exponent is negative.
Because of such a special case, we need to consider the way of error handling.
In the programs we write, there are usually three error handling methods. The following shows their corresponding advantages and disadvantages
Insert picture description here
. The improved code is as follows:

bool g_InvalidInput = false;

double Power(double base, int exponent)
{
	g_InvalidInput = false;

	if (equal(base, 0.0) && exponent < 0)
	{
		g_InvalidInput = true;
		return 0.0;
	}

	unsigned int absExponent = (unsigned int)(exponent);
	if(exponent < 0)
		absExponent = (unsigned int)(-exponent);

	double result = Powerresult(base, absExponent);
	if (exponent < 0)
		result = 1.0 / result;
	return result;
}		

In our code above, we use global variables to identify whether something went wrong. If something goes wrong, the value returned is 0. However, in order to distinguish whether it returns 0 when an error occurs or returns to 0 when the base is 0, we designed the g_InvalidInput global variable to distinguish. When an error occurs, this variable is set to true, otherwise it is false.

Improvement 2: More efficient Powerresult method
If our input exponent is 32, in our previous cycle, we have to do 31 cycles, but we think about it. There seems to be a more concise method.
Here we are going to mention a solution we mentioned in the Fibonacci sequence. There is a method of using a mathematical formula in the Fibonacci sequence. Its time complexity is O (logn). The mathematical formula considering power is as follows:
Insert picture description here
from the above formula, we can see that we want to improve the method n times Square, we must first get the n / 2 power, and then square the result of the n / 2 power. This can be achieved with a recursive idea.
With the foreshadowing of the Fibonacci sequence, it is easier for us to think about the function. Because we are asking for the 32nd power, from which we calculate the 16th power, the 8th power, the 4th power, and the square. The mathematical formula derived from this is as follows:
Insert picture description here
Based on the above formula, the code is implemented as follows:

double Powerresult(double base, unsigned int exponent)
{
	if (exponent == 0)
		return 1;
	if (exponent == 1)
		return base;

	//递归乘法的过程
	double result = Powerresult(base, exponent >> 1);
	result *= result;

	//指数为奇数的情况
	if ((exponent & 0x1) == 1)
		result *= base;

	return result;
}

Two, atoi function

Topic requirements

Convert the string to an integer, for example, enter the string "123", his output is the number 123

Topic analysis

First get this question, according to the requirements of the question, we naturally only think of the case of turning "123" into the number 123. But this question is not only so simple but only considers such a situation, it also has many special input situations that need to be considered in small details.

Case 1 : Check if the string is empty

str != nullptr

Case 2 : When the input string is "0"

Here, when the string we input is "0", his return value should be 0, but it conflicts with the return of 0 when the string is an empty string, so we need to set a global variable to distinguish. If it is illegal input, it returns 0 and sets the global variable as a special mark; if the input is the string "0", it returns 0, and the global variable will not be set.

enum Status{kValid = 0,kInvaild};
int g_nStatus = kValid;

** Case 3: ** Not all characters other than "0" ~ "9" are illegal, the input string will have a difference between positive and negative signs, so the plus and minus signs should also be legal input

if (*str == '+')
   str++;
else if (*str == '-')
{
	str++;
	minus = true;
}

Case 4 : Consider the case where the largest positive integer value is 0x7FFFFFFF and the smallest negative integer value is 0x80000000

The complete code implementation is as follows:
we divided two functions to specifically implement the StrToInt function mainly to determine whether it is a legal input, StrToIntCore is the core code for the specific conversion

enum Status{kValid = 0,kInvaild};
int g_nStatus = kValid;
long long StrToIntCore(const char* digit, bool minus);

int StrToInt(const char* str)
{
	g_nStatus = kInvaild;
	long long num = 0;

	if (str != nullptr && *str != '\0')//空串判断
	{
		bool minus = false;//设置一个布尔值来保存符号
		//符号判断
		if (*str == '+')
			str++;
		else if (*str == '-')
		{
			str++;
			minus = true;
		}

		//其余字符串转换
		if (*str != '\0')
		{
			num = StrToIntCore(str, minus);
		}
	}
	return (int)num;
}
long long StrToIntCore(const char* digit, bool minus)
{
	long long num = 0;

	while (*digit != '\0')
	{
		if (*digit >= '0' && *digit <= '9')
		{
			int flag = minus ? -1 : 1;
			num = num * 10 + flag * (*digit - '0');//核心代码

			//溢出判断
			if ((!minus && num > 0x7FFFFFFF) || (minus && num < (signed int)0x80000000))
			{
				num = 0;
				break;
			}
			digit++;
		}
		else//非法输入
		{
			num = 0;
			break;
		}
	}
	//输入为'\0'的合法情况
	if (*digit == '\0')
	{
		g_nStatus = kValid;
	}
	return num;
}
Published 98 original articles · won praise 9 · views 3649

Guess you like

Origin blog.csdn.net/qq_43412060/article/details/105403765