LeetCode字符串#extraKMP巩固练习:旋转字符串字符串轮转

Posted DAYceng

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LeetCode字符串#extraKMP巩固练习:旋转字符串字符串轮转相关的知识,希望对你有一定的参考价值。

旋转字符串

https://leetcode.cn/problems/rotate-string/

给定两个字符串, s 和 goal。如果在若干次旋转操作之后,s 能变成 goal ,那么返回 true 。

s 的 旋转操作 就是将 s 最左边的字符移动到最右边。

例如, 若 s = \'abcde\',在旋转一次之后结果就是\'bcdea\' 。

示例 1:

输入: s = "abcde", goal = "cdeab"
输出: true

示例 2:

输入: s = "abcde", goal = "abced"
输出: false

提示:

1 <= s.length, goal.length <= 100
s 和 goal 由小写英文字母组成

思路

与重复子串一样有两种思路:

1、直接将字符串s和goal相加,然后再相加后的字符串中查找s或者goal,找到就可以返回true

2、使用KMP算法

先求出s的next数组,然后还是将字符串s和goal相加,得到新字符串

goal 字符串复制一份连接到自身末尾,得到新的字符串 s2 的目的是为了模拟旋转操作之后的字符串。

假设原始字符串是 s,通过左旋若干次后得到的新字符串是 s\'。如果我们将 ss\' 进行比较,就会发现它们实际上是相同的字符串,只是从不同位置开始截取的。而这个位置的关系可以通过将 goal 复制一份连接到自身末尾来体现。

举个例子:假设 s = "abcde",将 s 左移两位得到的新字符串是 s\' = "cdeab"。那么将 goal 复制一份连接到自身末尾,得到的字符串是 goal + goal = "cdeababcde"。我们可以发现,在 goal + goal 中,第一个 goals\' 是对应的,因为它们都是从 c 开始的;第二个 goal 对应的就是 s,因为它们都是从 a 开始的。

使用KMP算法在新字符串中查找s

为了这点醋包了这碗面

代码

字符串相加使用find
//与重复子字符串的简单版本思路类似
class Solution 
public:
    bool rotateString(string s, string goal) 
        return s.size() == goal.size() && (s + s).find(goal) != string::npos;
    
;
脱裤子放屁法(KMP)
class Solution 
private:
    void getNext(int* next, string& s)
        int j = -1;
        next[0] = j;
        for(int i = 1 ;i < s.size(); ++i)
            while(j >= 0 && s[i] != s[j + 1]) j = next[j];

            if(s[i] == s[j + 1]) j++;
            next[i] = j;
        
    
public:
    bool rotateString(string s, string goal) 
        //判断一下,如果两个字符串长度不等直接false,如果给的字符串是空,那怎么转都可以得到本身,返回true
        //s为空goal不空的情况已经包含第一个判断中
        if(s.size() != goal.size()) return false;
        if(s.empty()) return true;

        // 将goal字符串复制一份连接到自身末尾,得到新的字符串s2
        string s2 = goal + goal; //string s2 = s + goal;也行
        int j = -1;
        int next[s.size()];
        getNext(next, s);

        for(int i = 0; i < s2.size(); ++i)//在s2中查找s
            while(j >= 0 && s2[i] != s[j + 1])
                j = next[j];
            

            if(s2[i] == s[j + 1])
                j++;
            

            if(j == s.size() - 1) return true;//遍历完s后结束
        
        return false;
    
;

字符串轮转

https://leetcode.cn/problems/string-rotation-lcci/

字符串轮转。给定两个字符串s1和s2,请编写代码检查s2是否为s1旋转而成(比如,waterbottle是erbottlewat旋转后的字符串)。

示例1:

输入:s1 = "waterbottle", s2 = "erbottlewat"
输出:True
示例2:

输入:s1 = "aa", s2 = "aba"
输出:False
提示:

字符串长度在[0, 100000]范围内。
说明:

你能只调用一次检查子串的方法吗?

思路

和旋转字符串一样,直接给代码

代码

字符串相加使用find
//与重复子字符串的简单版本思路类似
class Solution 
public:
    bool isFlipedString(string s1, string s2) 
        return s1.size() == s2.size() && (s2 + s2).find(s1) != string::npos;
    
;
KMP
//kmp版本
class Solution 
private:
    void getNext(int* next, string& s)
        int j = -1;
        next[0] = j;

        for(int i = 1; i < s.size(); ++i)
            while(j >= 0 && s[j + 1] != s[i])
                j = next[j];
            

            if(s[j + 1] == s[i]) j++;
            next[i] = j;
        

    
public:
    bool isFlipedString(string s1, string s2) 
        if(s1.size() != s2.size()) return false;
        if(s1.empty()) return true;

        int j = -1;
        int next[s1.size()];
        string ss2 = s2 + s2;
        getNext(next, s1);

        for(int i = 0; i < ss2.size(); ++i)
            while(j >= 0 && ss2[i] != s1[j + 1]) j = next[j];

            if(ss2[i] == s1[j + 1]) j++;

            if(j == s1.size() - 1) return true;
        
        return false;
    
;

2017-02-22if语句 if语句的嵌套 及巩固练习------------练习补充

“请输入年份:”(1-9999)
“请输入月份:”(1-12)
“请输入日期:”(要判断大小月,判断闰年)
判断输入的时间日期是否正确

//输出“请输入年份:”判断(1-9999)
            //输出“请输入月份:”判断(1-12)
            //输出“请输入日期:”判断(大小月、闰年、不能是负数)
            Console.Write("请输入年份(1-9999):");
            int nf = Convert.ToInt32(Console.ReadLine());



            if (nf > 0 && nf < 9999)
            {
                Console.WriteLine("您输入的格式正确");
                Console.Write("请输入月份(1-12):");
                int yf = Convert.ToInt32(Console.ReadLine());
                if (yf > 0 && yf < 13)
                {
                    Console.WriteLine("您输入的格式正确");
                    Console.Write("请输入日期");
                    int rq = Convert.ToInt32(Console.ReadLine());
                    if (rq > 0 && nf % 400 == 0 && yf == 1 && yf == 3 && yf == 5 && yf == 7 && yf == 8 && yf == 10 && yf == 12)
                    {
                        Console.WriteLine("您输入的格式正确");
                    }
                    else if (nf % 4 == 0 && nf % 100 == 0)
                    {
                        Console.WriteLine("您输入的格式正确");
                    }
                    else
                    {
                        Console.WriteLine("您输入的格式有误");
                    }
                }
                else
                {
                    Console.WriteLine("您输入的格式有误");
                }
            }
            else
            {
                Console.WriteLine("您输入的格式有误");
            }















            Console.ReadLine();

 

 

 

 

 

标准体重//注意运算关系的变换
男士体重 = 身高 - 100 +-3
kg cm
女士体重 = 身高 - 110 +-3

//男士体重 = 身高 - 100 +-3
            //     kg        cm
            //女士体重 = 身高 - 110 +-3
            Console.Write("请输入您的性别(男/女):");
            string xb = Console.ReadLine();

            Console.Write("请输入您的体重(kg):");
            double tz = Convert.ToDouble(Console.ReadLine());

            Console.Write("请输入您的身高(cm):");
            double sg = Convert.ToDouble(Console.ReadLine());


            if (xb == "")
            {
                double n = tz - sg + 100;
                if (n <= 3 && n >= -3)
                {
                    Console.WriteLine("您的体重是标准体重");
                }
                else if (n > 3)
                {
                    Console.WriteLine("您需要减肥了");
                }
                else if (n < -3)
                {
                    Console.WriteLine("您需要增加营养");
                }
            }
            else if (xb == "")
            {
                double n1 = tz - sg + 110;
                if (n1 <= 3 && n1 >= -3)
                {
                    Console.WriteLine("您的体重是标准体重");
                }
                else if (n1 > 3)
                {
                    Console.WriteLine("您需要减肥了");
                }
                else if (n1 < -3)
                {
                    Console.WriteLine("您需要增加营养");
                }
            }

            else
            {
                Console.WriteLine("您输入的格式有误");
            }















            Console.ReadLine();

 

 

 

 

 

“请输入24小时制的时间:”
0-24 如果超出“时间输入有误”

11 - “上午11点”
14 - “下午2点”

6点前是“凌晨”
晚上10点后是“深夜”

 

//“请输入24小时制的时间:”
            //0-24 如果超出“时间输入有误”

            //11 - “上午11点”
            //14 - “下午2点”

            //6点前是“凌晨”
            //晚上10点后是“深夜”
            Console.Write("请输入24小时制的时间:");
            int sj = Convert.ToInt32(Console.ReadLine());


            if (sj < 0 && sj > 24)
            {
                Console.WriteLine("您输入的时间格式有误");
            }
            else if (sj > 0 && sj < 24)
            {
                if (sj < 6)
                {
                    Console.WriteLine("凌晨" + sj + "");
                }
                else if (sj < 12)
                {
                    Console.WriteLine("上午" + sj + "");
                }
                else if (sj > 22)
                {
                    Console.WriteLine("深夜" + (sj - 12) + "");
                }
                else
                {
                    Console.WriteLine("下午" + (sj - 12) + "");
                }
            }






            Console.ReadLine();

 

以上是关于LeetCode字符串#extraKMP巩固练习:旋转字符串字符串轮转的主要内容,如果未能解决你的问题,请参考以下文章

2019 CCPC秦皇岛 J 题 MUV LUV EXTRAKMP 求最小循环节

LeetCode-Mysql练习1(175/176/177/178/184/185)(排名函数)

2017-02-22if语句 if语句的嵌套 及巩固练习------------练习补充

keyFile 巩固练习

差分数组(定义+性质+证明+代码实现+巩固练习)

python学习-练习题4巩固