[C/OC的那点事儿]在一个字符串中查找另一个特定的字符串并确定下标

本文介绍了两种不同的strstr函数实现方法:一种返回目标字符串首次出现的位置指针;另一种返回目标字符串在源字符串中的起始位置。第一种实现利用指针进行逐字符匹配,并通过打印输出目标字符串的位置来验证结果。第二种实现采用双层循环结构,适用于需要获取确切位置的应用场景。
//
//  main.c
//  strstr
//
//  Created by lichan on 13-11-20.
//  Copyright (c) 2013年 com.lichan. All rights reserved.
//

#include <stdio.h>
#include <string.h>
char * mystrstr (const char * str1,const char * str2)
{
    char *cp = (char *) str1;//因为 str1 为不可变量,需要转换成可变的cp变量.
    
    int length = (int)strlen(str1);
    char *s1, *s2;
    
    if ( !*str2 )   //当str2 为空得时候, 直接 把 str1 输出.
        return((char *)str1);
    
    while (*cp)
    {
        s1 = cp;
        s2 = (char *) str2;
        
        while ( *s1 && *s2 && !(*s1-*s2) )   //判断是否有相等的字符. !(*s1 - *s2)==1 表示相等,如果==0 表示 不相等.
            s1++, s2++;
        
        if (!*s2)
        {
           int length2 = (int)strlen(cp);
        printf("%d",(length - length2));
            return(cp);
        }
        
        cp++;
    }
    return NULL;
}

int main(int argc, const char * argv[])
{
    char *str1 ="lichan";
    char *str2 = "cha";
    
    printf("%s",mystrstr(str1, str2));

    // insert code here...
    printf("Hello, World!\n");
    return 0;
}

不得不说,这种算法真心的很巧妙啊. 领教了


方法二: 确定位置:

int strfind(char *str1,char *str2)
{
    int acount = mystrlen(str1);
    int bcount = mystrlen(str2);
   
    
    for (int i = 0; i < acount; i ++)
    {
         int equle = 1;
        
        for (int j = 0; j < bcount; j++)
        {
            if (*(str1+i +j ) != *(str2 + j))
            {
                equle = 0;
                break;
            }
        }
        if (equle ==1)
        {
            return i+1 ;
        }
        
        
    }
    return -1;
}

虽然时间复杂度大,但是也是一种算法.

# T659408 [IAMOI R4] 彻底怒了 ## 题目背景 ![](https://cdn.luogu.com.cn/upload/image_hosting/oc45tenz.png) ## 题目描述 金将军有两个长度为 $n$ 的字符串 $s,t$,他认为一个字符串的愤怒值为其 `CDNL` 子串的个数。 现在,他想在 $s$ 中选出一个长度至多为 $m$ 的子串 $s'$,在 $t$ 中选出一个长度至多为 $k$ 的子串 $t'$,使 $s',t'$ 按顺序拼接后的字符串的愤怒值最大,你需要帮他求出这个值。 子串为原字符串中连续的一段字符组成的字符串。 ## 输入格式 **本题有多组测试数据。** 输入的第一行包含一个整数 $T$,表示测试数据的组数。 接下来包含 $T$ 组数据,对于每组数据: - 第一行包含三个正整数 $n,m,k$。 - 第二行包含一个长度为 $n$ 的字符串 $s$。 - 第三行包含一个长度为 $n$ 的字符串 $t$。 ## 输出格式 对于每组数据输出一行包含一个整数,表示答案。 ## 输入输出样例 #1 ### 输入 #1 ``` 2 4 4 4 CDNL CDNL 2 2 2 CD NL ``` ### 输出 #1 ``` 2 1 ``` ## 说明/提示 **【样例解释】** 对于第一组数据,最优解拼接成的串是 `CDNLCDNL`,包含 $2$ 个 `CDNL` 子串,愤怒值为 $2$。 对于第二组数据,最优解拼成的串是 `CDNL`,包含 $1$ 个 `CDNL` 子串,愤怒值为 $1$。 **【数据范围】** | 测试编号 | $n\le$ | $m,k$ | 分数 | |:-:|:-:|:-:|:-:| | $1$ | $10^5$ | $=n$ | $20$ | | $2$ | $10$ | $\le n$ | $30$ | | $3$ | $100$ | ^ | $20$ | | $4$ | $10^5$ | $\le 10$ | ^ | | $5$ | ^ | $\le n$ | $10$ | 对于所有数据,保证:$1\le T\le 10$,$1\le n,m,k\le 10^5$,$s,t$ 中只包含大写字母 `C`,`D`,`N`,`L`。
最新发布
10-02
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值