//

之前的网站结构看着实在不顺眼,并且有很多用不上的部分(刚开始规划失误),于是今天突发奇想重构本网站,将其结构进行改进,增强可读性

本想直接重做的,但是又懒得去熟悉新的框架或者主题,所以还是选了重构

如果重做显然是想换个主题的

好好好,
b 站收藏夹里的已失效视频可以在开发者窗口看到信息
(打开那个收藏夹之后搜索 list?media 打头的条目,点开找到响应栏目,刷新收藏夹,就可以看到包括失效视频在内的所有视频的名称、up 主名字之类的),
虽然没办法看到失效视频,但是可以找到发那个视频的 up 主,而且可以知道到底是什么视频失效了

ICSLab1要求写机器码,由于完全0基础,并且教程稀少(为数不多的教程还是全英文的)写得很抓马

后来改为先写汇编,再用工具转化为十六进制,最后手动翻译和眷写为二进制

重点来了,汇编和机器码原先都测试通过,但是,放到报告里的时候不知道是手痒还是vsc抽风(估计是我手痒),给其中某一行加了三个下划线,提交的时候还没检查,最后助教用脚本测试的时候我的代码连编译都没过,代码正确性的50分一分都没有

还好助教英俊潇洒通情达理(笑),填表解释之后给我加到了85分,救我一命

  • 这周一天一个实验,两个硬件、一个算法、一个汇编,除此之外还要写周常作业,周末还有考试
    • 硬件每个三题,都要自己仿真和上板验证
    • 算法实验与二叉树有关
      • 先序遍历创建、输出
      • 后序线索化二叉树
      • 编写后序线索化二叉树的遍历算法
      • 表达式树
        • 波兰式、逆波兰式、中缀式、求值
    • 汇编实验是乒乓序列,不过代码的正确性只占50%,得卷报告。。。。。。
      • 有点。。。。。。不好评价
      • 写了一个算法,因为报告要求有改进环节,于是通过设置梯度来优化了遍历算法
        • 大概快了20 倍
        • 测试的时候还发现一个特殊的情况,在那种情况下还可以再快2倍
      • 代码写了半下午,报告写了一晚上.jpg
  • 下周一周时间要写一篇电磁论文,选题都没定,不过初步想做一些电磁相关的可视化
    • 是的,妮可计算机还要学物理
  • 而且下周还要写电磁一整章的作业,周四之前还要写完硬件实验(其它周常就不说了)

上面只是目前已知的,下周可是还有可能再加任务的。。。。。。。

一天睡六个小时不到,绝了

PB2215xxxx-magichear


本次作业中,在文件头加入了以下内容:

1
2
3
4
5
6
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0

typedef int Status;

以尽量模仿课程环境,其他结构也尽可能参考了课程教学,请放心食用
正文中每个问题的结构为:$$问题\Rightarrow主文件\Rightarrow头文件$$

迷宫问题

本题我编写了一个名为 sqstack.h 的头文件,用于存放与栈有关的操作,以免主文件过于冗长。

经测试,在不影响到通路路径的情况下,将(3,3)、(6,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
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
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
#include<stdio.h>
#include "sqstack.h"

#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
#define m 8 // 迷宫的行
#define n 8 // 迷宫的列

typedef int Status;
typedef int MazeType; // 迷宫数组定义

PosType dire[4] = { {0,1},{1,0},{0,-1},{-1,0} }; //{行增量,列增量}
PosType start,end; // 起止位置

MazeType maze[m+2][n+2] = { // 迷宫数组内容
{1,1,1,1,1,1,1,1,1,1},
{1,0,0,1,0,0,0,1,0,1},
{1,0,0,1,0,0,0,1,0,1},
{1,0,0,1,0,1,1,0,0,1}, // (3,3)位置堵住,最终结果不变
{1,0,1,1,1,0,0,0,0,1},
{1,0,0,0,1,0,0,0,0,1},
{1,1,1,0,0,0,1,0,0,1}, // (6,1)位置堵住,最终结果不变
{1,0,1,1,1,0,1,1,0,1},
{1,1,0,0,0,1,0,0,0,1},
{1,1,1,1,1,1,1,1,1,1},
}; // 除上述两点外,与PPT中给出的是同一个迷宫

Status printPath(SqStack *p, int* PathCount); // 打印函数声明
Status MazePath(int maze[][n+2], int* PathCount, int x, int y, SqStack *p); // 求解函数声明
Status MarkPrint(SElemType e); // 标记经过路径

Status main() {
SqStack mazeStack;
InitStack(&mazeStack); // 创建、初始化栈

int PathCount = 0; // 路径计数
start.x = 1; // 设定起止条件
start.y = 1;
end.x = m;
end.y = n;

MazePath(maze, &PathCount,start.x,start.y,&mazeStack); // 求解迷宫

DestroyStack(&mazeStack); // 销毁栈
return OK;
}

Status printPath(SqStack *p, int* PathCount) {
*PathCount += 1;
printf("Path %d :\n", *PathCount);
SElemType e;
for (SElemType* i = p->base; i < p->top; i++) {
e = *i;
printf("(%d,%d)->", e.seat.x, e.seat.y);
}
printf("Exit Found!\n\n");
return OK;
}

// 标记迷宫块不可通过
Status MarkPrint(SElemType e)
{
maze[e.seat.x][e.seat.y] = -1;
return OK;
}

Status MazePath(int maze[][n+2], int* PathCount, int x, int y, SqStack *p) {

// 走到终点
if (x == end.x && y == end.y) {
maze[x][y] = -1;

// 将终点存入路径中
SElemType e;
e.seat.x = x;
e.seat.y = y;
Push(p, e);

//输出路径
printPath(p, PathCount);

// 输出完毕
Pop(p, &e); // 弹出end point
maze[x][y] = 0; // 标记end point为未访问

return TRUE;
}
else {
// 若当前位置为0(未被标记)
if (maze[x][y] == 0) {
int di = 0;

//4个方向都进行试探
while (di < 4) {

//储存当前位置
SElemType e;
e.seat.x = x;
e.seat.y = y;

//标记为-1,表示已经走过
MarkPrint(e);
Push(p, e);

//改变方向
int i, j;
i = x + dire[di].x;
j = y + dire[di].y;

MazePath(maze, PathCount, i, j, p);

// 抹除当前位置
Pop(p, &e);
maze[x][y] = 0;

di++;//改变方向
}
}
//不能走的话就返回,回到上一个位置
else
return OK;
}
return OK;
}

栈操作头文件

sqstack.h,动态分配内存

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
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
#pragma once
#include <stdio.h>
#include <stdlib.h>
#define STACK_INIT_SIZE 100//储存空间初始分配量
#define STACKINCREMENT 10//存储空间分配增量
#define OK 1
#define ERROR 0
typedef struct {
int x; //行值
int y; //列值
}PosType; //迷宫坐标位置类型
typedef struct
{
int ord; //序号
PosType seat; //位置
int di; //方向
} SElemType; //栈元素类型

typedef struct {
SElemType *base; //在构造之前和销毁之后,base的值为NULL
SElemType *top; //栈顶指针
int stacksize; //当前已分配的存储空间,以元素为单位

}SqStack; //顺序栈

//栈的初始化
int InitStack(SqStack *p) {


p->base = (SElemType*)malloc(STACK_INIT_SIZE * sizeof(SElemType));
if (p->base == NULL)
return ERROR; //内存分配失败
p->top = p->base; //栈顶与栈底相同表示一个空栈
p->stacksize = STACK_INIT_SIZE;
return OK;

}
//判断栈是否为空
int EmptyStack(SqStack *p) {
//若为空栈 则返回OK,否则返回ERROR
if (p->top == p->base)
return OK;
else return ERROR;
}
//顺序栈的压入
int Push(SqStack *p, SElemType e) {
//插入元素e为新的栈顶元素
if ((p->top - p->base) >= p->stacksize) //栈满,追加储存空间
{
p->base = (SElemType*)realloc(p->base, (p->stacksize + STACKINCREMENT) * sizeof(SElemType));
if (p->base == NULL)
return ERROR;// 储存空间分配失败
p->top = p->base + p->stacksize;
p->stacksize += STACKINCREMENT;
}
*(p->top) = e;
(p->top)++;
return OK;
}


// 顺序栈的弹出
int Pop(SqStack *p, SElemType *e) {
//若栈不空,则删除p的栈顶元素,用e返回其值
if (p->top == p->base)
return ERROR;
--(p->top);
*e = *(p->top);
return OK;


}
//将顺序栈置空 栈还是存在的,栈中的元素也存在,
//如果有栈中元素的地址任然能调用
int ClearStack(SqStack *p) {
p->top = p->base;
return OK;
}
//顺序栈的销毁
int DestroyStack(SqStack *p) {
//释放栈底空间并置空
free(p->base);
p->base = NULL;
p->top = NULL;
p->stacksize = 0;

return OK;
}

打印杨辉三角

本题同样编写了一个名为SeqQueue.h的头文件用于处理与队列有关的操作

主代码中,对 PPT 里的提示做了些改边,使用了do-while语句。//–//之间的内容为我额外添加,其余部分与 PPT 中的基本类似。
PPT 中内容:

1
2
3
4
5
6
7
EnQueue (q,0);	//各行间插入一个0
for ( j=1; j<=i+2; j++ ) {
DeQueue (q,t ); //一个系数出队
EnQueue (q, s+t ); //计算下一行系数,并进队
s = t;
if ( j != i+2 ) cout << s << ' '; //第i+2个0 }

我的改写(部分):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
k=1;
while(k<n){
// 0 作为转行符,入队列
EnQueue(&Q,0);
do{
//队头元素出队列
DeQueue(&Q,&s);
// -----------------------------------------------
//取新的队头元素
GetHead(&Q,&e);
//如果所取元素非 0,则输出,否则做转行操作
if(e){
printf("%4d ",e);
}else{
printf(" \n");
}
// -----------------------------------------------
EnQueue(&Q,s+e);
}while(e!=0);//一旦 e 值为 0,即做转行操作,退出循环,开始新一行的排列
k++;
}

主代码

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
#include <stdio.h>
#include <stdlib.h>
#include "SeqQueue.h"

//杨辉三角实现函数
void yanghui(int n){
SeqQueue Q;
int s,e,k;
//输出 1
printf("%4d\n",1);
//初始化队列
InitQueue(&Q);
// 将三角的第二行作为起始行,向下推导
EnQueue(&Q,0);
EnQueue(&Q,1);
EnQueue(&Q,1);
k=1;
while(k<n){
// 0 作为转行符,入队列
EnQueue(&Q,0);
do{
//队头元素出队列
DeQueue(&Q,&s);
// -----------------------------------------------
//取新的队头元素
GetHead(&Q,&e);
//如果所取元素非 0,则输出,否则做转行操作
if(e){
printf("%4d ",e);
}else{
printf(" \n");
}
// -----------------------------------------------
EnQueue(&Q,s+e);
}while(e!=0);//一旦 e 值为 0,即做转行操作,退出循环,开始新一行的排列
k++;
}
//出循环后,队列中还存有下一行的数据
DeQueue(&Q,&e);
while(!IsEmpty(&Q)){
DeQueue(&Q,&e);
printf("%4d ",e);
}
DestroyQueue(&Q);
}
int main(){
yanghui(15);
return 0;
}

队列操作头文件

SeqQueue.h,同样动态分配内存,不过本题没有设置初始分配量

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
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
#pragma once
#include <stdio.h>
#include <stdlib.h>

#define OK 1
#define ERROR 0
#define OVERFLOW -1
typedef int Status;
typedef int QElemType;

typedef struct QNode
{
QElemType data;
struct QNode *next;
}QNode, *QueuePtr;

typedef struct
{
QueuePtr front;//队头
QueuePtr rear;//队尾
}SeqQueue;

void InitQueue(SeqQueue *Q)//初始化
{
Q->front = Q->rear = (QueuePtr)malloc(sizeof(QNode));
if (!Q->front) exit(OVERFLOW);
Q->front->next = NULL;
}

Status EnQueue(SeqQueue *Q, QElemType e)//入队
{
QueuePtr p = (QueuePtr)malloc(sizeof(QNode));
if (!p) exit(OVERFLOW);
p->data = e;
p->next = NULL;
Q->rear->next = p;
Q->rear = p;
return OK;
}

Status DeQueue(SeqQueue *Q, QElemType *e)//出队
{
if (Q->front == Q->rear)
return ERROR;
QueuePtr p = Q->front->next;
*e = p->data;
Q->front->next = p->next;
if (Q->rear == p) Q->rear = Q->front;
free(p);
return OK;
}

Status GetHead(SeqQueue *Q, QElemType *e)//取队头元素
{
if (Q->front == Q->rear)
return ERROR;
*e = Q->front->next->data;
return OK;
}

Status IsEmpty(SeqQueue *Q)
{
if (Q->rear == Q->front)
return OK;
else
return ERROR;
}

Status DestroyQueue(SeqQueue *Q)//销毁队列
{
while (Q->front)
{
Q->rear = Q->front->next;
free(Q->front);
Q->front = Q->rear;
}
return OK;
}

“人不要抱有侥幸心理”

周三下午在西图睡到了 14:05,然后莫名地不想去上课(于是也就没去)。
翘掉的课在 3C 上,要去的话最多晚一点,但还是来得及的,就是不想去,心里想着:这个老师(男神 xmj)可是广为人知的从来不点名选手,翘就翘了,况且这学期第一次翘课,这倒霉的概率也太小了。遂留在西图写电磁。
结果晚上十点多的时候助教在群里问上课前有谁请假了,顿感不对劲,马上打开 bb 刷了回放,发现准备下课的时候布置了个课堂作业(还收上去了),这下直接一次两寄。

  1. 生成 SSH 密钥:首先,你需要在本地机器上生成一个 SSH 密钥对。你可以在终端中使用 ssh-keygen 命令来生成密钥对 ⁵。例如,你可以使用以下命令来生成一个新的 ed25519 密钥对:

    1
    ssh-keygen -t ed25519 -C "<label>"

    其中,<label> 是一个可选的标签,用于帮助你识别这个密钥 ⁵。

输入密码时,密码不会被显示出来,但仍然可以正常输入

  1. 添加密钥到 SSH-agent:生成密钥对后,你可以将其添加到 ssh-agent 中。ssh-agent 是 SSH 的一个关键管理器。将密钥添加到 ssh-agent 可以避免你反复输入密码 ⁵。

  2. 将公钥添加到 GitHub 账户:然后,你需要将你的 SSH 公钥添加到 GitHub 账户中 ⁵。首先,复制你的 SSH 公钥。然后,在 GitHub 中打开设置页面,点击 “SSH and GPG keys”,然后点击 “New SSH key” 或 “Add SSH key”。在 “Key” 字段中粘贴你的公钥,然后点击 “Add SSH key”⁷。

  3. 更改仓库 URL:最后,你需要将你的仓库 URL 更改为 SSH URL⁷。你可以使用以下命令来更改仓库 URL:

    1
    git remote set-url origin <ssh url>

    其中,<ssh url> 是你的仓库的 SSH URL⁷。

你可以使用 git remote -v 命令来查看你的仓库的远程 URL¹。这个命令会显示你的远程仓库的 fetch 和 push URL¹。如果这些 URL 是 SSH URL,那么你就已经成功地将你的连接方式切换到了 SSH¹。

你也可以尝试使用 SSH 连接到 GitHub,然后查看是否能成功连接 ²。你可以使用以下命令来测试你的 SSH 连接:

1
ssh -T git@github.com

当你第一次尝试通过 SSH 连接到 GitHub 时,你的计算机会询问你是否信任 GitHub 的服务器。这是一个常见的安全措施,用于防止中间人攻击。在这种情况下,你应该输入 “yes”,然后按回车键。这将把 GitHub 的服务器添加到你的计算机的已知主机列表中,以后你再连接到 GitHub 时就不会再看到这个提示了。

如果你看到类似于 “Hi ! You’ve successfully authenticated, but GitHub does not provide shell access.” 的消息,那么你就已经成功地通过 SSH 连接到了 GitHub²。

  1. 启动 ssh-agent:
    这个错误可能是因为 ssh-agent 服务没有启动 ¹。你可以尝试以管理员权限运行 PowerShell,然后手动启动服务 ¹。你可以通过以下命令来检查 ssh-agent 服务的状态 ¹:
1
Get-Service ssh-agent

如果服务的状态显示为 “Stopped”,那么你需要将其启动类型设置为 “Manual” 或 “Automatic”,然后再次尝试启动服务 ¹。你可以使用以下命令来设置启动类型 ¹:

1
Set-Service -Name ssh-agent -StartupType Manual

或者

1
Set-Service -Name ssh-agent -StartupType Automatic

然后,你可以再次尝试启动服务 ¹:

1
Start-Service ssh-agent

在 Windows 服务中,”Manual” 和 “Automatic” 是服务的两种启动类型 ¹²³:

  • Automatic:这意味着服务会在计算机启动时自动启动 ¹²。这是因为有些服务是系统运行所必需的,或者它们需要在系统启动时就开始运行 ²。

  • Manual:这意味着服务不会在计算机启动时自动启动 ¹²。相反,它们只有在被其他服务或程序调用时才会启动 ¹²。这种类型的服务通常是那些不常用,或者只在特定条件下才需要的服务 ²。

总的来说,”Automatic” 和 “Manual” 的主要区别在于服务是否会在计算机启动时自动启动 ¹²

  1. 关闭 ssh-agent:
    在你完成 SSH 操作后,你可以选择是否关闭 ssh-agent³⁴。如果你不再需要 SSH 连接,那么关闭 ssh-agent 是一个好主意,因为这样可以避免留下活动的密钥 ³。然而,如果你仍然需要 SSH 连接,那么你可能希望保持 ssh-agent 处于运行状态 ⁴。

如果你决定关闭 ssh-agent,你可以使用以下命令来停止它 ²:

1
Stop-Service ssh-agent

个人用户还是建议设置为自动

参考:

  1. https://www.linuxfordevices.com/tutorials/linux/connect-to-github-with-ssh

注册/登录链接

https://www.npmjs.com/login?next=/login/cli/82f73849-2702-4fde-aa75-958faed0e8cf

npm init 的初始化过程的常见的字段:

  • package name: 这是你的包的名称。它应该是独一无二的,因为它将被用于在 npm 上发布你的包。例如,你可以输入my-image-package
  • version: 这是你的包的版本号。默认情况下,它应该是1.0.0
  • description: 这是对你的包的简短描述。
  • entry point: 这是当其他人安装并使用你的包时,Node.js 将首先运行的文件。对于只包含图片的包,这通常不重要。
  • test command, git repository, keywords, author, license: 这些字段都是可选的,你可以根据需要填写。

在每个提示后面,按回车键将会选择括号中的默认值(如果有)。如果你不确定某个字段应该填什么,你可以先选择默认值,稍后再在package.json文件中进行修改。

完成所有步骤后,一个新的package.json文件将会在你的项目目录中创建。然后,你可以按照我之前提供的步骤将你的图片添加到项目中,并更新package.json文件。

更新 npm 包的步骤如下:

  1. 修改你的代码或资源:首先,你需要对你的包进行所需的修改。这可能包括添加新的图片,修改现有的图片,或者更改其他文件。

  2. 更新版本号:每次发布 npm 包时,都需要更新package.json文件中的版本号。你可以手动更改它,也可以使用npm version命令来自动更新。这个命令有三个参数:patch(修订),minor(次版本)和major(主版本),分别对应语义化版本控制的三个级别。例如,如果你想更新修订号(也就是最后一个数字),你可以在命令行中运行npm version patch

  3. 发布你的包:使用npm publish命令将你的包发布到 npm。如果一切顺利,你的新版本应该很快就会出现在 npm 上。

  4. 通过 unpkg 访问新版本:在 unpkg 的 URL 中,将版本号更改为你刚刚发布的新版本号。例如,如果你的新版本号是1.0.1,那么 URL 应该是 https://unpkg.com/my-package@1.0.1/assets/img/logo.jpg

获取图片永久链接

以下是将图片作为 npm 包发布到 npm 上,然后通过 unpkg 获取永久链接的详细步骤:

  1. 创建一个 npm 项目

    • 首先,你需要在你的计算机上安装 Node.js 和 npm。你可以从Node.js 官方网站下载并安装它们。
    • 然后,在命令行中导航到你想要创建项目的目录,然后运行npm init命令。这将会引导你创建一个新的 npm 项目。
  2. 将图片添加到项目中

    • 将你想要作为永久链接的图片文件复制到你的 npm 项目的目录中。你可以根据需要创建子目录来组织你的文件。
  3. 更新 package.json 文件

    • 打开package.json文件,然后找到files字段。如果该字段不存在,那么你需要添加它。
    • files数组中,添加一个字符串,该字符串是你的图片文件(或包含图片文件的目录)相对于package.json文件的路径。例如,如果你的图片文件名为logo.jpg并且位于项目根目录下的img目录中,那么你应该添加"img/logo.jpg"files数组中。
      “files”: [“logo”,”picture”]
  4. 发布 npm 包

    • 在命令行中,导航到你的 npm 项目的目录,然后运行npm login命令。按照提示输入你的 npm 账户信息。
    • 登录成功后,运行npm publish命令来发布你的包。
  5. 通过 unpkg 访问图片

    • 一旦你的包被成功发布到 npm 上,你就可以通过 unpkg 来访问你的图片了。例如,如果你的包名为my-package,版本号为1.0.0,并且你的图片文件位于img/logo.jpg,那么你可以通过以下 URL 来访问你的图片: https://unpkg.com/my-package@1.0.0/img/logo.jpg

删除已发布的 npm 包

可以删除以前发布的 npm 包。但是请注意,一旦删除了一个包,其他依赖于这个包的项目可能会受到影响。因此,在删除一个包之前,最好先通知使用这个包的开发者。

以下是如何删除 npm 包的步骤:

  1. 首先,你需要在命令行中运行npm login命令,并按照提示输入你的 npm 账户信息。
  2. 登录成功后,运行npm unpublish your-package-name命令来删除你的包。请将your-package-name替换为你想要删除的包的名称。

请注意,根据 npm 的政策,如果你的包已经存在 24 小时以上,那么你可能需要联系 npm 支持团队来删除你的包 ¹。
(1) npm Uninstall——如何删除包 freeCodeCamp.org
(2) npm 卸载方法 - 知乎 - 知乎专栏
(3) npm 包的安装与卸载-CSDN 博客
(4) 卸载包和依赖 | npm 中文网 - Node.js
(5) undefined
(6) undefined

这次的网站比较简约,框架也很好搭,两天就弄得差不多了,后面就是逐渐完善内容啦

想部署到子项目中,但是主题一直应用不了,有点小烦

0%