4399挂经总结

非常总要的部分 【ip知识点】

计算IP 的5连问

IP 计算总结

image-20210928233000817

image-20210928233551493

ip 可以用一个 32位的整数来存储

计算公式:

  1. 多少个0 ,就是 2的多少次方, 比如1个0 就是 $2^1$, 8个0 就是 $2^8$

  2. 比如给定一个 形如 ip/24 的东西, 就是表示他有 24个1 , $ 32-24 = 8 $ 个 0 , 也就是 $2^8 = 256 $ 也就是 减去 全0 和 255 的那个数,一共与 1 到 254 这几个 数字可以用,也就是 有 254个主机的IP 可以分配

  3. 题目演练2:

    1. 给定 ip/23 的子网掩码, 那么 我们知道 他有 32 个 1 减去 23 个 1 , 知道他 有 9个 0 ,也就是 $2^9 = 512$ , 减去 0 和 511 这2个 标志位置, 可取的 主机标号范围是 $[1,510]$ , 一共可以有 510个主机 的 number 可以被分配

image-20210929003805476

image-20210929003937038

划分子网原理

image-20210929004134893

学习视频

划分子网相当于自己 DIY , 就是 比如 TCP 协议上面 我再 自定义 自己的协议,【自定义应用层协议,大概这样理解】

image-20210929004328320

比如划分前 , 有 8位的主机号, 我自己进行 diy ,主机号 前面搞个子网号码, 那么, 假设 分配 n 为作为子网号, 就有 $2^{8-n} -2$ 个主机号 跑去 0 和 全1 那个数

image-20210929004811004

由于 $2^{6} - 2 = 62$ , 也就是可以分配的区间是 [1,62] ,

但是 我们算的只是主机位的, 还有 还有网络位组成

我们 8 位的 数, 也就是值域是 [0,255], 每个子网 有64 个主机号,

256 个坑位 处于 64 个

$256/64 = 4$

表示 我们有 可以划分为 4个子网

子网号的组合可以是:

${ 00,01,10,11 }$

十进制转二进制

这种直接看我下面的代码, $s[n] = s[n/2] + s[n%2]$

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include<iostream>
#include<cstring>
using namespace std;
string f(int u) {
    if(u == 1) {
        return "1";
    }
    if( u == 0) {
        return "0";
    }

    return f(u/2) + f(u%2);

}

int main() {
    //int ip = 32;

    cout << f(22) <<endl;

    cout << f(23) <<endl;
    cout << f(255) <<endl;
    return 0;
}

比如 23 ,

  1. $f(23) = f(23/2) + f(23%2) $
    1. $f(23) = f(11) + f(1)$ => 1
  2. f(11) = f(5) + f(1) => 1
  3. f(5) = f(2) + f(1) => 1
  4. f(2) = f(1) + f(0) => 0
  5. f(1 ) = 1

所以 答案就是 $ 0 1 1 1 $

IP 和 int 互转,用代码实现

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
#include<bits/stdc++.h>
using namespace std;

int iptoi(string &ip) {
    int res = 0;
    int n = ip.size();
    int s = -1;
    for(int i=n-1;i>=0;--i) {
        if(ip[i] =='.') continue;
        s++;
        if(ip[i] =='1') {
            res += (1<<s);
        }
    }
    return res;

}

string itop(int ip) {
    // top
    string ips[4];

    int offset = 0;
    // 从右 完左,从低到高
    for(int i=3;i>=0;--i,offset+=8) {
        string &cur = ips[i];
        for(int j=0+offset;j<8+offset;++j) {
            if ( (ip & (1<<j)) ) {
                cur.push_back('1');
            }else cur.push_back('0');
            //cur.push_back( ( ip & (1<<j)) +'0' );
            // 0 + '0'
        }
        reverse(cur.begin(),cur.end());

    }
    string res;
    for(int i=0;i<4;++i) {
        res += ips[i];
        res += '.';
    }
    res.pop_back();
    return res;



}
int main(void) {
  //  cout <<"hello" <<endl;
    cout << itop(23) <<endl;
    cout << itop(8) <<endl;
    cout << itop(1) <<endl;
    string res = itop(32) ;

    cout << iptoi(res) <<endl;
    return 0;

}

dp算法知识点

一个细胞1小时分裂 1次, 每个细胞最多分裂为 3个细胞,就不能再分裂了, N 小时后 细胞的数量

前一天x2减去不能分裂的

$ dp[n] = 2*dp[n-1] - dp[n-3] $

dp[1] = 1;

dp[2] = 2;

dp[3] = 4

dp[4] = 4*2 - 1 # 这里 1号细胞已经不能分裂了。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include<iostream>
#include<cstring>
using namespace std;
const int MAXN = 50;
int dp[MAXN];
int  f(int u) {
    dp[1] = 1;
    dp[2] = 2;
    dp[3] = 4;
    for(int i=4;i<=u;++i) dp[i] = 2*dp[i-1]  - dp[i-3];

    return dp[u];

}

int main() {
    //int ip = 32;

    cout << f(22) <<endl;

    cout << f(23) <<endl;
    cout << f(25 ) <<endl;
    return 0;
}

linux 问题

linux 计算文件有多少行

1
2
3
4
wc -l  www.log
# -c 表示字符数
# -w 表示统计的字数
# -l 表示字节数

对排序最多的IP 进行打印

https://blog.csdn.net/Alen_xiaoxin/article/details/88702565

1
cat access_log |cut -d ' ' -f 1 | sort |uniq -c | sort -nr | awk '{print $0 }' | head -n 10 | less