leetcode【数据结构简介】《数组和字符串》卡片——字符串简介

字符串简介

字符串实际上是一个 unicode 字符数,可以执行几乎所有在数组中使用的操作。
下面将介绍一些在处理字符串时应该注意的问题。这些特性在不同的语言之间可能有很大不同。

比较函数

字符串有他自己的比较函数
然而,存在这样一个问题:

我们可以用 == 来比较两个字符串吗?

这取决于下面这个问题的答案:

我们使用的语言是否支持运算符重载?

  1. 如果答案是 yes (例如 C++)。我们可以使用 == 来比较两个字符串。
  2. 如果答案是 no (例如 Java),我们可能无法使用 == 来比较两个字符串。当我们使用 == 时,它实际上会比较这两个对象是否是同一个对象。
  3. 关于C,字符串的比较函数为strcmp,不能用==来比较两个字符串。关于strcmp的相关介绍见【传送门】小白函数笔记本

关于运算符重载

是否可变

不可变意味着一旦字符串被初始化,你就无法改变它的内容

  • 在某些语言(如 C++、C)中,字符串是可变的。 也就是说,你可以像在数组中那样修改字符串。
  • 在其他一些语言(如 Java)中,字符串是不可变的。 此特性将带来一些问题。 我们将在下一篇文章中阐明问题和解决方案。

额外操作

要了解内置操作的时间复杂度。
在计算解决方案的时间复杂度时,不要忘记考虑内置操作的时间复杂度。

不可变字符串——问题和解决方案

在上文中,应该已经知道某门语言中的字符串是否为不可变的。如果字符串是不可变的,则会带来一些问题。

修改操作

不可变字符串无法被修改。哪怕你只是想修改其中的一个字符,也必须创建一个新的字符串。

小心Java中的字符串

在 Java 中,由于字符串是不可变的,因此在连接时首先为新字符串分配足够的空间,复制旧字符串中的内容并附加到新字符串。

解决方案

  1. 如果你确实希望你的字符串是可变的,则可以将其转换为字符数组。
  2. 如果你经常必须连接字符串,最好使用一些其他的数据结构,如 StringBuilder

相应程序练习

1. 二进制求和

题目

  • 给定两个二进制字符串,返回他们的和(用二进制表示)。
  • 输入为非空字符串且只包含数字 1 和 0。

输入: a = “11”, b = “1”
输出: “100”

思路

  • 满二进一

“奇淫巧计”

奇淫巧计一:巧用三目运算符

下面两种代码,实现效果一样,哪一种更简洁呢?

length = length1>length2?(length1+1):(length2+1);
if(length1>length2)	length=length1+1;
else	length=length2+1;

再比如,一个比较两个数大小的max函数代码:

int max(int a, int b){
    return a>b?a:b;
}
int max(int a, int b){
    if(a>b) return a;
    else return b;
}

哪个更简洁呢?

奇淫巧计二:妙用ASCII码

因为这个程序涉及到进位,仅仅只靠字符自然是不能使代码最简洁明了,所以我们需要使用到ASCII码。

1'1'的转换,你还在用if(a='1') c = 1;吗?
c = a-'0'; 它不香吗?

奇淫巧计三:用sum存储进位信息

问:从后往前遍历,难道每个位子时候进位都需要记录下来?
答:这确实需要记录下来。
问:但是要开一个数组来一一记录吗?
答:只需要一个实时更新的变量来存储进位信息!(本程序的变量名为sum)

值得注意的是

关于if()

关于if()条件判断语句,如果()里面有多个条件,从左往右一一遍历。
除非,&&中,有一为0则整个为0;||中,有一为1则整体为1,后面不再遍历。

关于字符串数组

字符串总是以'\0'作为结束符。因在再给一个字符串分配空间的时候,需要多给一个字符的空间存放结束符'\0'。不然很容易出现数组越界或者其他情况。
举例:"hello"的长度其实为6,分配的空间为sizeof(char) * 6

代码

char * addBinary(char * a, char * b){
    int length,length1=strlen(a),length2=strlen(b),sum=0,i=length1-1,j=length2-1,k,num;
    length = length1>length2?(length1+1):(length2+1);
    char *c=(char *)malloc(sizeof(char)*(length+1));
    c[0]='0';c[length]='\0';
    k=length-1;
    while(i>-1||j>-1||sum)
    {
        num=(i>-1?a[i]-'0':0)+(j>-1?b[j]-'0':0)+sum;
        sum=0;
        if(num>1)
        {
            sum=1;
            num-=2;
        }
        c[k--]=num+'0';
        j--;i--;
    }
    if(c[0]=='0')
    {
        for(i=0;i<length-1;i++)
            c[i]=c[i+1];
        c[length-1]='\0';
    }
    return c;
}

执行结果

二进制求和执行结果

2. 实现strStr()

题目

给定一个 haystack 字符串和一个 needle 字符串,在 haystack 字符串中找出 needle 字符串出现的第一个位置 (从0开始)。如果不存在,则返回 -1。

输入: haystack = “hello”, needle = “ll”
输出: 2

方法一:暴力解决

【注意】字符串为空字符串的表示:*needle==NULL

代码如下:

int strStr(char * haystack, char * needle){
    int len1=strlen(haystack), len2=strlen(needle);
    if(*needle==NULL) return 0;
    if(len1<len2) return -1;
    for(int i=0; i<len1; i++){
        int flag = 0;
        for(int j=0; j<len2; j++){
            if(haystack[i+j]!=needle[j]){
                flag = 1;
                break;
            }
        }
        if(!flag) return i;
    }
    return -1;
}

执行效果:
暴力解决strStr()执行结果

虽然代码行数少,但是运行时间实在惨不忍睹,这终究不是一段好代码。寻求突破口:KMP算法以及KMP算法的改进算法
KMP算法解析传送门

方法二:KMP算法

日后补上

3. 最长公共前缀

题目

编写一个函数来查找字符串数组中的最长公共前缀。
如果不存在公共前缀,返回空字符串 “”。

输入: [“flower”,“flow”,“flight”]
输出: “fl”

输入: [“dog”,“racecar”,“car”]
输出: “”
解释: 输入不存在公共前缀。

思路

从上往下,每个比一比。

主要是特例的考虑:输入为[][""]的时候。

if(!strsSize) return "";
if(ch=='\0' && i==0) flag=0;

代码

char * longestCommonPrefix(char ** strs, int strsSize){
    if(!strsSize) return "";    
    int len1 = strlen(strs[0]); char ch;    
    char * s = (char *)malloc(sizeof(char) * (len1+1));    
    for(int i=0; i<len1+1; i++){
        ch = strs[0][i];        
        int flag=1;        
        if(ch=='\0' && i==0) flag=0;        
        for(int j=1; j<strsSize && flag; j++)            
        if(ch!=strs[j][i]) flag = 0;        
        if(!flag){            
            s[i] = '\0';            
            break;        
        }        
        else s[i] = ch;
    }
    return s;
}

执行效果

最长公共前缀执行效果

发布了13 篇原创文章 · 获赞 2 · 访问量 277

猜你喜欢

转载自blog.csdn.net/AuthurWhywat/article/details/105045106