剑指offer 17 打印从1到最大的n位数 题目:定义一个实现任意两个整数的加法函数。

题目:

输入数字n,按顺序打印从1到最大的n位十进制数。比如输入3,则打印出1,2,3一直到最大的三位数999。

思路:

这里由于没有规定n的取值范围,我们需要考虑当n很大时,使用int 、long long 都会溢出的情况。并不是简单的计算出最大的n位数,再打印。

那么最常用的方法就是用字符串或者数组来表示一个大数。

因为数字最大是n位,我们需要一个长度为n+1的字符串(字符串最后一位是结束符'\0')。

当实际数字不够n位的时候,在字符串的前半部分补0。

因此,代码具体步骤:

1、将字符串的每一个数字都初始化为‘0’

2、在字符串表达的数字上模拟加法

3、把字符串表达的数字打印出来

代码:

void Print1ToMax(int n)

{
 if(n<=0)
  return;
 char*number=new char[n+1];
 memset(number,'0',n);
 number[n]='\0';
 while(!increment(number))
 {
   printfnumber(number));
 }
   delete[] number;
}

将数字字符转换成对应的数字的方法:

b=a-'0';//其中a为数字字符,b为数字字符a对应的数字。

 //函数实现在表示数字的字符串上加1

bool increament(char*number)

{
 bool isoverflow=false;
   int takeover=0;//进位标识符
  int length=strlen(number);
  for(int i=length-1;i>=0;i--)
{
  int sum=number[i]-'0'+takeover;//将数字字符转换为对应的数字,并考虑进位情况
  if(i==length-1)
  sum++;
 if(sum>=10)
 { 
   if(i==0)
   isoverflow=true;
   else 
  {
    sum-=10;
    takeover=1;
    number[i]='0'+sum;//将数字转换为对应的字符串
  }
}
 else 
 {
  number[i]='0'+sum;
  break;
 }
}
return isoverflow;
}
//函数实现了打印用字符串表示的数字
//前面提到,当数字不够n位的时候,在数字的前面补0,但是打印的时候这些补位的0不应该打印出来
//在此函数里,只有在碰到第一个非0字符后才开始打印,直至字符串的结尾
void printfnumber(char *number)
{
  bool isbegining0=true;
  int length=strlen(number);
  for(int i=0;i<length;i++)
 {
  if(isbegining0&&number[i]!='0')
  isbegining0=false;
  if(!isbegining0)
  printf("%c",number[i]);
 }
printf("\t");
}

总结:

如果面试题是关于n位的整数并且没有限定n的取值范围,或者输入任意大小的整数,那么这道题目很有可能是考察大数问题的。

记住:字符串时一种有效表示大数的方法

题目二:

题目:定义一个实现任意两个整数的加法函数。

考点:大数相加

#include<iostream>  
using namespace std;  
char *BigNunAdd(char *str1, char *str2)  
{  
    int len1 = strlen(str1);  
    int len2 = strlen(str2);  
    int len = len1 > len2?len1 : len2;  
    char *res = new char[len + 2]; //len+2,考虑进位和‘\0’ 
    memset(res, '0', len + 2);  
    res[len + 1] = '\0';  
  
    int p1 = len1 - 1;  
    int p2 = len2 - 1;  
    int p = len;  
    int ntake = 0; //进位标志
    // 两个数,对应位相加
    while (p1 >= 0 && p2 >= 0)  
    {  
        int temp =str1[p1] - '0' + str2[p2] - '0'+ntake;  //将数字字符转化为对应的数字并考虑到进位情况
        ntake = 0;  
        if (temp >= 10)  
        {  
            ntake = 1;  
            temp -= 10;  
        }  
        res[p] += temp;  
        p--;  
        p1--;  
        p2--;  
    }  
    //其中一个数字位数比较低,高位只剩一个数时如:327+15
    if (p1 >= 0)  
    {  
        while (p1 >= 0)  
        {  
            int temp = str1[p1] - '0' + ntake;  //看前面是否有进位
            ntake = 0;  
            if (temp >= 10)  
            {  
                ntake = 1;  
                temp -= 10;  
            }  
            res[p] += temp;  
            p--;  
            p1--;  
        }  
    }  
    //同上  
    if (p2 >= 0)  
    {  
        while (p2 >= 0)  
        {  
            int temp = str1[p2] - '0' + ntake;  
            ntake = 0;  
            if (temp >= 10)  
            {  
                ntake = 1;  
                temp -= 10;  
            }  
            res[p] += temp;  
            p--;  
            p2--;  
        }  
    }  
    res[p] += ntake;  
    //返回res
    return res;  
}  
有关大数相乘和大数相减的题目: https://blog.csdn.net/kiwi_berrys/article/details/52444024

猜你喜欢

转载自blog.csdn.net/weixin_41413441/article/details/80724217