初级算法-字符串

文章目录

      • 字符串:
        • 反转字符串
          • 题意:
          • 解:
          • 代码:
        • 整数反转
          • 题意:
          • 解:
          • 代码:
        • 字符串中的第一个唯一字符
          • 题意:
          • 解:
          • 代码:
        • 有效的字母异位词
          • 题意:
          • 解:
          • 代码:
        • 验证回文串
          • 题意:
          • 解:
          • 代码:
        • 字符串转换整数 (atoi)
          • 题意:
          • 解:
          • 代码:
        • 实现 strStr()
          • 题意:
          • 解:
          • 代码:
        • 外观数列
          • 题意:
          • 解:
          • 代码:
        • 最长公共前缀
          • 题意:
          • 解:
          • 代码:

字符串:

反转字符串

题意:

如题,要求原地算法

解:

下标变换或者函数reverse

代码:
#include
#include
#include
using namespace std;
/*
void reverseString(vector& s)
{
    int lg=s.size();
    for(int i=0;i& s)
{
    reverse(s.begin(),s.end());
}
int main()
{
    vector chars;char ch;
    while(cin>>ch)
    {
        chars.push_back(ch);
    }
    reverseString(chars);
    for(auto &achar:chars) cout<

整数反转

题意:

要求反转一个32位整数,如果溢出返回0,机器不允许使用64整数

解:

由于不允许64整数那么就用unsigned或者string存储,毕竟是字符串题而且方便翻转

注意点:

1、力扣提供函数为reverse,使用标准库函数需要添加std::(DEV跑的时候我没加CE了)

2、String2Int函数内 ans=10*ans+(s[i]-'0');不能使用 ans=10*ans+s[i]-'0';优先级导致溢出

3、字符串比较溢出的时候需要确认长度,详见字符串比较方式(从头到尾的字典序比较)

代码:
#include
using namespace std;
int String2Int(string s)
{
    int lg=s.length(),i=0,ans=0;
    if(s[0]=='-') i++;
    for(;iMIN_INT) return 0;
    }
    else
    {
        std::reverse(s.begin(),s.end());
        if(s.length()==MAX_INT.length() && s>MAX_INT) return 0;
    }
    int ans=String2Int(s);
    return ans;
}
int main()
{
    int temp;cin>>temp;
    int ans=reverse(temp);
    cout<

字符串中的第一个唯一字符

题意:

如题,第一个唯一存在的字符

解:

由于不允许64整数那么就用unsigned或者string存储,毕竟是字符串题而且方便翻转

用点简单的,index记录出现的下标,由于下标>=0所以特设-1为不存在(还没遇见),-2为出现超过一次

全都是小写字符可以直接转下标去访问数组

代码:
#include
using namespace std;
int firstUniqChar(string s)
{
    int index[26],lg=s.length(),ans=INT_MAX;
    memset(index,-1,sizeof index);
    
    for(int i=0;i=0) index[num]=-2;
    }
    for(int i=0;i<26;i++)
    {
        if(index[i]>=0) ans=min(ans,index[i]);
    }
    return (ans==INT_MAX?-1:ans);
}
int main()
{
    string s;cin>>s;
    int ans=firstUniqChar(s);
    cout<

有效的字母异位词

题意:

判断两个字符串是否拥有相同种数的字母,每种字母数量是否相同

解:

记个数

代码:
#include
using namespace std;
bool isAnagram(string s, string t)
{
    int lgs=s.length(),lgt=t.length();
    if(lgs!=lgt) return false;
    vectornums(26);
    for(auto ch:s) nums[(ch-'a')]++;
    for(auto ch:t) nums[(ch-'a')]--;
    for(auto num:nums) if(num!=0) return false;
    return true;
}
int main()
{
    string s,t;cin>>s>>t;
    bool ans=isAnagram(s,t);
    cout<

验证回文串

题意:

判断一个字符串移除所有非字母数字,将大写字母变成小写字母后是否是一个回文串

解:

双指针,字符处理

代码:
#include
using namespace std;
bool check(char a)
{
    if((a>='0' && a<='9')||(a>='a' && a<='z')||(a>='A' && a<='Z')) return true;
    return false;
}
bool isPalindrome(string s)
{
    int lg=s.length();
    for(int i=0;i='A' && s[i]<='Z') s[i]=s[i]-'A'+'a';
    for(int l=0,r=lg-1;l=0 && !check(s[r])) r--;
        if(r<0||l>=lg) break;
        //cout<

字符串转换整数 (atoi)

题意:

如题,具体规则不写了

解:

状态机获取字符串,去除前缀零和对只有符号的字符串补零,字符串比较防止溢出

我这个写法虽然繁琐了点但是不需要用到LongLong,虽然如官方题解一样可以通过INT_MAX 除以 10 进行比较防止移除,但是还要考虑加法溢出,不如直接用字符串比较

代码:
#include
#include
#include
using namespace std;
int String2Int(string s)
{
    int lg=s.length(),i=0,ans=0;
    if(s[0]=='-') i++;
    for(;i=2 && s[1]=='0') s.erase(1,1);
        if(s.size()==1) s.push_back('0'); 
    }
    else
    {
        while(s.size()>=1 && (s[0]=='+'||s[0]=='0')) s.erase(0,1);
        if(s.empty()) s.push_back('0'); 
    }
}
int myAtoi(string s)
{
    string temp,num;
    int ans=0,step=0;
    for(auto &ch:s)
    {
        if(step==0)//阶段0
        {
            if(ch==' ') continue;
            else if(ch=='+'||ch=='-'|| (ch>='0'&&ch<='9') )
            {
                step=1;
                temp.push_back(ch);
            }
            else break;
        }
        else if(step==1 && (ch>='0'&&ch<='9') )//阶段1
        {
            temp.push_back(ch);
        }
        else break;
    }
    solve(temp);
    if(temp[0]=='-')//负数
    {
        string MIN_INT=to_string(INT_MIN);
        if(temp.length()

实现 strStr()

题意:

在s1中找s2的最小下标,找不到返回-1

解:

经典的字符串匹配,暴力和KMP,小小写了一下KMP,好久没用了

代码:
#include
using namespace std;
void get_next(const string &needle,vector &next)
{
    int m1=1,m2=0;//m1表示主串位置,m2表示已经匹配的字符数量 
    while(m10 && needle[m1]!=needle[m2]) m2=next[m2];
        if(needle[m1]==needle[m2]) m2++;
        next[++m1]=m2;
    }
    //for(auto n:next) cout<next(lg2+1);//next存储匹配i失败时跳转至next[i-1] 
    get_next(needle,next);
    int m1=0,m2=0;//m1表示主串位置,m2表示已经匹配的字符数量 
    while(m1>s1>>s2;
    int ans=strStr(s1,s2);
    cout<

外观数列

题意:

解:

简单字符串处理+递归/迭代

代码:
#include
using namespace std;
string solve(const string n)
{
    cout<>n;
    string ans=countAndSay(n);
    cout<

最长公共前缀

题意:

如题

解:

先排序可以把最短的放最前面,这样最长前缀的长度一定小于等于这个最短的字符串,其他的暴力

代码:
#include
using namespace std;
string solve(const string &s1,const string &s2)
{
    string ans;
    int lg=min(s1.size(),s2.size());
    for(int i=0;i& strs)
{
    sort(strs.begin(),strs.end());
    int lg=strs.size();
    if(lg==1) return strs[0];
    string ans=solve(strs[0],strs[1]);
    for(int i=2;istrs;string str;
    while(cin>>str)
    {
        strs.push_back(str);
    }
    string ans=longestCommonPrefix(strs);
    cout<

你可能感兴趣的:(力扣每日一题,算法,c++,leetcode)