leetcode: String to Integer (atoi)

原題:String to Integer (atoi)

這道題放在leetcode上,多了一些需求,要求處理非法字符,其實是經典的字符串提取操作。

問題要求

一個字符串是合法的,則它的前綴必須是由若干個空格組成的(可以沒有),可以有1個正負號(多個也被認爲是非法的),正負號緊接着的是0-9的數字,後綴的任何非法字符都不用管。

要求:將合法的字符串轉換成int數值,若轉換後超過INT的範圍,則對應返回其上界或下界;非法字符串統一返回0。

思路

我把解決問題的邏輯分爲兩部分:
1. 提取合法字符串的數字部分,並確認其正負性,非法字符串則在這個過程中被變成空串;
2. 將提取後的字符串轉換成int數值。

提取字符串的過程

直接看代碼和註釋:

bool isNum(char ch) {
    return (ch >= '0' && ch <= '9');
}

bool isSign(char ch) {
    return (ch == '+') || (ch == '-');
}

bool strip(string& str) {
    int len = str.size(), left = 0, right;
    // 前綴只允許空格,其它非法字符則表示該字符串非法,應返回0
    while (left < len && !isNum(str[left]) && !isSign(str[left])) {
        if (str[left] != ' ') {
            str = "";
            return false;
        }
        ++left;
    }

    // 處理正負號
    bool isNeg = false;
    if (isSign(str[left])) {
        isNeg = str[left] == '-';
        ++left;
    }

    // 後綴的非法字符全部不用管,只看數字就好了
    right = left;
    while (right < len && isNum(str[right]))
        ++right;

    str = str.substr(left, right - left);
    return isNeg;
}

str2int

這裏給的參數是處理過後的字符串了,不用擔心非法字符,可以專心做轉換,有偷懶的方法(用C++的sstream),也有務實的方法。

先聲明一下:

static const int INT_MAX_VALUE = 0x7fffffff, INT_MIN_VALUE = 0x80000000;
// 偷懶的方法
int str2int(const string& str, bool isNeg) {
    double num;
    stringstream ss(str);
    ss >> num;
    if (isNeg)
        num = -num;
    if (num > INT_MAX_VALUE)
        return INT_MAX_VALUE;
    if (num < INT_MIN_VALUE)
        return INT_MIN_VALUE;
    return num;
}

務實的方法爲:

// 務實的方法
int str2int(const string& str, bool isNeg) {
    long long num = 0;
    for (int i = 0; i < str.size(); ++i) {
        num *= 10;
        num += (int)(str[i] - '0');
        if (!isNeg && num > INT_MAX_VALUE) {
            return INT_MAX_VALUE;
        } else if (isNeg && -num < INT_MIN_VALUE) {
            return INT_MIN_VALUE;
        }
    }

    return isNeg ? -num : num;
}

這裏利用了long long的便利,其實可以用int來存放num的,只是要多加一些判斷而已!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章