【函数描述】
enumerate() 函数用于将一个可遍历的数据对象(如列表、元组或字符串)组合为一个索引序列,同时列出数据和数据下标,一般用在 for 循环当中。
【语法、参数】
enumerate(sequence, [start=0])
参数
- sequence —— 一个序列、迭代器或其他支持迭代对象。
- start —— 下标起始位置的值。
【实例演示】
以下展示了使用 enumerate() 方法的实例:
seasons = ['Spring', 'Summer', 'Fall', 'Winter']
list(enumerate(seasons))
# [(0, 'Spring'), (1, 'Summer'), (2, 'Fall'), (3, 'Winter')]
list(enumerate(seasons, start=1)) # 下标从 1 开始
# [(1, 'Spring'), (2, 'Summer'), (3, 'Fall'), (4, 'Winter')]
for循环中的enumerate()函数 :
seq = ['one', 'two', 'three']
for i, element in enumerate(seq): # 取出索引和元素
print(i, element)
# 0 one
# 1 two
# 2 three
【实战训练】
子串分值和
【题目描述】
对于一个字符串S,我们定义S的分值f(S)为S中出现的不同的字符个数。例如f("aba ')=2,f("abc")= 3,f(“aaa”)=1。现在给定一个字符串 S[0...n-1](长度为n),请你计算对于所有S的非空子串S [i...j](0≤i≤j<n) ,f(S[i.….j])的和是多少。
输入描述
输入一行包含一个由小写字母组成的字符串 SS。
其中,1 ≤ n ≤ 10^51≤n≤105。
输出描述
输出一个整数表示答案。
输入输出样例
输入
ababc
输出
28
问题解析 :
方法:统计个体贡献
由于f(S)表示S中出现的不同的字符个数,也就是说对于字符串aaa而言,3个a中只有一个a可以对其产生贡献。那么我们不妨将第1个、第2个a的贡献抹去,只计算第3个a的贡献。即当一个字符ch在字符串中出现了多次,我们只计算最靠右的ch对答案的贡献(其它ch在该字符串的贡献都被抹去了)。
【做法】定义right_index表示第i个字符下一次出现的位置。那么要让第i个字符能对答案产生贡献,则包含它的子串的左端点的取值范围必须在[1 , i]之间(即左端点没有限制),右端点的取值范围必须在[i+ 1, right_index - 1]之间(若右端点的取值大于等于right_index,则该字符对该子串贡献将被抹除)。其对答案的贡献为限制左右端点取值范围后所能构造出的子串的个数,即i*(right_index - i)。
如上图,左端点:[0]右端点:[1,4]记在第一个a的贡献;左端点:[0,5]右端点:[6,8]记在第二个a的贡献;左端点:[0,9]右端点:[10]记在第三个a的贡献。
代码演示 :
s=input() ans=0 for i,c in enumerate(s): # 取出索引i和元素C r=i+1 # 右端点:当前索引的下一个 while r<len(s): # 右端点从当前索引的下一个到末尾进行遍历 if s[r]!=c:r+=1 # 不是相同的字符,右端点向右移一位 else:break # 是相同的字符,结束 ans+=(i+1)*(r-i) # 贡献:左边(所有)*右边(没有相同)。i+1是因为i从0开始 print(ans)