Day6 不要二、把字符串转换成整数

✨个人主页: 北 海
所属专栏: C/C++相关题解
操作环境: Visual Studio 2019 版本 16.11.17

成就一亿技术人


文章目录

  • 选择题
    • 1. 计算机组成原理
  • 编程题
    • 1. 不要二
    • 2. 把字符串转换成为整数


选择题

1. 计算机组成原理

题目:执行下面语句后的输出为()

int I=1;
if(I<=0) 
 printf("****\n");
else 
 printf("%%%%\n");

选项:

  • A. %%
  • B. ****
  • C. 有语法错,不能正确执行
  • D. %%%%

题目分析:比较考验 C 语言基础的题目,% 配合其他字符,可将其进行转义,比如 %d 表示匹配整型进行输出,如果想单纯表示 % 时,需要使用两个 % 表示一个 %,即在打印时 %% -> %

结果:A

Day6 不要二、把字符串转换成整数_第1张图片


编程题

1. 不要二

题目链接:不要二

Day6 不要二、把字符串转换成整数_第2张图片

题目分析:这也是一道纯数学题,求在 W * H 的二维矩阵中,至多可以放下多少块距离不等于 2 的蛋糕,因为是二维矩阵,所以每个格子都有相应的坐标,而两块蛋糕之间的距离的平方可以通过公式 (x1 - x2) * (x1 - x2) + (y1 -y2) * (y1 - y2) 得出

Day6 不要二、把字符串转换成整数_第3张图片

此时就比较简单了,直接创建一个 W * H 的二维数组,然后判断能否填入蛋糕(上下左右都不能有蛋糕),最后再返回成功填入的蛋糕数即可

#include 
#include 
using namespace std;

bool getCake(vector<vector<int>>& vv, int x, int y)
{
    //判断
    if ((x - 2) >= 0 && vv[x - 2][y])
        return false;
    else if ((x + 2) < vv.size() && vv[x + 2][y])
        return false;
    else if ((y - 2) >= 0 && vv[x][y - 2])
        return false;
    else if ((y + 2) < vv[0].size() && vv[x][y + 2])
        return false;

    return true;
}

int main()
{
    //格中距离,不能为2
    int x = 0, y = 0;
    cin >> x >> y;

    //状态:0表示有蛋糕,1表示没蛋糕
    vector<vector<int>> vv;
    vv.resize(x, vector<int>());
    for (int i = 0; i < x; i++)
        vv[i].resize(y, 0);    //初始化状态

    int cnt = 0;    //计数
    for (int i = 0; i < x; i++)
    {
        for (int j = 0; j < y; j++)
        {
            //填入蛋糕:距离为2的格子处没蛋糕或者越界,可正确填入
            if (getCake(vv, i, j))
            {
                vv[i][j] = 1;
                cnt++;
            }
        }
    }

    cout << cnt << endl;

    return 0;
}

Day6 不要二、把字符串转换成整数_第4张图片

2. 把字符串转换成为整数

题目链接:把字符串转换成为整数

Day6 不要二、把字符串转换成整数_第5张图片

题目分析:这是一道来自剑指Offer的中等题,其实就是模拟库中的字符串转整数函数(atoi),题目要求比较多:给定字符串中包含很多干扰信息,比如空格、非数字字符等,所以在进行转换时需要特别注意

非法的情况:

  • 出现多个 +-
  • 在数字字符串为空时,出现了非数字字符,比如 a
  • 出现符号 +- 的情况下,仍然出现非数字字符
  • 出现前导0之后,仍然出现 +-

其他情况,诸如 出现 空格 或 其他非数字字符 时,可以将合法的字符串进行转换出现多个符号且已存在合法字符串时,也可以进行转换

class Solution
{
public:
    int StrToInt(string s)
    {
        string numStr;

        //1、去除空格、避免非法情况、提纯
        //非法情况:
        //  同时出现 +、- (二者只能出现其一)
        //  出现符号与数字之前存在空格(非连续)
        //  未出现数字之前先出现非数字字符(不包括 +、-)
        //去除前导0:出现多个连续的前导0时,需要去除

        bool flag = false;  //正负号标志
        int symbolNum = -1;  //符号数

        for (auto e : s)
        {
            if (e != ' ')
            {
                if (e == '+' || e == '-')
                {
                    //判断是否冗余出现
                    if (e == '-') flag = true;
                    symbolNum++;

                    if (symbolNum)
                    {
                        //如果前面有合法字符串,则返回进行转换
                        if (numStr.size())
                            break;

                        return 0; //否则就是非法情况 -> 出现多个 +、-
                    }
                    
                    if (numStr.size())
                    {
                        //此时因为符号出现在数字之后,需要去除符号的负面影响
                        //其实就是相当于数字字符串之后出现了非数字字符
                        flag = false;
                        break;
                    }
                }
                else if (!isdigit(e))
                {
                    //非数字字符的情况
                    if (numStr.size() == 0 || symbolNum == 0)
                    {
                        if (numStr.size())
                            break;
                        return 0;   //出现符号 +、- 的情况下,还出现非数字字符
                    }
                    else
                        break;  //截取有效部分进行转换
                }
                else
                {
                    //此时单纯为数字,并且为连续的数字,可以加入 numStr 中
                    //注意:前导0不参与计算
                    if (e == '0' && numStr.size() == 0)
                        symbolNum++;    //把前导0看作符号位,再出现符号就非法了
                    else
                        numStr += e;
                }
            }
            else
            {
                //需要注意非连续的情况
                //出现符号或numStr已有数据时,在出现空格则不再继续统计
                if (numStr.size() || symbolNum == 0)
                    break;  //数字字符串之后出现了非数字字符
            }
        }

        //2、进行转换
        //首先排除长度越界情况(大范围越界)
        if (numStr.size() > 10)
            return flag ? INT_MIN : INT_MAX;

        //进行转换
        int num = 0;
        int base = 0;   //用于控制当前数的大小
        auto rit = numStr.rbegin();
        while (rit != numStr.rend())
        {
            num += ((*rit - '0') * (int)pow(10, base++));
            ++rit;
        }

        flag ? num *= -1 : num;
        
        //3、判断越界
        //其次排除边缘越界的情况
        //本来是负数,结果转成了正数
        if (flag && num > 0)
            return INT_MIN;
        //本来是正数,结果转成了负数
        if (!flag && num < 0)
            return INT_MAX;

        return num;
    }
};

注意: 需要特别注意边缘越界的情况,比如 INT_MAX + 1 是越界的

Day6 不要二、把字符串转换成整数_第6张图片
Day6 不要二、把字符串转换成整数_第7张图片


星辰大海

相关文章推荐

Day5 统计回文、连续最大和

Day4 计算糖果、进制转换

Day3 字符串中找出连续最长的数字串、数组中出现次数超过一半的数字

Day2 排序子序列、倒置字符串

Day1 组队竞赛、删除公共字符

你可能感兴趣的:(C/C++相关题解,算法,c++,开发语言)