1. 程式人生 > >7.Reverse Integer題目和答案詳解

7.Reverse Integer題目和答案詳解

1 題目簡述

 Given a 32-bit signed integer, reverse digits of an integer.

 給定一個32位有符號整數,反轉這個整型數。

Example 1:

  Input: 123

  Output:  321

Example 2:

  Input: -123

  Output: -321

Example 3:

  Input: 120

  Output: 21

  Assume we are dealing with an environment which could only hold integers within the 32-bit signed integer range. For the purpose of this problem, assume that your function returns 0 when the reversed integer overflows.
  假設我們正在處理一個只能在32位有符號整數範圍內儲存整數的環境。為了解決這個問題,假設當反整數溢位時,函式返回0。給定一個32位有符號整數,反轉這個整型數。

2 答案詳解

(1) 解決思想

  本次解答採用C++編寫,C++相對於C語言的一個重要的特點是:面向物件程式設計(OOP),故我們採用類的方法來實現所述要求。要處理的是32位有符號整數,即int型整數,對於不同系統和編譯器的int型別是不是佔4個位元組,讀者可以自己用sizeof()函式確認,只要找到佔4個位元組的整型即可,在這不做過多討論。   首先,要知道佔4個位元組的有符號整型(以後將用int代替)的十進位制範圍為:-2147483648~2147483647,在標頭檔案climits中對其最大值和最小值進行了巨集定義:INT_MAX和INT_MIN。若給定整型數的反轉數超出了這個範圍,將返回結果0。
  然後,可以知道若給定整數為-9~9時,將返回其本身大小的值;為了掃除接下來的障礙,做這樣的操作:可以看到INT_MIN的反轉數必定超出了int範圍,故若給定的整數等於INT_MIN時,返回結果0。   之後,對於剩下int範圍內的整數,可知道均是2位以上的十進位制數(無論正負)。對於給定整數是否為正數,可以先設定一個符號變數sign;若為正數,sign=1,若為負數,sign=-1。並先將給定整數*sign來使其變為正數,這是出於操作便利的目的,將在後面的操作體現;這也是為什麼上一步要單獨討論INT_MIN的原因,因為INT_MIN取其正數時將溢位。接下來定義一個儲存int資料的容器,對給定數逐步進行對10取餘和對10相除,將給定數按低位到高位的數字逐步插入容器中。注意:負數對負數進行取餘時,除結果為0的情況外,仍為負數。
  最後,從容器的兩端開始遍歷,因為最後插入容器中的數字是給定整數的最高位,則它與容器始端的距離即為所要相乘的10的次方數。現在求給定整數的反轉數,即始端數字要乘以最後一個數字的10的次方數,依此類推,求取次方數時,從最後一個數字往前遍歷容器;抽取數字時,從容器始端往後遍歷;定義一個long(8個位元組整型)judge,每抽取一次數字與10的次方相乘後,將結果加到judge中,並將judge與sign相乘,若溢位則返回結果0,若沒溢位,則再次將judge與sign相乘確保變為正數,繼續進行抽取數字操作。若最終judge沒有溢位,將返回結果judge*sign確保反轉數與給定整數符號相同。

(2) 設計程式

   所設計的程式採用類模板,這樣可以對程式碼進行重用,從而對各種整數進行反轉時無需做過多的程式改動,程式如下:
#include <iostream>
#include <climits>
#include <iterator>
#include <vector>
#include <cmath>

using std::vector;
using std::iterator;
using std::cout;
using std::endl;

template<class T>
class ReverseInteger
{
private:
    T num_;
public:
    ReverseInteger(const T& num = 0):num_(num) {}
    T result();
};

template<class T>
T ReverseInteger<T>::result()
{
    vector<T> nums;
    T num(num_);
    T res(0);
    T divisor(10);
    int sign(1);
    typename vector<T>::iterator ith;
    typename vector<T>::iterator itt;
    if(num == INT_MIN ) {
        return res;
    } else if(num < -9) {
        sign = -1;
        num = -num;
    } else if(num < 10) {
        return res = num;
    }
    while(num % divisor or num / divisor) {
        nums.push_back(num % divisor);
        num /= divisor;
    }
    ith = nums.begin();
    itt = nums.end()-1;
    long judge(0);
    long max(INT_MAX);
    long min(INT_MIN);
    int n;
    do {
        n = distance(nums.begin(),itt);
        judge += (*ith) * pow(10,n);
        judge = judge * sign;
        if(judge > max or judge < min) {
            return res = 0;
        }
        judge = judge * sign;
        ith++;
        itt--;
    } while(itt != nums.begin()-1);
    return res = judge * sign;
}

int main()
{
    int data = -123456789;
    int res;
    ReverseInteger<int> ri(data);
    res = ri.result();
    cout << "integer number:" << data << endl;
    cout << "res:" << res << endl;
}
程式執行結果為:
integer number: -123456789 res: -987654321