首页 > 编程语言 >算法练习-day8

算法练习-day8

时间:2023-06-15 17:33:01浏览次数:48  
标签:needle day8 int 练习 next 算法 数组 字符串 haystack

字符串

28. 找出字符串中第一个匹配项的下标

题意:给你两个字符串haystack和needle,请你在haystack字符串中找出needle字符串的第一个匹配项的下标(下标从0开始)。如果needle不是haystack的一部分,则返回-1。

示例:

算法练习-day8_i++

       思路:本题有两种思路:1.暴力求解法,只需要一次遍历,以i为haystack字符串的起始,对needle的第一个元素进行对比,若相等则继续循环对比,当出现比较元素次数等于needle字符串长度时,就说明i开头就是needle字符串第一次出现的位置,时间复杂程度为O(m*n);2.KMP算法求解,我们使用KMP算法,可以跳过一些不必要的比较,比如:haystack=“aaaaaaaab”,needle=“aab”,此时我们就需要多次重复比较aa,直到最后匹配成功,这是非常麻烦的,而我们使用KMP算法,最直观的就是指向needle的指针不用回退,就算不动也不会从0开始比较,这也是KMP算法的优点;其次是next数组的建立,该数组就是匹配比较失败后,哪个haystack数组中元素该和needle数组元素进行比较

这里我建议大家可以看下这个视频,对KMP算法的了解会更加透彻:KPM算法

方法1代码:

    int strStr(string haystack, string needle) {
        for (int i = 0; i<haystack.size(); i++)
        {
            int j = 0;
            if (haystack[i] == needle[j])
            {
                int n = i;
                while (j < needle.size() && haystack[n] == needle[j])
                {
                    n++, j++;
                }
                if (n - i == needle.size())
                {
                    return i;
                }
            }
        }
        return -1;
    }

方法2代码:

    vector<int> BuildNext(string& needle)//创建next数组
    {
        vector<int> next;
        int i = 1, prefix = 0;//i表示走到的数组位置,prefix表示前缀长度
        next.push_back(0);//第一个元素的前缀长度一定为0
        while (i<needle.size())
        {
            if (needle[i] == needle[prefix])//当元素相等时,前缀长++,i继续向后移动
            {
                prefix++;
                next.push_back(prefix);
                i++;
            }
            else
            {
                if (prefix == 0)//当prefix为0时,说明该元素没有与之相等的前缀长
                {
                    next.push_back(prefix);
                    i++;
                }
                else//寻找之前前缀长
                {
                    prefix = next[prefix - 1];
                }
            }
        }
        return next;
    }
    int strStr(string haystack, string needle) {
        vector<int> next = BuildNext(needle);
        int i = 0, j = 0;
        while (i < haystack.size())
        {
            if (haystack[i] == needle[j])//当两个元素相等时,++i,++j
            {
                i++,j++;
            }
            else if (j>0)//不等时,可以跳过之前匹配的needle元素,让haystack的不匹配元素和needle的下一个待匹配元素比较
            {
                j = next[j - 1];
            }
            else
            {
                i++;
            }
            if (j == needle.size())
            {
                return i - j;
            }
        }
        return -1;
    }

459. 重复的子字符串

题意:给定一个非空的字符串s,检查是否可以通过由它的一个子串重复多次构成。

示例:

算法练习-day8_i++_02

       思路:1.旋转数组法,若字符串全部由子串组成,则说明字符串是对称的,因此,我们可以将字符串一个个向后移动,在字符串遍历结束前,当移动后字符串等于移动前字符串时,就说明该字符串就是由子串组成;2.KMP算法,由于当字符串为子串组成的时,next数组会形成第一段子串为0,其他子串递增的情况,因此当我们得到next数组后,只需要判断两点:

  1. next数组末尾不为0
  2. 整个字符串%一组字串为0

即可说明,该字符串就是由子串组成 

方法1代码:

    bool repeatedSubstringPattern(string s) {
        for(int i=1;i<s.size();i++)
        {
            string clone=s.substr(i)+s.substr(0,i);
            if(clone==s)
            {
                return true;
            }
        }
        return false;
    }

方法2代码:

    vector<int> BuildNext(string& s)
    {
        vector<int> next;
        next.push_back(0);
        int i=1,prefix=0;
        while(i<s.size())
        {
            if(s[prefix]==s[i])
            {
                prefix++;
                next.push_back(prefix);
                i++;
            }
            else
            {
                if(prefix==0)
                {
                    next.push_back(prefix);
                    i++;
                }
                else
                {
                    prefix=next[prefix-1];
                }
            }
        }
        return next;
    }
    bool repeatedSubstringPattern(string s) {
        vector<int> next = BuildNext(s);
        int len = next.size();
        if (next[len-1] != 0 && (len % (len - next[len-1]) == 0))
        {
            return true;
        }
        return false;
    }

标签:needle,day8,int,练习,next,算法,数组,字符串,haystack
From: https://blog.51cto.com/u_15209404/6493660

相关文章

  • 算法——树(一)
    1、中序遍历递归classSolution{List<Integer>ans=newArrayList<>();publicList<Integer>inorderTraversal(TreeNoderoot){inorder(root);returnans;}publicvoidinorder(TreeNoderoot){if(root!=nul......
  • JDBC练习-添加
      /**添加*1.insertintotb_brand(brand_name,company_name,ordered,description,status)values(?,?,?,?,?);*2.参数:需要id之外所有参数信息*3.结果:boolean**/@TestpublicvoidtestBrand1()throwsException{......
  • 数据结构(python版)—— 2、前期知识与算法分析
    从C转到python(一)C:helloWorld!#include<stdio.h>​intmain(){//sayhelloprintf("HelloWorld!\n")}1-Compile编译到机器码2-Link与各种库链接3-Execute执行目标程序Python:HelloWorld!defmain():#sayhelloprint("HelloWorld!"......
  • python day8
    第一阶段第六章6.10数据容器(序列) ......
  • 2小时解不完的数据库练习题,来挑战一下吧!
    写在前面我已经记不起来,有多久没更新文章了。5月中旬我还在上班,中旬以后一系列发生的事情,真的远远超出了可承受范围,只能硬着头皮面对!我是谁,我应该是谁,又能怎样,只能向前·····数据库实例class表course表score表student表teacher表实际语句1、查询所有的课程的......
  • 力扣上任务调度相关的算法
    目录应用应用1:Leetcode1834.单线程CPU题目分析代码实现应用2:Leetcode621.任务调度器题目分析代码实现应用应用1:Leetcode1834.单线程CPU题目1834.单线程CPU给你一个二维数组tasks,用于表示n项从0到n-1编号的任务。其中\(tasks[i]=[enqueueTime_i,proc......
  • 优化算法——人工蜂群算法(ABC)
    一、人工蜂群算法的介绍  人工蜂群算法(ArtificialBeeColony,ABC)是由Karaboga于2005年提出的一种新颖的基于群智能的全局优化算法,其直观背景来源于蜂群的采蜜行为,蜜蜂根据各自的分工进行不同的活动,并实现蜂群信息的共享和交流,从而找到问题的最优解。人工蜂群算法属于群......
  • 简单易学的机器学习算法——岭回归(Ridge Regression)
    一、一般线性回归遇到的问题  在处理复杂的数据的回归问题时,普通的线性回归会遇到一些问题,主要表现在:预测精度:这里要处理好这样一对为题,即样本的数量和特征的数量时,最小二乘回归会有较小的方差时,容易产生过拟合时,最小二乘回归得不到有意义的结果模型的解释能力:如果模型中的特征......
  • 简单易学的机器学习算法——协同过滤推荐算法(1)
    一、推荐系统的概念  推荐系统(RecommendationSystem,RS),简单来说就是根据用户的日常行为,自动预测用户的喜好,为用户提供更多完善的服务。举个简单的例子,在京东商城,我们浏览一本书之后,系统会为我们推荐购买了这本书的其他用户购买的其他的书:推荐系统在很多方面都有很好的应......
  • C#中使用CAS实现无锁算法
    CAS的基本概念CAS(Compare-and-Swap)是一种多线程并发编程中常用的原子操作,用于实现多线程间的同步和互斥访问。它操作通常包含三个参数:一个内存地址(通常是一个共享变量的地址)、期望的旧值和新值。CompareAndSwap(内存地址,期望的旧值,新值)CAS操作会比较内存地址处的值与期望......