最近准备找实习,感觉群里很多人每天都会比较焦虑,我也会焦虑,不过学习算法的过程好像让人感觉会比较能静下心来,这个写一下之前一直遇到的问题。
废话不多说直接给各位看官老爷上干货,先给个c/c++和java的基本类型数据范围(时间有限,我大致白嫖了一下别人的成果),这些都是计算机组成原理中非常基础的知识了,好久没用又会忘了
1. c/c++中int等的数据范围
速查表:
char -128 ~ +127 (1 Byte)
short -32767 ~ + 32768 (2 Bytes) 3*10^4
unsigned short 0 ~ 65536 (2 Bytes) 6*10^4
int -2147483648 ~ +2147483647 (4 Bytes) 2*10^9
unsigned int 0 ~ 4294967295 (4 Bytes) 4*10^9
long == int
long long -9223372036854775808 ~ +9223372036854775807 (8 Bytes) 9*10^18
double 1.7 * 10^308 (8 Bytes)
符号属性 长度属性 基本型 所占位数 取值范围 输入符举例 输出符举例
-- -- char 8 -2^7 ~ 2^7-1 %c %c、%d、%u
signed -- char 8 -2^7 ~ 2^7-1 %c %c、%d、%u
unsigned -- char 8 0 ~ 2^8-1 %c %c、%d、%u
[signed] short [int] 16 -2^15 ~ 2^15-1 %hd
unsigned short [int] 16 0 ~ 2^16-1 %hu、%ho、%hx
[signed] -- int 32 -2^31 ~ 2^31-1 %d
unsigned -- [int] 32 0 ~ 2^32-1 %u、%o、%x
[signed] long [int] 32 -2^31 ~ 2^31-1 %ld
unsigned long [int] 32 0 ~ 2^32-1 %lu、%lo、%lx
[signed] long long [int] 64 -2^63 ~ 2^63-1 %I64d
unsigned long long [int] 64 0 ~ 2^64-1 %I64u、%I64o、%I64x
-- -- float 32 +/- 3.40282e+038 %f、%e、%g
-- -- double 64 +/- 1.79769e+308 %lf、%le、%lg %f、%e、%g
-- long double 96 +/- 1.79769e+308 %Lf、%Le、%Lg
注意:
浮点参数压栈的规则:float(4 字节)类型扩展成double(8 字节)入栈。
所以在输入时,需要区分float(%f)与double(%lf),而在输出时,用%f即可。
printf函数将按照double型的规则对压入堆栈的float(已扩展成double)和double型数据进行输出。
如果在输出时指定%lf格式符,gcc/mingw32编译器将给出一个警告。
然后看8种基本类型
整型
byte 1字节 8位元组,即8位bit, 可存储-2^8~2^7 (-128 ~ 127)
short 2字节 2*8 = 16 bit -2^16~2^15 (-32768 ~ 32767)
int 4字节 4*8 = 32 bit -2^32~2^31 (-2147483648 ~ 2147483647)
long 8字节 8*8 = 64 bit -2^64~2^63 (-18446744073709551616 ~ 18446744073709551615)
浮点型
float 4字节 4*8 = 32 bit -2^32~2^31 (-2147483648 ~ 2147483647)
double 8字节 8*8 = 64 bit -2^64~2^63 (-18446744073709551616 ~ 18446744073709551615)
字符型
char 2字节 2*8 = 16 bit 英文字符所占字节 2,中文字符根据编码不同
布尔型
boolean 1字节 8bit true|false
补充完基础知识后:
3. 上菜剑指 Offer II 098. 路径的数目
一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为 “Start” )。
机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为 “Finish” )。
问总共有多少条不同的路径?
示例 1:
输入:m = 3, n = 7 输出:28
示例 2:
输入:m = 3, n = 2 输出:3 解释: 从左上角开始,总共有 3 条路径可以到达右下角。 1. 向右 -> 向下 -> 向下 2. 向下 -> 向下 -> 向右 3. 向下 -> 向右 -> 向下
示例 3:
输入:m = 7, n = 3 输出:28
示例 4:
输入:m = 3, n = 3 输出:6
提示:
1 <= m, n <= 100题目数据保证答案小于等于 2 * 109
注意:本题与主站 62 题相同: 力扣
对于平时习惯用int数据的我好几次栽在了数据范围里面,所以今天特意来写个博客,希望自己能记住。
这题是最近在做dp专题的时候遇到的,这个题的dp思路也是很明显的,作为菜鸟的我居然也能直接想出来,下面这个思路,最简单最暴力的思路,其实这个双重循环dp应该还可以用滚动数组进行优化的。
代码一:遍历+二维数组class Solution {
public:
int uniquePaths(int m, int n) {
vector> dp(m + 1, vector(n + 1, 0));
dp[0][1] = 1;
for (int i = 1; i <= m; ++i){
for (int j = 1; j <= n; ++j){
dp[i][j] = dp[i - 1][j] + dp[i][j - 1];
}
}
return dp[m][n];
}
};
代码二:遍历+一维数组(滚动数组优化空间)
class Solution {
public:
int uniquePaths(int m, int n) {
vector dp(n + 1, 0);
dp[1] = 1;
for (int i = 1; i <= m; ++i){
for(int j = 1; j <= n; ++j){
dp[j] += dp[j - 1];
}
}
return dp[n];
}
};
不过做完后我就发现,这个题可以用高中(高二)的数学知识(统计)去做,于是我开始在数据范围上翻车了
oh,no 翻车一#翻车代码一
class Solution {
public:
int uniquePaths(int m, int n) {
int ans = 1;
for (int i = m + n - 2, j = 1; j < m; --i, ++j){
ans = ans * i / j;
}
return ans;
}
};
上面主要报错的原因是对于输入数组
23
12
这组输入的话计算过程中间有数据超过了c++中定义的 int 类型数值范围
oh, my god 翻车二#翻车代码二
class Solution {
public:
int uniquePaths(int m, int n) {
long long ans = 1;
for (int i = m + n - 2, j = 1; j < m; --i, ++j){
ans = ans * i / j;
}
return ans;
}
};
这部分还是因为没有对于m和n的值进行比较去优化计算过程中的数据范围顶峰所导致的数据溢出
AC代码#比较m和n的值,调整优化后顺利AC
class Solution {
public:
int uniquePaths(int m, int n) {
if (m > n){
return uniquePaths(n, m);
}
long long ans = 1;
for (int i = m + n - 2, j = 1; j < m; --i, ++j){
ans = ans * i / j;
}
return ans;
}
};
ok,终于改变数据类型,调整数据范围,在做优化之后
(这步优化主要是针对 和 中m - 1 和 n - 1 二者的大小问题,这两个在数值上是相等的,具体证明去看高中数学二项式定理证明,但是上面那个数字大的计算量会多于数值小的那个,所以在开始时多加一个判断,可以实现在计算量和数据范围两个部分进行优化效果。)
谢谢各位老爷们的学习
参考博客链接:
Java中int的取值范围_xk_一步一步来的博客-CSDN博客_javaint范围
c/c++中int等的数据范围_柯微-CSDN博客_c++ int范围



