offer17
输入一个表示整数的字符串,把该字符串转换成整数并输出。例如输入字符串"345",则输出整数345。
需要考虑到为负数,字符串中出现其他的非数字字符,数值溢出等情况。
bool str_to_int(const char *a,int &n){
if(a==NULL){
printf("error,input is empty!\n");
return false;
}
char sign=0;
int len=strlen(a);
int i=0;
long long num=0;
//这里需要注意,最小负数的绝对值比最大正数要大1,所以需要用longlong保存。
long long lim=INT_MAX;
lim++;
if(*a=='+'||*a=='-'){
sign=*a;
i++;
}
for(;i<len;i++)
{
//检查是否是数字字符
if(!(a[i]>='0'||a[i]<='9')){
printf("error,input is not int!\n");
return false;
}
num=num*10+(int)(a[i]-'0');
if(num>lim){
printf("error,input is too big!\n");
num=0;
return false;
}
}
if(sign=='-')
num=-num;
//如果超出范围,主要是考虑到最小负数的绝对值,
if(num<INT_MIN||num>INT_MAX){
printf("error,input is too big!\n");
num=0;
return false;
}
n=num;
return true;
}
offer38
输入数字n,按顺序输出从1最大的n位10进制数。比如输入3,则输出1、2、3一直到最大的3位数即999。
这时候需要考虑n很大时,需要用字符串来保存数值,要模拟加1的操作。
void AddOne(char *a)
{
int len=strlen(a);
len--;
int sign=0;
sign=((a[len]-'0')+1)/10;
a[len]=((a[len]-'0')+1)%10+'0';
while (sign)
{
len--;
sign=((a[len]-'0')+1)/10;
a[len]=((a[len]-'0')+1)%10+'0';
}
}
void Print(char *a)
{
int n=strlen(a);
int i;
for (i=0;i<n;i++)
{
if (a[i]!='0')
break;
}
printf("%s \n",a+i);
}
void PrintNum(int n)
{
char *a=(char*)malloc(sizeof(char)*(n+2));
memset(a,'0',n+1);
a[n+1]='\0';
printf("%s \n",a);
AddOne(a);
Print(a);
while (a[0]=='0')
{
Print(a);
AddOne(a);
}
}
offer44
实现函数double Power(double base, int exponent),求base的exponent次方。不需要考虑溢出。
在最笨的算法能够实现时,我们需要对其进行优化,
首先要考虑错误的情况,o的负次方是不存在的,这里规定了函数原型,无法用返回值来判定输入的合法性,可以考虑用全局变量标志。可以考虑用递归区分次方的奇偶。就可以了
bool InvalidInput=false;
double PowerNoNegtive(double base, int exponent)
{
if (base==0)
return 0.0;
if (exponent==1)
return base;
if (exponent==0)
return 1;
if (exponent%2)
{
double temp=PowerNoNegtive(base,(exponent-1)/2);
return temp*temp*base;
}
else
{
double temp=PowerNoNegtive(base,exponent/2);
return temp*temp;
}
}
double Power(double base, int exponent)
{
if (base==0&&exponent<0)
{
InvalidInput=true;
return 0.0;
}
if (exponent<0)
{
return 1.0/PowerNoNegtive(base,-exponent);
}
else
return PowerNoNegtive(base,exponent);
}