数据结构——字符串

1.leetcode 151

题目链接:

. - 力扣(LeetCode). - 备战技术面试?力扣提供海量技术面试资源,帮助你高效提升编程技能,轻松拿下世界 IT 名企 Dream Offer。https://leetcode.cn/problems/reverse-words-in-a-string/题目评价:极好的字符串题目,考察逆转、删除空格,解法多次使用了双指针法

cpp 复制代码
class Solution {
public:
    //逆转字符串s中起始l到末尾r的子串
    void reverse(string& s,int l,int r)
    {
        char tmp = 0;
        while (l < r)
        {
            tmp = s[l];
            s[l] = s[r];
            s[r] = tmp;
            l++; r--;
        }
    }
    

   /* 单词 是由非空格字符组成的字符串。s 中使用至少一个空格将字符串中的 单词 分隔开。
返回 单词 顺序颠倒且 单词 之间用单个空格连接的结果字符串。
注意:输入字符串 s中可能会存在前导空格、尾随空格或者单词间的多个空格。返回的结果字符串中,单词间应当仅用单个空格分隔,且不包含任何额外的空格。*/
    string reverseWords(string s) {
       //先清除空格,再总体逆转整个字符串,再逐个逆转每个单词
        removeBlanks(s);
        reverse(s, 0, s.length()-1);
        reverseEachWord(s);
        return s;
    }

 //删除前置后置空格,以及单词间冗杂的空格,时间复杂度为O(n)
    void removeBlanks(string& s)
    {
        //erase时间复杂度为O(n),遍历+erase时间复杂度为O(n^2),采用双指针法时间复杂度为O(n)
        int slow=0;  //慢指针指向新字符串元素
        int fast=0;  //快指针遍历字符串
        for (fast = 0; fast < s.length(); fast++)
        {
            //有两类字符:字母-下个字母->放字母,字母-空格->放字母+空格
            if (s[fast] != ' ')
            {
                if (fast == s.length() - 1 || s[fast + 1] != ' ')
                    s[slow++] = s[fast];
                else
                {
                    s[slow++] = s[fast];
                    s[slow++] = ' ';
                }
            }
        }
        //除末尾多余空格
        if (s[slow - 1] == ' ') slow--;
        s.resize(slow);  //slow指示新字符串的大小
    }

    //在删除空格的基础上,实现每个单词逆转,核心是判断单词的开头与结尾,单词开头要么是第一个字符要么是空格之后的第一个字符
    //单词的结尾要么是最后一个字符,要么是空格后的第一个字符
    void reverseEachWord(string& s)
    {
        int l = 0, r = 0;
        for (int r = 0; r <= s.length(); r++)
        {
            if (s[r] == ' '||r==s.length())
            {
                reverse(s, l, r - 1);
                l = r + 1;
            }
        }
    }
};

2. 替换数字(第八期模拟笔试)

时间限制:1.000S 空间限制:128MB

题目描述

给定一个字符串 s,它包含小写字母和数字字符,请编写一个函数,将字符串中的字母字符保持不变,而将每个数字字符替换为number。 例如,对于输入字符串 "a1b2c3",函数应该将其转换为 "anumberbnumbercnumber"。

输入描述

输入一个字符串 s,s 仅包含小写字母和数字字符。

输出描述

打印一个新的字符串,其中每个数字字符都被替换为了number

输入示例

a1b2c3

输出示例

anumberbnumbercnumber

提示信息

数据范围:

1 <= s.length < 10000。

cpp 复制代码
class solution {
public:
	string convert(string & s)
	{
		//1.识别数字,扩容[number6位扣除数字1位]
		int i = 0;
		while (i<s.length())
		{
			if (s[i] >= '0' && s[i] <= '9')
			{
				int pi = s.length() - 1;
				//1.识别数字,扩容[number6位扣除数字1位],记录需要移动的次数
				int move = s.length()-1 - i;
				s.resize(s.length() + 5);
				//2.双指针,分别指向新老字符串的末尾,把待转化数字后面的字符搬到字符串尾部
				int pj = s.length() - 1;
				while (move--)
				{
					s[pj] = s[pi];
					pj--;
					pi--;
				}
				//3.放进number
				string tmp = "rebmun";
				for (int i = 0; i < 6; i++)
					s[pj - i] = tmp[i];
                //4.移动i
				i += 6;
			}
			else 
			i++;
		}
		return s;
		
	}
};

3. 右旋字符串(第八期模拟笔试)

时间限制:1.000S 空间限制:128MB

题目描述

字符串的右旋转操作是把字符串尾部的若干个字符转移到字符串的前面。给定一个字符串 s 和一个正整数 k,请编写一个函数,将字符串中的后面 k 个字符移到字符串的前面,实现字符串的右旋转操作。

例如,对于输入字符串 "abcdefg" 和整数 2,函数应该将其转换为 "fgabcde"。

输入描述

输入共包含两行,第一行为一个正整数 k,代表右旋转的位数。第二行为字符串 s,代表需要旋转的字符串。

输出描述

输出共一行,为进行了右旋转操作后的字符串。

输入示例

2
abcdefg

输出示例

fgabcde

提示信息

数据范围:

1 <= k < 10000,

1 <= s.length < 10000

cpp 复制代码
class solution {
public:
	void Reverse(string& s, int i, int j)
	{
		char c = 0;
		while (i < j)
		{
			c = s[i];
			s[i] = s[j];
			s[j] = c;
			i++;
			j--;
		}
	}
	string RightReverse(string& s,int k)
	{
		//先局部翻转,再总体翻转 原理表示如:A1B1A2B2->B1A1B2A2->A2B2A1B1
		int len = s.length();
		Reverse(s, 0, len - k - 1);
		Reverse(s, len - k, len - 1);
		Reverse(s, 0, len - 1);
		return s;
	}
};

4. KMP算法

cpp 复制代码
//实现字符串的匹配(即在文本串中寻找模式串子串)
class KMP {
	int* next; //next数组含义:next[i]记录前i字符构成的子串中最长公共前后缀,指示模式串与文本串不匹配时模式串下一个比较字符
public:

	int KMP_Match(string s1 = "", string s2 = " ")
	{
		int* next = new int[s2.length()];
		getNext(s2, next);
		int i = 0, j = 0; //i遍历文本串,j遍历模式串
		for (int i = 0; i < s1.length(); i++)
		{
			while (j > 0 && s1[i] != s2[j]) {
				j = next[j - 1];
			}
			if (s1[i] == s2[j]) j++;
			if (j == s2.length())  //匹配
			{
				return i + 1 - s2.length();
			}
		}
		return -1;
	};

	void getNext(string s,int* next)
	{
		//i:前缀尾,j:后缀尾,注意 i指示当前最长公共前后缀的长度!!!
		//初始化
		if (!next)  next = new int[s.length()];
		next[0] = 0;  //next数组第一个位置设为0
		int i = 0, j;
		for ( j = 1; j < s.length(); j++){
		
			 //前后缀不匹配,循环前缀尾取上一个next的值,直至前后缀匹配或前缀到头
				while(i>0&&s[i]!=s[j])
				i = next[i - 1];  
				//前后缀匹配
				if (s[i] == s[j])
					i++; //公共前后缀长度加一
			
			next[j]=i;//更新next数组
		}

	}
};
相关推荐
The_Ticker9 分钟前
CFD平台如何接入实时行情源
java·大数据·数据库·人工智能·算法·区块链·软件工程
Lenyiin42 分钟前
02.06、回文链表
数据结构·leetcode·链表
爪哇学长1 小时前
双指针算法详解:原理、应用场景及代码示例
java·数据结构·算法
爱摸鱼的孔乙己1 小时前
【数据结构】链表(leetcode)
c语言·数据结构·c++·链表·csdn
Dola_Pan1 小时前
C语言:数组转换指针的时机
c语言·开发语言·算法
繁依Fanyi1 小时前
简易安卓句分器实现
java·服务器·开发语言·算法·eclipse
烦躁的大鼻嘎1 小时前
模拟算法实例讲解:从理论到实践的编程之旅
数据结构·c++·算法·leetcode
C++忠实粉丝2 小时前
计算机网络socket编程(4)_TCP socket API 详解
网络·数据结构·c++·网络协议·tcp/ip·计算机网络·算法
祁思妙想2 小时前
10.《滑动窗口篇》---②长度最小的子数组(中等)
leetcode·哈希算法
用户37791362947552 小时前
【循环神经网络】只会Python,也能让AI写出周杰伦风格的歌词
人工智能·算法