Leo's blog

建议麦当劳

代码差错指北

如题, 这是随缘更新的指北.

不严谨的统计显示, 程序员的工作时间中, 10%用于构思和写代码, 30%用于debug, 60%用于纠结该给变量起什么名字.

那么问题来了, 抢答!! PHP天下第一!!, 如何DEBUG才是高效的DEBUG呢?

LOG调试法

打LOG无论是在学习中还是在工作中都是极其重要的DEBUG方式. 1 那么就有人问了, 啥是打LOG?

LOG能帮我们:

对程序运行情况的记录和监控;

了解程序的运行状态

总而言之, LOG就是程序运行时输出的帮助我们辨别程序运行状态的输出.

通过LOG看变量的值

这点很显然, 程序执行到一半输出变量的值就能知道变量的值是多少. 废话 需要注意的是, 不仅仅能打印变量的值, 还能打印表达式的值.

举个例子: 优秀的X同学在做某道题的时候写出了以下的代码

1
2
3
4
5
6
long a;
scanf("%d",&a); // 注意这里有一个错误: 应该是%ld

if(a==-1){
执行某些代码
}

他输入了-1之后,发现本应执行的if语句内代码并没有被执行. 于是他就在第三行插入了 printf("%d",a==-1);, 发现输出的值是0, 意味着a并不等于-1. 意识到 a!=-1 之后, 优秀的X同学就意识到了scanf处出现了错误.

通过LOG判断程序执行的位置

看到上面的例子后, 各位可能有个疑惑: “X同学是怎么知道程序没有执行if语句内的内容呢?”

(做手势: 看看本节标题) 你是不是心中浮现了一个玄妙的想法: 只要在if语句内输出点东西就好了啊! 是不是特别神奇! (夸张脸)

说时迟, 那时快, 只见X同学飞快的敲下了以下代码

1
2
3
4
5
6
7
long a;
scanf("%d",&a); // 注意这里有一个错误: 应该是%ld

if(a==-1){
printf("这个东西应该输出的啊???");// 当然并没有输出
执行某些代码
}

当他按下了神圣的F11键之后, “当场他就懵了”, 陷入了沉思.

通过LOG查看递归调用的函数

这点可能课内还没有学到, 可以等讲完课后回来复习 (观众留存度++)

对于一个递归函数, 比如汉诺塔:

1
2
3
4
5
6
7
8
9
10
11
void hanoi(int n, char from, char via, char to) {
printf("将要从%c通过借助%c移动%d个盘子到%c\n",from,via,n,to);
if (n == 1)
move(from, to);
else {
hanoi(n - 1, from, to, via);
move(from, to);
hanoi(n - 1, via, from, to);
}
printf("已经从%c通过借助%c移动%d个盘子到%c\n",from,via,n,to);
}

室友调试法

把室友扥(den)过来, 完整的讲述你程序的思路给他听, (不用管室友是否真的在听), 一般讲到一半你就会意识到你哪儿错了

小黄鸭调试法

没有室友? 找一只小黄鸭放在桌子上给它讲述你的程序思路.

大概每日一题

首先, 给各位道个歉. 昨天由于沉迷学习忘了更新, 绝对不是忙于抢新题库的一血

那么,

作天的题

题目描述

1
2
3
4
5
本关任务:计算正整数num的各位上的数字之积。
例如:
输入:2583 经过(2x5x8x3) 输出:240
输入:102 经过(1x0x2) 输出:0
输入:136 经过(1x3x6) 输出:18

输入

1
一个数num

输出

1
运算结果(一个整数)

做题思路1

循环, 每次取一位, 和ans变量相乘.

伪代码:

1
2
3
4
5
6
7
ans = 1
输入num
k = 1
while(num / k != 0):
ans *= (num/k)%10 // num去掉后面的位数后取最后一位
k *= 10
输出ans

这种思路的核心在于, 设置中间变量k. 每次把num除k来去掉尾部多余的位数之后取最后一位累乘.

做题思路2

循环, 每次取num的最后一位, 和ans变量相乘后去掉最后一位

伪代码:

1
2
3
4
5
ans = 1
读入num
while num != 0:
ans *= (num%10) // ans乘以num的最后一位
num /= 10 // 核心: 去掉num的最后一位

这个思路的核心在于, 每次取最后一位num用于计算后去掉最后一位.
相比第一个思路的好处是 省略了一个中间变量.

1024特别节目

今天是1024程序员节

不知道能为各位做点什么,
给各位画幅画吧

1
2
3
4
 
O
~~~~~
~~~~~

一副海上明月图送给大家

每日一题

公众号新开了个栏目, 叫大概每日一题.

那么问题来了, 为啥叫大概每日一题呢?

鸽子表情包

今天的题

题目描述:

1
找出具有m行n列二维数组Array的“鞍点”,即该位置上的元素在该行上最大,在该列上最小,其中1<=m,n<=10。

输入:

1
第一行有两个数m和n,下面有m行,每行有n个数。

输出:

1
Array[i][j]=x

做题思路

这道题的思路还是比较清晰的: 枚举每一行, 寻找这一行里最大的数在第几列, 寻找那一列最小的数, 看看这一行最大的数是不是这一列最小的数.

伪代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
输入m,n
循环i从0到m-1
循环j从0到n-1
读入data[i][j]

循环i从0到m-1
max=data[i][0]
pos=0
循环j从0到n-1
如果data[i][j] 大于 max
更新max与pos

flag = 1
循环j从0到n-1
如果data[j][pos]小于max
flag = 0
如果flag=1 说明data[i][pos]是鞍点
输出,退出程序
输出none

注意点

在找数组的最小值的时候有两种实现方式:

1
2
3
4
5
6
7
8
int min = 0x70000000;
int pos = -1;
for(int i = 0; i < n;++ i){
if(min < data[i]){
min = data[i];
pos = i;
}
}

1
2
3
4
5
6
7
8
int min = data[0];
int pos = 0;
for(int i = 1; i < n;++ i){
if(min < data[i]){
min = data[i];
pos = i;
}
}

第一种方式将min设为极大值(或将max设为极小值), 第二种方式奖min设为数组第一项的值.

这两种方式都是正确的, 要注意的就是

  1. 使用第一种方式时设置的极大值一定要很大.
    1. int所能存储的最大值是0x7fffffff, 所以对于以上情况把min设置为0x7ffffff是安全的.
    2. 对于要比较min+data[i]和data[i]的大小的时候, min的初值应设置为int所能存储的最大值的一半, 以保证min+data[i]仍在int范围内. 对于这种情况, 0x3f3f3f3f是一个安全的值.
  2. 使用第二种方式一定要把pos变量初始化为0

RAP: Retrieval-Augmented Planning with Contextual Memory for Multimodal LLM Agents

NUS, arxiv preprint

Motivation:

Reflecting past experiences in current decision-making processes, an innate human behavior, continues to pose significant challenges. Addressing this, we propose Retrieval-Augmented Planning (RAP) framework, designed to dynamically leverage past experiences corresponding to the current situation and context, thereby enhancing agents’ planning capabilities.

Strength

  • Retrieve related experience as new ICL examples
  • image-20240716200249688

Challenges

  • lack of comparison between fine-tunning the model on the memory database

SteP: Stacked LLM Policies for Web Actions

Cornell and ASAPP research; CoLM 2024

Author’s claim: Specifying a large prompt to handle all possible behaviors and states is extremely complex; decomposition to distinct policies requires careful handling of control between policies. They propose Step, an approach to dynamically compose policies to solve a diverse set of web tasks.

Use Markov Decision Tree where the state is a stack of policies.

Enable dynamic control where any policy can choose to invoke any other policy

image-20240716193601410

Strengths

  • some sort of “mid-level intent” prompt for completing high-level tasks

Challenges

  • I didn’t realize how policies are constructed when reading the introduction and the abstract.
    • Okay, I see why they are trying to avoid saying that. policies are manually crafted.
  • Then the need for manual crafting policies is a big issue.
0%