头像

巷港




离线:20小时前


最近来访(180)
用户头像
易思人
用户头像
R虎虎生威R
用户头像
ninecoffee
用户头像
蓝染染
用户头像
shenma
用户头像
天元之弈
用户头像
云梦passion
用户头像
Hard_IINE
用户头像
chaosliang
用户头像
李.嘉图
用户头像
Codiplay
用户头像
朱星星
用户头像
OLIVEIRA
用户头像
林笠可
用户头像
我叫白小白但长的不白
用户头像
种花家的市长
用户头像
雷金鱼
用户头像
咲张熊猫人
用户头像
wngzs
用户头像
初衷.c


巷港
2天前

Pyhton常用内置函数总结

内置函数不需要导入任何模块即可使用
执行下面的命令可以列出所有内置函数

dir(builtins)
dir()函数可以查看指定模块中包含的所有成员或者指定对象类型所支持的操作。

  • 内置函数int()
内置函数int()用来把实数转换为整数,或把数字字符串按指定进制转换为十进制数。

e.g

>>> int(3.5)
3
>>> int(-3.5)
-3
>>> int('101', 2)             # 二进制
5
>>> int('101', 16)            # 十六进制
257
>>> int('\t 8 \n')            # 自动忽略数字两侧的空白字符
8


  • 内置函数max()、min()、sum()
    max()、min()、sum()这三个内置函数分别用于计算列表、元组或其他可迭代对象中所有元素最大值、最小值以及所有元素之和,sum()要求元素支持加法运算,max()和min()则要求序列或可迭代对象中的元素之间可比较大小。

e.g

>>> import random
>>> a = [random.randint(1,100) for i in range(10)]   #列表推导式
>>> a
[72, 26, 80, 65, 34, 86, 19, 74, 52, 40]
>>> print(max(a), min(a), sum(a))
86 19 548

#如果需要计算该列表中的所有元素的平均值,可以直接这样用:

>>> sum(a)/len(a)
54.8


  • 内置函数range()

range()语法格式为range([start,] end [, step] ),返回具有惰性求值特点的range对象,其中包含左闭右开区间[start,end)内以step为步长的整数。参数start默认为0,step默认为1。
e.g

>>> range(5)                  #start默认为0,step默认为1
range(0, 5)
>>> list(range(5))
[0, 1, 2, 3, 4]
>>> list(range(1, 10, 2))     #指定起始值和步长
[1, 3, 5, 7, 9]
>>> list(range(9, 0, -2))     #步长为负数时,start应比end大
[9, 7, 5, 3, 1]


  • 内置函数enumerate()
enumerate()函数用来枚举可迭代对象中的元素,返回可迭代的enumerate对象,其中每个元素都是包含索引和值的元组

e.g

>>> list(enumerate('abcd'))                        #枚举字符串中的元素
[(0, 'a'), (1, 'b'), (2, 'c'), (3, 'd')]
>>> list(enumerate(['Python', 'Great']))          #枚举列表中的元素
[(0, 'Python'), (1, 'Great')]
>>> list(enumerate({'a':97, 'b':98, 'c':99}.items())) #枚举字典中的元素
[(0, ('a', 97)), (1, ('b', 98)), (2, ('c', 99))]
>>> for index, value in enumerate(range(10, 15)):  #枚举range对象中的元素,这个在字典dict的遍历时会用到
    print((index, value), end=' ')
(0, 10) (1, 11) (2, 12) (3, 13) (4, 14) 


  • 内置函数map(),好用常用,竞赛中常用输入的处理~

内置函数map()把一个函数func依次映射到序列或迭代器对象的每个元素上,并返回一个可迭代的map对象作为结果,map对象中每个元素是原序列中元素经过函数func处理后的结果。
e.g

>>> list(map(str, range(5)))  #把列表中元素转换为字符串
['0', '1', '2', '3', '4']
>>> def add5(v):              #单参数函数
    return v+5

>>> list(map(add5, range(10)))#把单参数函数映射到一个序列的所有元素
[5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
>>> def add(x, y):            #可以接收2个参数的函数
    return x+y

>>> list(map(add, range(5), range(5,10)))
                              #把双参数函数映射到两个序列上
[5, 7, 9, 11, 13]


  • 内置函数zip()

zip()函数用来把多个可迭代对象中的元素压缩到一起,返回一个可迭代的zip对象,其中每个元素都是包含原来的多个可迭代对象对应位置上元素的元组,如同拉拉链一样。
e.g

>>> list(zip('abcd', [1, 2, 3]))             #压缩字符串和列表
[('a', 1), ('b', 2), ('c', 3)]
>>> list(zip('123', 'abc', ',.!'))           #压缩3个序列
[('1', 'a', ','), ('2', 'b', '.'), ('3', 'c', '!')]
>>> x = zip('abcd', '1234')
>>> list(x)
[('a', '1'), ('b', '2'), ('c', '3'), ('d', '4')]


  • 内置函数filter

内置函数filter()将一个单参数函数作用到一个序列上,返回该序列中使得该函数返回值为True的那些元素组成的filter对象,如果指定函数为None,则返回序列中等价于True的元素。
e.g


>>> seq = ['foo', 'x41', '?!', '***']
>>> def func(x):
    return x.isalnum()                  #测试是否为字母或数字

>>> filter(func, seq)                   #返回filter对象
<filter object at 0x000000000305D898>
>>> list(filter(func, seq))             #把filter对象转换为列表
['foo', 'x41']
>>> list(filter(str.isalnum, seq))      #等价的用法
['foo', 'x41']


  • 内置函数print,与输出密切相关,常用!
print()函数是一个输出函数,可以用它来输出想要输出的内容。
语法格式为:
print (value,...,sep='',end='\n',file=sys.stdout,flush=False)

print函数各个参数的详细说明(sep和end是常用的!)

value:可以接收任意多个变量或值,因此print()函数可以输出多个值。 sep:print()函数输出多个变量时,print()函数默认以空格隔开多个变量,如果想要改变默认的分隔符,可通过sep参数进行设置。
end:用来设定以什么结尾,默认值是换行符 \n,可以换成其他字符串如:\t," " 等。
注意:在Python3中,print()函数总是默认换行的。因此若想输出不换行,一定设置一下end参数!(end = ' ')
file:表示设置输出设备,把print()函数中的值打印到什么地方,默认输出到标准端(sys.stdout)。
flush:该参数只有两个选项True或false。True表示强制清除缓存,false表示缓存的事情交给文件本身。

e.g


>>> print(3, 5, 7)
3 5 7
>>> print(3, 5, 7, sep=',')    #指定分隔符
3,5,7
>>> print(3, 5, 7, sep=':')
3:5:7
>>> for i in range(10,20):
    print(i, end=' ')          #不换行

10 11 12 13 14 15 16 17 18 19


  • 内置函数input()输入函数

input()函数用于向用户显示一条提示信息,然后获取用户输入的内容,输入内容的数据类型为字符串,如果想要得到其他类型的数据需要进行强制类型转换。

语法格式为:变量名=input("文字说明")

注意:在Python 3.x中,input()函数用来接收用户的键盘输入,不论用户输入数据时使用什么界定符,input()函数的返回结果都是字符串,需要将其转换为相应的类型再处理。

>>> x = input('Please input:')
Please input:3
>>> print(type(x))
<class 'str'>
>>> x = input('Please input:')
Please input:'1'
>>> print(type(x))
<class 'str'>
>>> x = input('Please input:')
Please input:[1,2,3]
>>> print(type(x))
<class 'str'>


  • 内置函数help(),这个可太有用了!

当调用一些函数或模块时,可能会忘记一些函数的参数或返回值等其他细节,可以使用Python内置的help()函数,help()函数用于查看函数或模块用途的详细说明。

语法格式为: help(对象名)

e.g使用help()函数查看print()函数的说明
图片1.png


  • 内置函数type()
type()函数能够查看一个对象的数据类型。
语法格式为:type(对象名)

e.g查询以下两个对象的数据类型:
图片2.png

通过查询,验证了数字123的数据类型是整型
"I Love Python!"的数据类型为字符串类型。
  • 内置函数id()
id()函数用于获取对象的内存地址
语法格式为: id(对象名)

e.g查看数字123和字符串”I Love Python!”在内存中的地址:
图片3.png




巷港
3天前

看论文看不下去了,正好有个师妹来问操作系统的实验。
大二没怎么认真做实验上机的我,竟然在大三的时候认真做了一遍!(难以置信)

实验内容

编写一个有关生产者和消费者的程序:每个生产者每次生产一个产品存入仓库,每个消费者每次从仓库中取出一个产品进行消费,仓库大小有限,每次只能有一个生产者或消费者访问仓库。要求:采用信号量机制。

实验原理

生产者消费者原理

11.png

生产者消费者模型如上图所示,一群生产者在生产消息,并将此消息提供给消费者去消费。它们中间设了具有M个缓存区的缓冲池,生产者每次可将生产的消息放入一个缓存区内,消费者每次可将一个缓存区内的消息拿出来消费。但这个过程有两个条件:任何一方操作一个缓冲区时不能有其它同时对该缓冲区进行操作;只有当缓冲区还有空余,生产者才能生产,只有当缓冲区至少有一个产品,消费者才能从中取出来消费。这里两个条件分别对应了互斥和同步。在此次实验中,有若干个生产者和若干个消费者。有多少个生产者,就有多少个生产者进程;有多少个消费者,就有多少个对应的消费者进程。生产者和消费者的个数作为命令行参数传入到程序中。即实现互斥又实现同步可以用信号量机制. 信号量(Semaphore),有时被称为信号灯,是在多线程环境下使用的一种设施,是可以用来保证两个或多个关键代码段不被并发调用。在进入一个关键代码段之前,线程必须获取一个信号量;一旦该关键代码段完成了,那么该线程必须释放信号量。其它想进入该关键代码段的线程必须等待直到第一个线程释放信号量。缓冲池作为临界资源,信号量的初始值为1,生产者与消费者进行生产或费时首先得获得临界资源。缓冲池空闲区域的个数,商品的个数也用信号量来定义,初始值分别为值为M和0。生产者要放产品到缓冲区时,除了要获得缓冲区这个临界资源,还要获得空闲的缓冲区区域;消费者要在缓冲区消费商品,除了要获得缓冲区这个临界资源,还要获得商品这个信号量。


Linux操作系统的代码实现

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <semaphore.h>
#include <time.h>
#define N 4   // 消费者或者生产者的数目
#define M 20 // 缓冲数目
int in = 0;   // 生产者放置产品的位置
int out = 0; // 消费者取产品的位置
char buff[M]; // 缓冲区
int producter_id = 0;   //生产者id
int consumer_id = 0; //消费者id
pthread_mutex_t mutex; // 互斥信号量, 一次只有一个线程访问缓冲区。
/* 打印缓冲情况 */
void print()
{
int i;
pthread_mutex_lock(&mutex);
for(i = 0; i < M; i++)
{
    printf("%c ", buff[i]);  
    //usleep(100);
}
puts("");
pthread_mutex_unlock(&mutex);
}
/* 生产者方法 */
void *producter()
{
int id = ++producter_id;
while(1)
{
   // 用sleep的数量可以调节生产和消费的速度
   sleep(2);
   char data;
   data=rand()%26+65;     
   in = in % M;
   printf("生产者进程%d在%2d位置产生数据%c: ", id,in,data);  
   buff[in] = data;  
   print();  
   ++in;
}
}
/* 消费者方法 */
void *consumer()
{
char data;
int id = ++consumer_id;
while(1)
{
   // 用sleep的数量可以调节生产和消费的速度
   sleep(1);
   out = out % M;
   data=buff[out];
   printf("消费者进程%d在%2d位置消费数据%c: ",id, out,data);   
   buff[out] = '*';
   print();
   ++out;
}
}
int main()
{
 pthread_mutex_init(&mutex,NULL);
pthread_t p[N];
pthread_t c[N];
int i;
int ret[N];
for(i=0; i<M; i++)
   buff[i]='*';  //'*'表示空,初始化缓冲区
srand((int)time(NULL));
// 创建N个生产者线程
for (i = 0; i < N; i++)
{
   ret[i] = pthread_create(&p[i], NULL,(void*)producter, (void *)(&i));
   if(ret[i] != 0)
   {
    printf("producter %d creation failed \n", i);
    exit(1);
   }
}
//创建N个消费者线程
for(i = 0; i < N; i++)
{
   ret[i] = pthread_create(&c[i], NULL, (void*)consumer, NULL);
   if(ret[i] != 0)
   {
    printf("consumer %d creation failed\n", i);
    exit(1);
   }
}
//销毁程
for(i = 0; i < N; i++)
{
   pthread_join(p[i],NULL);
   pthread_join(c[i],NULL);
}
pthread_mutex_destroy(&mutex);
exit(0);
}

gcc zfl.c -g -lpthread -o zfl.out
./zfl.out

22.png

注意事项

问题:出现“undefined reference to ‘pthread_create’”,所有关于线程的函数都会有此错误,导致无法编译通过。
问题的原因:pthread不是Linux下的默认的库,也就是在链接的时候,无法找到phread库中哥函数的入口地址,于是链接会失败。
解决:在gcc编译的时候,附加要加 -lpthread参数即可解决。
eg:gcc rwlock.c -g -lpthread

引用转自 Linux下undefined reference to ‘pthread_create’问题解决
引用中的内容转自 Linux下undefined reference to ‘pthread_create’问题解决




巷港
6天前

读论文的方法(递归式DFS读论文法)

论文八股结构

  1. 标题title
  2. 摘要abstract
  3. 导言introduction
  4. 算法方法method
  5. 实验experiment
  6. 结论conclusion

李沐分享的读论文方法(3遍论文法)

  1. 第一遍,读标题,摘要,结论。可以看一看使用的方法和实验部分的重要的图和表等。这样能花费大概十几分钟就可以了解到论文是否适合我们的研究方向,是否具有较大参考价值。
  2. 第二遍,确定这篇论文是值得我们读下去的话,可以快速过一遍论文,一些细节比如公式和公式证明推导等部分可以不看直接跳过,但需要了解一些重要的图和表,知道每个模块部分在干什么,并且对一些相关文献做好标记和注释。如果觉得自己正在读的论文难度太大不易懂,并且觉得这篇论文还有深究的必要,那就可以先去读引用的文献。
  3. 第三遍,首先需要明白每一句、每一段在干什么。同时,主动给自己设定难题,即如果我来解决xx问题,我的方法和思路会是什么,作者的方法好在哪里,对自己的启发是什么。其次,作者一定说明了哪些地方我没有再去深究探索,那么我们可以思考一下这些地方,我们是否有思路,或者这些地方会是我们以后文章的研究方向或者创新点吗?最后,需要明确整个实验的流程,关闭文章,能做到脑海中的复现和口头复述,能回忆起文章的大部分内容。这样,日后自己的文章也能知道是否可以引用等等。



巷港
6天前

阅读量破万啦!开心!

学习竞赛科研继续努力啊!!冲!!

阅读量破万啦!.png




巷港
12天前

这不只是一道线性dp题,也是信息检索中拼写校正的重要方法

今天上限选课《信息检索》学了拼写校正法中的编辑距离,对动态规划解决编辑距离有了更为本质的理解和体会。
现在结合原理推导,重新理解一遍这道经典的线性dp题目。

回顾题意

给定两个字符串 A 和 B,现在要将 A 经过若干操作变为 B,可进行的操作有:
删除–------将字符串 A 中的某个字符删除。
插入–------在字符串 A 的某个位置插入某个字符。
替换–-----将字符串 A 中的某个字符替换为另一个字符。
现在请你求出,将 A 变为 B 至少需要进行多少次操作。


《信息检索》中拼写校正法对于编辑距离的定义

给定两个字符串 $s_1$和 $s_2$,两者的编辑距离(edit distance)定义为将$s_1$转换为$s_2$的最小编辑操作数。
通常,这样的编辑操作为:
(1) 将一个字符插入字符串
(2)从字符串中删除一个字符
(3)将字符串中的一个字符替换成另一个字符


我们可以发现,将一个字符串变为另一个字符串的方式就是以上三种。我们可以通过矩阵的推导理解本质

以字符串$s_1=”paris”$和$s_2=”alice”$为例推导矩阵

矩阵推导.png


其中,每一个方格中的四个元素分别代表的含义是:

1、左上角:根据左上角的元素是否替换,若当前对应元素相等则不替换(即值等于左上角),若不等则替换(左上角+1)
2、右上角:$s_1$当前元素删除(或等价于$s_2$插入一个字符)
3、左下角:$s_1$插入一个字符(或等价于$s_2$删除当前元素)
4、右下角:这三种操作的最小值。即替换、删除、插入这三种操作对应的操作数的最小值。

因此,矩阵第i行第j列中右下角方格的元素代表的是$s_1$的前i个字符构成的字符串和$s_2$前j个字符构成的字符串的编辑距离


代码详解

#include <bits/stdc++.h>
using namespace std;
const int N = 1010;
char a[N],b[N];
int f[N][N];
int n,m;
int main()
{
    scanf("%d%s",&n,a+1); //从下标为1读入a字符串
    scanf("%d%s",&m,b+1); //从下标为1读入b字符串
    for (int i=1;i<=n;i++) f[i][0]=i; //b为空串时
    for (int j=1;j<=m;j++) f[0][j]=j; //a为空串时

    //核心dp
    for (int i=1;i<=n;i++)
        for (int j=1;j<=m;j++)
        {
            //首先更新一下a中插入和a删除的情况作为预选答案
            //也就是先得到本方格内左下角和右上角的元素值
            f[i][j]=min(f[i][j-1],f[i-1][j])+1;
            // 这时再根据此时a和b的对应字符是否相等决定a替换这种情况
            //也就是得到本方格内左上角的值,然后得出右下角的值
            if (a[i]==b[j]) f[i][j]=min(f[i][j],f[i-1][j-1]); //相等
            else f[i][j]=min(f[i][j],f[i-1][j-1]+1); //不等
        }
    printf("%d\n",f[n][m]); //回归定义,答案就是a的前n个字符和b的前m个字符的最短编辑距离
    return 0;
}



巷港
12天前

这不只是一道线性dp题,也是信息检索中拼写校正的重要方法

今天上限选课《信息检索》学了拼写校正法中的编辑距离,对动态规划解决编辑距离有了更为本质的理解和体会。
现在结合原理推导,重新理解一遍这道经典的线性dp题目。

回顾题意

给定两个字符串 A 和 B,现在要将 A 经过若干操作变为 B,可进行的操作有:
删除–------将字符串 A 中的某个字符删除。
插入–------在字符串 A 的某个位置插入某个字符。
替换–-----将字符串 A 中的某个字符替换为另一个字符。
现在请你求出,将 A 变为 B 至少需要进行多少次操作。


《信息检索》中拼写校正法对于编辑距离的定义

给定两个字符串 $s_1$和 $s_2$,两者的编辑距离(edit distance)定义为将$s_1$转换为$s_2$的最小编辑操作数。
通常,这样的编辑操作为:
(1) 将一个字符插入字符串
(2)从字符串中删除一个字符
(3)将字符串中的一个字符替换成另一个字符


我们可以发现,将一个字符串变为另一个字符串的方式就是以上三种。我们可以通过矩阵的推导理解本质
矩阵推导.png


其中,每一个方格中的四个元素分别代表的含义是:

1、左上角:根据左上角的元素是否替换,若当前对应元素相等则不替换(即值等于左上角),若不等则替换(左上角+1)
2、右上角:$s_1$当前元素删除(或等价于$s_2$插入一个字符)
3、左下角:$s_1$插入一个字符(或等价于$s_2$删除当前元素)
4、右下角:这三种操作的最小值。即替换、删除、插入这三种操作对应的操作数的最小值。

因此,矩阵第i行第j列中右下角方格的元素代表的是$s_1$的前i个字符构成的字符串和$s_2$前j个字符构成的字符串的编辑距离


代码详解

#include <bits/stdc++.h>
using namespace std;
const int N = 1010;
char a[N],b[N];
int f[N][N];
int n,m;
int main()
{
    scanf("%d%s",&n,a+1); //从下标为1读入a字符串
    scanf("%d%s",&m,b+1); //从下标为1读入b字符串
    for (int i=1;i<=n;i++) f[i][0]=i; //b为空串时
    for (int j=1;j<=m;j++) f[0][j]=j; //a为空串时

    //核心dp
    for (int i=1;i<=n;i++)
        for (int j=1;j<=m;j++)
        {
            //首先更新一下a中插入和a删除的情况作为预选答案
            //也就是先得到本方格内左下角和右上角的元素值
            f[i][j]=min(f[i][j-1],f[i-1][j])+1;
            // 这时再根据此时a和b的对应字符是否相等决定a替换这种情况
            //也就是得到本方格内左上角的值,然后得出右下角的值
            if (a[i]==b[j]) f[i][j]=min(f[i][j],f[i-1][j-1]); //相等
            else f[i][j]=min(f[i][j],f[i-1][j-1]+1); //不等
        }
    printf("%d\n",f[n][m]); //回归定义,答案就是a的前n个字符和b的前m个字符的最短编辑距离
    return 0;
}


活动打卡代码 AcWing 814. 复制数组

巷港
16天前
def copy(a,b,size):
    b[:size] = a[:size]

n,m,size = map(int,input().split())
a = list(map(int,input().split()))
b = list(map(int,input().split()))
copy(a,b,size)
for i in range(m):
    print(b[i],end=" ")


活动打卡代码 AcWing 809. 最小公倍数

巷港
16天前
def gcd(a,b):
    if b == 0:
        return a
    return gcd(b,a%b)

a,b = map(int,input().split())
print(a*b//gcd(a,b))


活动打卡代码 AcWing 807. 区间求和

巷港
16天前

``’
def add_sum(l,r):
ans = 0
for i in range(l,r+1):
ans +=i
return ans

l,r = map(int,input().split())
print(add_sum(l,r))
```



活动打卡代码 AcWing 806. 两个数的和

巷港
16天前
def add(a,b):
    return a+b

a,b = map(float,input().split())
print(f"{add(a,b):.2f}")