[题解报告]《算法零基础100讲》(第22讲) 字符串算法(二) - 字符串比较

一. 推荐专栏

推荐算法专栏

《算法零基础100讲》(第22讲) 字符串算法(二) - 字符串比较

二. 重点知识

2.1 strcmp函数

  strcmp是一个比较两个字符串的函数,从第一个字符开始,逐个比较(按照ASCLL码值),直到出现不同的字符或者出现’\0’。
头文件

#include <string.h>

函数定义

int strcmp(const char* str1, const char* str2);

返回值

  1. 如果str1小于str2,返回值 < 0;
  2. 如果str1大于str2,返回值 > 0;
  3. 如果str1等于str2,返回值 = 0;

2.2 strstr函数

  strstr的作用是找到子串在一个字符串中第一次出现的位置。

头文件

#include <string.h>

函数定义

char* strstr(const char* str1, const* str2);

其中str1为被查找的字符串,str2为查找的字串

返回值
  如果在str1中找到str2,将其第一次出现的地址返回,否则返回NULL。

三. 课后习题

3.1 替换空格

题目链接
剑指 Offer 05. 替换空格

思路分析:
  我们只需要在遇到空格位置是分别将’%’,‘2’,'0’三个字符加入即可。
  此外我们还需注意新字符串的长度,最后的情况是原来的三倍。

代码如下:

#define MAX 20000

char* replaceSpace(char* s){
    
    
    char* ret = malloc(MAX);
    int retSize = 0;
    int len = strlen(s);
    for(int i = 0; i < len; i++){
    
    
        if(s[i] == ' '){
    
    
            ret[retSize++] = '%';
            ret[retSize++] = '2';
            ret[retSize++] = '0';
        }
        else{
    
    
            ret[retSize++] = s[i];
        }
    }
    ret[retSize] = '\0';
    return ret;
}

在这里插入图片描述

3.2 稀疏数组搜索

题目链接
面试题 10.05. 稀疏数组搜索

思路分析:
  这道题其实很简单,我们只需要将word里面的每个字符串逐一与s进行比较即可,遇到相同的则返回其下表位置,没有则返回-1。
代码如下:

int findString(char** words, int wordsSize, char* s){
    
    
    for(int i = 0; i < wordsSize; i++){
    
    
        //如果是空格则直接跳过
        if(words[i] == " "){
    
    
            i++;
        }
        //比较是否相等
        if(strcmp(words[i], s)== 0){
    
    
            return i;
        }
    }
    return -1;
}

在这里插入图片描述

3.3 单词规律

题目链接:
290. 单词规律
思路分析:
  这道题用C写确实有写难受。

  1. 首先我的想法是用两个数组hash1,hash2分别记录pattern和s的规律,例如pattern:abba,则hash1:[0,1,1,0],后面出现相同的字符,则将其改为第一次出现的位置的下标,对于s也是如此记录。
  2. 然后问题来了,pattern很好记录,但s是比较一个一维符串数组里的单词,每个单词使用空格个开,它该如何比较每个单词呢?
  3. 这是我们需要定义一个指针数组hash,因为s用空格分开了每个单词,所以我们把所有空格改为’\0’,并且将每个单词的首个字符的地址放入hash中,这样单词就被分开了,如何使用strcmp进行比较,最后得到1中的想法,也就是hash2
    代码如下:
bool wordPattern(char * pattern, char * s){
    
    
    int len1 = strlen(pattern);
    int len2 = strlen(s);
    int hash1[len1];
    int hash2[len1];
    //初始化
    for(int i = 0; i < len1; i++){
    
    
        hash1[i] = i;
        hash2[i] = i;
    }
    //将pattern的模式记录下来
    for(int i = 0; i < len1 - 1; i++){
    
    
        for(int j = i + 1; j < len1; j++){
    
    
            if(pattern[i] == pattern[j]){
    
    
                hash1[j] = hash1[i];
            }
        }
    }
    char* hash[256];
    int hashSize = 0;
    int flag = 1;
    //将s中的单词拆分开来,并用指针数组hash存储
    for(int i = 0; i < len2; i++){
    
    
        if(flag){
    
    
            hash[hashSize++] = s + i;
            flag = 0;
        }
        if(s[i] == ' '){
    
    
            s[i] = '\0';
            flag = 1;
        }
    }
    //特殊情况
    if(len1 != hashSize){
    
    
        return false;
    }
    //记录s的模式
    for(int i = 0; i < hashSize - 1; i++){
    
    
        for(int j = i + 1; j < hashSize; j++){
    
    
            if(!strcmp(hash[i], hash[j])){
    
    
                hash2[j] = hash2[i];
            }
        }
    }
    //比较hash1和hash2是否相同
    for(int i = 0; i < len1; i++){
    
    
        if(hash1[i] != hash2[i]){
    
    
            return false;
        }
    }
    return true;;
}

3.4 解码字母到整数映射

题目链接:
1309. 解码字母到整数映射
思路分析:
  这题的主要难点就是 ‘#’ 这个符号,阻挠着我们,但问题也不大。

  1. 首先我们可以发现 j 之后的字符都是由三个字符表示,并且第三个字符是 ‘#’
  2. 然后我们可以根据这个规律,对每个字符后面第二个字符进行判断。
  3. 如果是带 ‘#’ 这个字符的话,他们都是由两个字符对应,这使我们难以通过ASCLL码值进行计算,所以我们要用以个简短的字符串保存它,然后转化为数字。

代码如下:

char * freqAlphabets(char * s){
    
    
    int len = strlen(s);
    char* ret = malloc(len);
    int retsSize = 0;
    //用来转化
    char tmp[3];
    tmp[2] = '\0';
    int i;
    for(i = 0; i < len; i++){
    
    
        //判断是否为j以后的字母
        if(i + 2 < len && s[i + 2] == '#'){
    
    
            tmp[0] = s[i];
            tmp[1] = s[i + 1];
            int k = atoi(tmp);
            ret[retsSize++] = 'j' + (k - 10);
            i += 2;
        }
        else{
    
    
            ret[retsSize++] = s[i] - '1' + 'a';
        }
    }
    ret[retsSize] = '\0';
    return ret;
}

在这里插入图片描述

3.5 作为子字符串出现在单词中的字符串数目

题目链接
1967. 作为子字符串出现在单词中的字符串数目
思路分析:

   这道题我们只需要将pattern中的每个字符串逐一在word中进行寻找,查看是否为word的子串。
代码如下:

int numOfStrings(char ** patterns, int patternsSize, char * word){
    
    
    int ret = 0;
    for(int i = 0; i < patternsSize; i++){
    
    
    	//判断是否为子串
        if(strstr(word, patterns[i])){
    
    
            ret++;
        }
    }
    return ret;
}

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_53060585/article/details/121269192