打印 1 到最大的 n 位數(使用字符串表示正數)

    打印 1 到最大的 n 位數:輸入數字 n 按順序打印出從 1 最大的 n 爲十進制數。例如,輸入 3 , 打印 1, 2, ... , 999.ios

    分析:注意沒有規定 n 的範圍,當 n 很大時,求最大的 n 位整數使用 int 或 long 類型都有可能會溢出。所以,最經常使用的解決方法是使用字符串或者是數組表達大數。git

    使用字符串表示的時候,最直觀的方法就是使用字符 '0' ~'9' 之間的某一個字符來表示數字中的一位。由於數字最大是 n 位的,因此,須要一個 n + 1 的字符串(最後一個的符號位 '\0')。當實際數字不夠 n 位時,在字符串的前半部分補零。數組

    首先將字符串的每一位初始化爲 '0',而後,每一次爲字符串表示的數字加 1,在打印出來。所以,至於要作兩件事:(一) 在字符串表達的數字上模擬加法,(二)把字符串表達的數字打印出來。函數

//主例程
void Print1ToMaxOfNDigits(int n)
{
 if(n <= 0)
  return;
 char *number = new char[n + 1];
 memset(number, '0', n);
 number[n] = '\0';
 while(!Increment(number))
 {
  PrintNumber(number);
 }
 delete [] number;
}
spa

上述代碼中,Increment()函數實如今表示數字的字符串 number 上增長 1 ;而函數 PrintNumber()打印出 number 。這兩個看似簡單的函數都暗藏着小小的玄機。code

   1) 須要知道在何時中止在 number 上加 1,一個最簡單的辦法就是每次遞增以後,都調用庫函數 strcmp()比較表示數字的字符串 number 和最大位數 n 位數字 「99...9」,若是想等表示已經到了最大的 n 位數並終止遞增。雖然調用 strcmp 很簡單,但對於長度爲 n 的字符串,它的時間複雜度爲 O(n)。ci

咱們注意到只有在「99...9」加 1 的狀況下,纔會在第一個字符(下標爲 0)的基礎上產生進位,而其餘全部的狀況都不會在第一個字符上產生進位。所以,當咱們發現加 1 在第一個字符上產生進位時,則已是最大的 n 位數,此時,Increment 函數返回 true,函數 Print1ToMaxOfNDigits 中的while 循環終止。rem

如下代碼實現了用 O(1) 的時間判斷是否已經達到了最大的 n 位數:字符串

 

bool Increment(char *number)
{
 bool IsOverflow = false; //判斷是否溢出(超出最大位數 n)
 int nTakeOver = 0;   //進位
 int length = strlen(number);
it

 for(int i = length - 1; i >= 0; i--)
 {
  int nSum = number[i] - '0' + nTakeOver;
  if(i == length - 1)
   nSum++;   //每次調用數值增1
  if(nSum >= 10)
  {
   if(i == 0)
    IsOverflow = true;    //在第一位字符處產生進位時,返回 true
   else
   {
    nSum = nSum - 10;
    nTakeOver = 1;
    number[i] = '0' + nSum;
   }
  }
  else
  {
   number[i] = '0' + nSum;
   break;
  }
 }
 return IsOverflow;
}

2)如何打印用字符串表示的數字:因爲 當數字不夠 n 位時,咱們在數字的前面補零,打印時這些補位的 0 不該該打印出來,所以,不能簡單的使用 printf 進行打印。爲此,咱們定義了函數 PrintNumber(),在這個函數裏,只有在碰到第一個非零的字符時纔開始打印,直到字符串的結尾。

void PrintNumber(char *number)
{
 bool isBeginning0 = true;
 int length = strlen(number);
 for(int i = 0; i < length; i++)
 {
  if(isBeginning0 && number[i] != '0')
   isBeginning0 = false;
  if(!isBeginning0)
  {
   cout << number[i];
  }
 }
 printf("\t");
}

總代碼:

//打印 1 到最大的 n 位數
#include<iostream>
using namespace std;
bool Increment(char *number)
{
 bool IsOverflow = false; //判斷是否溢出(超出最大位數 n)
 int nTakeOver = 0;   //進位
 int length = strlen(number);
 //cout << length << endl;
 for(int i = length - 1; i >= 0; i--)
 {
  int nSum = number[i] - '0' + nTakeOver;
  if(i == length - 1)
   nSum++;   //每次調用數值增1
  if(nSum >= 10)
  {
   if(i == 0)
    IsOverflow = true;
   else
   {
    nSum = nSum - 10;
    nTakeOver = 1;
    number[i] = '0' + nSum;
   }
  }
  else
  {
   number[i] = '0' + nSum;
   break;
  }
 }
 return IsOverflow;
}
void PrintNumber(char *number)
{
 bool isBeginning0 = true;
 int length = strlen(number);
 for(int i = 0; i < length; i++)
 {
  if(isBeginning0 && number[i] != '0')
   isBeginning0 = false;
  if(!isBeginning0)
  {
   cout << number[i];
  }
 }
 printf("\t");
}
//主例程
void Print1ToMaxOfNDigits(int n)
{
 if(n <= 0)
  return;
 char *number = new char[n + 1];
 memset(number, '0', n);
 number[n] = '\0';
 while(!Increment(number))
 {
  PrintNumber(number);
 }
 delete [] number;
}
int main()
{
 int n;
 cin >> n;
 Print1ToMaxOfNDigits(n);
 cout << endl;
 system("pause");
 return 0;
}
相關文章
相關標籤/搜索