0
点赞
收藏
分享

微信扫一扫

string类型基础算法题详解

瑾谋 2022-03-12 阅读 94

目录

1.字符串最后一个单词的长度

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

3.仅仅反转字母

4.验证回文串

5.字符串相加


1.字符串最后一个单词的长度

【思路】:这道题找到最后一个单词也就是找到最后一个空格,可以用rfind反向迭代找到最后一个空格,算出最后一个单词的大小。如果只有一个单词没有空格的话那么直接输出这个单词的长度。

但是要注意的是,在单词与单词之间的间隔,是用空格来进行的,直接用cin>>s时候,如果输入像hello nowcoder这样的字符串,s仅识别第一个单词,空格之后的字符串被识别为下一个字符串,留在了缓冲区。所以不能用cin>>s来获取字符串。

想要将空格页识别成字符串

【方法一】:

    string s;
    //C写法
    char ch = getchar();//获取一个字符
	while (ch != '\n')//循环加入s来获取字符串,遇到\n就是换行停下来
	{
		s += ch;
		ch = getchar();
	}
	//getline(cin,s);

【方法2】:

    string s;
    //C++写法
	char ch = cin.get();
    while(ch!='\n')
    {
        s+=ch;
        ch=cin.get();
    }

【方法3】:

在C++的string类中,写入了一个成员方法getline,用来获取字符串的,参数1是输入流,参数2为要获取的字符串。其基本思想就是上面代码的体现。

string s;
getline(cin,s);
#include<iostream>
using namespace std;
#include <string>

int main()
{
    string s;
    getline(cin,s);
    size_t pos=s.rfind(' ');//获取从后向前数第一个空格位置
    
    if(pos!=string::npos)//当不等于npos(值为-1,也就代表没找到),找到了
    {
        string last=s.substr(pos+1,s.size()-(pos+1));//获取最后一个单词字符串
        cout<<last.size()<<endl;//输出字符串大小

        //cout<<s.size()-pos-1<<endl;//或者直接写这种直接算出大小
    }
    else
    {
        cout<<s.size()<<endl;
    }
    
    return 0;
}

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

【思路】:这道题如果让每个字符和字符串相比,那么时间复杂度是O(n^2),所以用另一种思路,设一个数组,遍历这个字符串,记录每个字符出现的次数,放入这个数组中。再次遍历整个字符串,这时相对应的字符有了自己的重复次数,当遇到第一个次数等于1的字符,返回这个字符的下标索引。

class Solution {
public:
    int firstUniqChar(string s) {
        //O(N)
        int CountArray[26]={0};

        //统计次数
        for(size_t i=0;i<s.size();i++)
        {
            CountArray[s[i]-'a']++;
        }

        //找到第一个出现一次的
        for(size_t j=0;j<s.size();j++)
        {
            if(CountArray[s[j]-'a']==1)
            {
                return j;
            }
        }
        return -1;

    }
};

3.仅仅反转字母

 【思路】:定义两个下标begin和end,一个指向第一个位置,一个指向最后一个位置。begin从前向后遍历,直到遇到字母,end从后向前遍历,直到遇到字母,二者交换。begin和end继续遍历,直到二者相遇(begin<end),不再遍历,返回这个字符串。

class Solution {
public:
    //判断是否是字符
    bool IsLetter(char ch)
    {
        if((ch >= 'A' && ch <= 'Z') || (ch>='a'&&ch<='z'))
        {
            return true;
        }
        return false;
    }

    string reverseOnlyLetters(string s) {
        //当遇到数字才翻转
        int begin=0;
        int end=s.size()-1;
        while(begin<end)
        {
            while(begin<end && !IsLetter(s[begin]))
            //这里还要判断一下begin<end,because如果这个字符串都不是字母,那么一直++下去会越界
            {
                ++begin;
            }
            while(begin<end && !IsLetter(s[end]))
            {
                --end;
            }
            swap(s[begin++],s[end--]);
        }
        return s;
    }
};

4.验证回文串

【思路】:判断是否是回文字符,定义两个下标,一个begin指向0位置,一个end指向最后一个字符,索引为s.size()-1,因为跟大小没有关系,所以可以把所有字母都转成小写或者都转成大写,再去比较。当begin遇到不是字母或数字,++begin,直到找到字母或数字;同理,当end遇到字母或数字停下,比较二者是否相等。如果不相等返回false,相等的话继续向下寻找,begin++,end--。直到begin不再小于end,搜索结束。

class Solution {
public:
    //判断是否为字母或数字
    bool isLetterOrNum(char ch)
    {
        if(ch>='a'&&ch<='z')
            return true;

        if(ch>='A' && ch<='Z')
            return true;
        if(ch>='0'&&ch<='9')
            return true;
        return false;
    }

   bool isPalindrome(string s) {
		int begin = 0, end = s.size() - 1;
		//全变小写
		 while(begin<s.size())
		 {
		     if(isLetterOrNum(s[begin]))
		     {
		         s[begin]=tolower(s[begin]);
		     }
			 ++begin;
		 }
		 begin = 0;

		while (begin<end)
		{
			while (begin<end && !isLetterOrNum(s[begin]))
			{
				++begin;
			}
			while (begin<end && !isLetterOrNum(s[end]))
			{
				--end;
			}

			 if(s[begin]!=s[end])
			 {
			     return false;
			 }
			begin++;
			end--;
		}
		return true;
	}
};

对于字母全部变小写,还可以这样写,运用范围for.

        for (auto& ch : s)
		{
			if (ch >= 'A'&&ch <= 'Z')//大写字母的ascii码比小写字母小32
				ch += 32;
		}

5.字符串相加

【思路】:

单位+单位+进位,从两个数的末尾开始遍历,个位的仅为是0,所以初始化的进位extra设为0。

当两个数有一个没遍历完就继续循环,当一个数A已经遍历完,而另一个数B没有遍历完,那么设A的当前位为0,那么就是0+单位+进位。

在全局定义一个空字符串,将每个相加位数都变成字符尾插到这个空字符串当中,然而这样得到的数字是反的,最后得到的正确数字,我们再将他反转。

当两个数都遍历完,跳出循环,如果最后一个进位是1,那么再在这个字符串尾插1,除此之外,直接得到反转字符串的结果。

class Solution {
public:
    string addStrings(string num1, string num2) {
        int end1=num1.size()-1;
        int end2=num2.size()-1;
        int extra=0;
        int retVal;
        string sVal;

        while(end1>=0 ||end2>=0)
        {
            int x1=0;
            if(end1>=0)
            {
             x1=num1[end1]-'0';
            end1--;
            }

            int x2=0;
            if(end2>=0)
            {
             x2=num2[end2]-'0';
            end2--;
            }
            else
            {
                x2=0;
            }
            
            retVal=x1+x2+extra;
            if(retVal>9)
            {
                retVal-=10;
                extra=1;
            }
            else
            {
                extra=0;
            }
            sVal.push_back(retVal+'0');
        }
        if(extra==1)
        {
            sVal+='1';
        }

        reverse(sVal.begin(),sVal.end());
        return sVal;
    }
};
举报

相关推荐

0 条评论