面试题17:打印从1到最大的n位数

面试题17:打印从1到最大的n位数

题目:输入数字n,按顺序打印出从1到最大的n位十进制数

分析:由于n未知,可能是非常大的数,常规的数据类型可能装不下,考虑用字符串数组来存储数字,但需要考虑一下两个问题:

  1. 字符串数组表示数字的相加算法(通过模拟十进制数的加法过程完成或其他方法);
  2. 规范得打印出数字。

代码:

#include <stdio.h>

///
///题目:打印1到n位的最大数(考虑大数问题,用字符串来表示数字)
///

void print1toNMaxRecursively(int n);

//字符窜表示的数字自增1,返回值表示是否溢出
bool charNumberIncrease(char *number, int length);

//打印字符窜表示的数字
void printCharNumber(char *number, int length);

int main()
{
  print1toNMaxRecursively(5);
  return 0;
}

void print1toNMaxRecursively(int n)
{
  if (n <= 0)
  {
    return;
  }

  char *number = new char[n + 1];
  for (int i = 0; i < n; i++)
  {
    number[i] = '0';
  }
  number[n] = '\0';
  while (!charNumberIncrease(number, n))
  {
    printCharNumber(number, n);
  }
}

//字符窜表示的数字自增1
bool charNumberIncrease(char *number, int length)
{

  bool isOverflow = false;
  int takeOver = 0;
  int sum = 0;
  for (int i = length - 1; i >= 0; i--)
  {
    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] = sum + '0';
      }
    }
    else
    {
      number[i] = sum + '0';
      break;
    }
  }

  return isOverflow;
}

//打印字符窜表示的数字
void printCharNumber(char *number, int length)
{
  bool isBeginPrint = false;
  for (int i = 0; i < length; i++)
  {
    if (!isBeginPrint && number[i] != '0')
    {
      isBeginPrint = true;
    }
    if (isBeginPrint)
    {
      printf("%c", number[i]);
    }
  }
  printf(",");
}

除了通过模拟十进制数的加法过程来完成以外,还可以通过全排列的思路完成:由于是打印出1到n位的最大数,那么可以将改问题看成打印n位数的全排列,以下通过递归的方式编写代码:

void print1toNMaxRecursively(int n)
{
    if (n <= 0)
    {
        return;
    }

    char *number = new char[n + 1];
    for (int i = 0; i < n; i++)
    {
        number[i] = '0';
    }
    number[n] = '\0';
    for (int i = 0; i < 10; i++)
    {
        number[0] = i + '0';
        print1toNMaxRecursiveCore(number, n, 0);
    }

    delete[] number;
}

//全排列打印的核心函数
void print1toNMaxRecursiveCore(char *number, int length, int index)
{
    if (index == length - 1)
    {
        printCharNumber(number, length);
        return;
    }

    for (int i = 0; i < 10; i++)
    {
        number[index + 1] = i + '0';
        print1toNMaxRecursiveCore(number, length, index + 1);
    }
}

相关题目:计算两个大数相加的结果(只考虑正数)
代码:

///
///题目:两个大数相加(只考虑正数),输入:三行,第一行输入相加两数的最大位数N,后两行分别输入一个大数
///

#include <iostream>
#include <stdio.h>
using namespace std;

//两个字符串表示的大数相加
char *addBigNumber(char *num1, char *num2, int maxLength);

//打印字符窜表示的数字
void printCharNumber(char *number, int length);

int main()
{
    cout << "input three line:N:max bit and two big number" << endl;
    int N = 0;
    cin >> N;
    char *num1 = new char[N + 1];
    char *num2 = new char[N + 1];
    cin >> num1;
    cin >> num2;

    char *sum = addBigNumber(num1, num2, N);
    if (sum != NULL)
    {
        cout << "sum:";
        printCharNumber(sum, N + 1);
    }
    return 0;
}

//两个字符串表示的大数相加
char *addBigNumber(char *num1, char *num2, int maxLength)
{
    if (maxLength <= 0)
    {
        return NULL;
    }

    int index1 = 0, index2 = 0;
    for (; num1[index1] != '\0'; index1++)
    {
        if (!(num1[index1] >= '0' && num1[index1] <= '9'))
        {
            cout << "invali input!" << endl;
            return NULL;
        }
    }

    for (; num2[index2] != '\0'; index2++)
    {
        if (!(num2[index2] >= '0' && num2[index2] <= '9'))
        {
            cout << "invalid input!" << endl;
            return NULL;
        }
    }
    index1--;
    index2--;

    int max = index1 > index2 ? index1 : index2;
    if (maxLength < max)
    {
        cout << "invali input!" << endl;
        return NULL;
    }

    //预留一位,防止溢出
    char *sum = new char[maxLength + 2];
    sum[maxLength + 1] = '\n';
    int takeOver = 0;
    for (int i = maxLength; i >= 0; i--)
    {
        int n1 = 0, n2 = 0;
        if (index1 >= 0)
        {
            n1 = num1[index1] - '0';
        }
        if (index2 >= 0)
        {
            n2 = num2[index2] - '0';
        }

        int temp = n1 + n2 + takeOver;
        if (temp >= 10)
        {
            temp -= 10;
            takeOver = 1;
            sum[i] = temp + '0';
        }
        else
        {
            sum[i] = temp + '0';
            takeOver = 0;
        }
        index1--;
        index2--;
    }

    return sum;
}

//打印字符窜表示的数字
void printCharNumber(char *number, int length)
{
    bool isBeginPrint = false;
    for (int i = 0; i < length; i++)
    {
        if (!isBeginPrint && number[i] != '0')
        {
            isBeginPrint = true;
        }
        if (isBeginPrint)
        {
            cout << number[i];
        }
    }
    cout << endl;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值