從給定字串中查詢有效的整數


在這個問題中,我們需要按照題目說明中的規則從給定的字串中提取整數。我們可以透過檢查字串的初始子字串是否符合給定的有效整數值規則來解決問題。

題目描述 – 我們給定一個包含數字、‘.’、‘+’ 和 ‘-’ 字元的字串 digits。我們需要從給定的字串中提取有效的整數值。

有效整數的規則

  • 它不應該包含前導零和空格。

  • 整數應該以符號或數字開頭。

  • 如果沒有給出任何符號,則認為整數為正數。

  • 如果字串包含小數部分,則從字串中提取整數部分。

  • 如果字串包含數字值之前的其他字元(除了數字),則列印 0。

  • 如果字串在整數值之後包含其他字母數字,則提取並列印整數值。

  • 整數應該在 -2147483647 和 2147483647 之間。如果不是,則列印限制值。

  • 如果字串中間包含其他字元,則提取初始整數。

示例

輸入

digits = "+234567.4234"

輸出

234567

解釋 – 它已從十進位制數中提取了整數部分。此外,符號為 ‘+’,因此它已打印出沒有符號的正數。

輸入

digits = "-23324";

輸出

-23324

解釋 – 它已打印出帶有符號的數字的小數部分。

輸入

digits = "   000122";

輸出

122

解釋 – 它已忽略了前導空格和零。

輸入

digits = "   000122";

輸出

0

解釋 – 字串在數字之前包含其他字母字元。因此,它列印 0。

方法 1

在這種方法中,我們將檢查前導空格、零、符號等。此外,我們將管理字串的小數部分。簡而言之,我們將找到一個遵循所有給定規則的整數值。

使用者可以逐步按照以下演算法進行操作。

演算法

步驟 1 – 使用最小和最大整數值初始化 mini 和 maxi 變數。

步驟 2 – 定義 ‘final_int’ 變數來儲存整數值,‘sign’ 變數來儲存整數的符號,以及 ‘digitPresent’ 變數來跟蹤包含數字的數字字串。 ‘digitPresent’ 變數用於檢查字串開頭是否包含其他字元、中間是否有空格等。

步驟 3 – 開始遍歷數字字串。

步驟 4 – 如果第 i 個索引處的字元是空格,並且 ‘digitPresent’ 為 true,則表示空格位於整數中間。因此,使用 break 關鍵字中斷迴圈。否則,如果空格位於開頭,則使用 ‘continue’ 關鍵字移動到下一個迭代。

步驟 5 – 如果第 i 個字元是 ‘-’ 或 ‘+’,請按照以下步驟操作。

步驟 5.1 – 如果 ‘sign’ 不為零,則中斷迴圈,因為 ‘-’ 或 ‘+’ 位於整數值中間。

步驟 5.2 – 如果字元是 ‘-’,則將 ‘sign’ 變數的值更新為 -1,並將 ‘digitsPresent’ 變數更新為 true,因為整數已開始。

步驟 5.3 – 如果字元是 ‘+’,則將 ‘sign’ 變數的值更新為 1,並將 ‘digitPresent’ 變數更新為 true。

步驟 6 – 如果當前字元是 ‘.’ 或其他字元,則中斷迴圈。

步驟 7 – 如果第 i 個字元是 0 到 9 之間的數字,請按照以下步驟操作。

步驟 7.1 – 將 ‘digitPresent’ 的值更新為 true。

步驟 7.2 – 如果 ‘sign’ 的值為 0,則將其更新為 1,因為字串不包含任何符號。因此,我們預設將其視為正數。否則,保持不變。

步驟 7.3 – 如果 (final_int < mini / 10 || final_int > maxi / 10 || final_int * 10 + (digits[i] - '0') < mini || final_int * 10 + (digits[i] - '0') > maxi) 為 true,則將 final_int 乘以 10,並新增數字值。否則,如果整數值超過限制,則根據 sign 值分配 mini 或 maxi。

步驟 8 – 返回 final_int*sign 值。

示例

#include <iostream>
#include <cmath>
using namespace std;

int getValidInt(string digits) {
    // Get the minimum and maximum integer value
    int mini = (-1) * pow(2, 31);
    int maxi = pow(2, 31) - 1;
    // Variable initialization
    long final_int = 0;
    int sign = 0, digitPresent = false;
    // Traverse the string
    for (int i = 0; i < digits.length(); i++) {
        // Ignoring only leading white spaces
        if (digits[i] == ' ') {
            if (digitPresent)
                break;
            else
                continue;
        }
        // handling the sign
        else if (digits[i] == '-' || digits[i] == '+') {
            // Case 1 - The sign is in the middle of the string
            if (sign != 0)
                break;
            // Case 2 - The sign is at the start of the string
            else if (digits[i] == '-' && sign == 0) {
                sign = -1;
                digitPresent = true;
            } else if (digits[i] == '+' && sign == 0) {
                sign = 1;
                digitPresent = true;
            }
        }
         // handling other characters.
        // Removing decimal part
        else if ((digits[i] == '.' || !(digits[i] - '0' >= 0 && digits[i] - '0' < 10))) {
            break;
        }
        // Handling digits
        else if (digits[i] - '0' >= 0 && digits[i] - '0' < 10) {
            digitPresent = true;
            sign = sign == 0 ? 1 : sign;
            if (!(final_int < mini / 10 || final_int > maxi / 10 || final_int * 10 + (digits[i] - '0') < mini || final_int * 10 + (digits[i] - '0') > maxi)) {
                final_int = final_int * 10 + (digits[i] - '0'); 
            } else {
                final_int = sign == -1 ? mini : maxi;
                break;
            }
        }
    }
    return final_int * sign;
}
int main() {
    string digits = "  +234567.4234";
    cout << "The valid integer from the given string is - " << getValidInt(digits);
    return 0;
}

輸出

The valid integer from the given string is - 234567

時間複雜度 – O(N) 以提取整數值。

空間複雜度 – O(1)

程式設計師需要按照上述程式碼中編寫的順序編寫 if-else 語句。如果他們以不同的順序編寫,則程式碼有時會給出錯誤的輸出。因此,我們可以瞭解到,在像這樣的某些問題中,保持 if-else 語句的順序也很重要。

更新於:2023年8月25日

瀏覽量:159

開啟您的職業生涯

完成課程獲得認證

開始學習
廣告