序列切片操作

75 阅读3分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第31天,点击查看活动详情


大家好,我是芒果,一名非科班的在校大学生。对C/C++、数据结构、Linux及MySql、算法等领域感兴趣,喜欢将所学知识写成博客记录下来。 希望该文章对你有所帮助!如果有错误请大佬们指正!共同学习交流

作者简介:


序列的切片操作

  • 切片操作符([ ], [A:B], [A:B:C]): 通过下标访问其中的某一个元素, 或者某个子序列

image-20220318084117964

  • 正数的索引以序列的起始位置作为起点, 负数的索引以序列的结束位置做为起点.
  • 试图访问一个越界的索引, 会引发异常(可以简单理解成程序执行出错)
a  =[1,2,3]
print(a[100])
#执行结果:
IndexError: list index out of range

关于切片:左闭右开区间

方式1:[:] 左右两个端点都不写值,截取的是整个序列的元素,从头到尾

a  =[1,2,3,4,5]
print(a[:])#[1, 2, 3, 4, 5]

方式2:[A:B]

元素下标取值范围: [A,B)

a  =[1,2,3,4,5]
print(a[1:3])       #[2,3]       截取下标[1,3)的元素       print(a[1:-1])      #[2,3,4]     截取下标[1,-1)的元素print(a[:3])        #[1,2,3]     截取下标[0,3)的元素   print(a[1:])        #[2,3,4,5]   截取下标[1,-1)的元素

如果左边端点不写,默认从0开始, 右边端点不写,默认截取到最后一个位置(即:-1位置)


方式3:[A:B:C] 第三个参数表示步长,即每隔多少个元素截取一个

  • 扩展切片操作[::] 除了可以表示子序列的起始和结束位置, 还可以表示 "步长"

例子:

a = [1,2,3,4,5]
print(a[::2])   #每两个元素截取一个
#执行结果:
[1,3,5]

翻转字符串

字符串翻转, 这是一个非常基础, 也是笔试面试中会经常出现的一个题目. 我们学过C/C++, 有三种方法来解决这个问题.

方法1:首尾指针

char str[] = "abcdefg";
char* beg = str;
char* end = str + strlen(str);
while (beg < end) {
    swap(*beg++, *--end);
}

方法2:栈

char str[] = "abcdefg";
Stack stack;
char* p = str;
while(p) {
    stack.push(*p++);
}
int index = 0;
while(!stack.empty()){
    str[index++] = stack.top();
    stack.pop();
}

方法3:使用reverse + 迭代器翻转

#include <algorithm>
char str[] = "abcdefg";
std::reverse(str, str + strlen(str));   //指针就是天然的迭代器

python的做法:

a = "abcdefg"
print(a[::-1])

这个代码的含义:

a[::-1] -1表示往前走,从后往前拿元素

a = [1,2,3,4,5,6]
print(a[::-1])      #[6,5,4,3,2,1]
#含义
从-1位置往前走,先走到下标为-1位置,然后从6开始往前走

对于切片语法来说, 下标越界也没关系. 因为取的是前闭后开区间,区间里的元素, 能取到多少就取到 多少.