从给定字符串中查找有效的整数


在这个问题中,我们需要按照题目说明中的规则从给定的字符串中提取整数。我们可以通过检查字符串的初始子字符串是否符合给定的有效整数值规则来解决问题。

题目描述 – 我们给定一个包含数字、‘.’、‘+’ 和 ‘-’ 字符的字符串 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

开启您的职业生涯

完成课程获得认证

开始学习
广告