记一次奇怪的做题经历,for循环是用size_t还是int?

引言

题目并不难,是leetcode的238题,因为vscode的默认补齐for循环的临时值类型为size_t,所以一般我也不会去改这个,但是在一次巧合中发现了size_t其实并没有int好用,且看下面分析。

题目描述

给你一个长度为 n 的整数数组 nums,其中 n > 1,返回输出数组 output ,其中 output[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积。

输入: [1,2,3,4]
输出: [24,12,8,6]

提示:题目数据保证数组之中任意元素的全部前缀元素和后缀(甚至是整个数组)的乘积都在 32 位整数范围内。

说明: 请不要使用除法,且在 O(n) 时间复杂度内完成此题。

进阶:
你可以在常数空间复杂度内完成这个题目吗?( 出于对空间复杂度分析的目的,输出数组不被视为额外空间。)

分析

题目很简单,不再陈述了,下面是我的代码:

class Solution {
public:
    vector<int> productExceptSelf(vector<int>& nums) {
        vector<int> res(nums.size());
        res[0] = 1;
        for(size_t i = 1; i < nums.size(); i++){
            cout << i << endl;
            res[i] = res[i-1] * nums[i-1];
        }
        int right = 1;
        for(size_t i = nums.size()-1; i >= 0 ; i--){
            res[i] *= right;
            right *= nums[i];
        }
        return res;
    }
};

这样一个代码竟然在执行题目的样例的时候出现了段错误,这是为什么呢?没有地方出现问题呀,那么只能打印一下了,

class Solution {
public:
    vector<int> productExceptSelf(vector<int>& nums) {
        vector<int> res(nums.size());
        res[0] = 1;
        for(int i = 1; i < nums.size(); i++){
            cout << i << endl;
            res[i] = res[i-1] * nums[i-1];
        }
        int right = 1;
        size_t t = nums.size() - 1;
        cout << t << endl;
        for(size_t i = nums.size()-1; i >= 0 ; i--){
            cout << i << endl;
            getchar();
            res[i] *= right;
            right *= nums[i];
        }
        return res;
    }
};

在这里插入图片描述
printf大法好!很清楚,当i为0的之后还会再减1,但是size_t会把-1变为最大的整数,这样的话就陷入死循环了,所以出现了问题。到这里这个令人诧异的问题就水落石出了。

结论

对于我们来说for循环中使用size_t的话会在反向循环的时候陷入死循环,而int就不会出现这样的问题,所以我们需要在进行反向循环的时候注意不要使用size_t,硬要用的话就要改变for的判断条件了。

posted @ 2022-07-02 13:17  李兆龙的博客  阅读(70)  评论(0编辑  收藏  举报