字符串问题常用解决方法

  • 哈希法
  • 基本思路
  • 题目“确认字符互异”
  • 解题思路
  • 解题代码
  • 题目“确定两串乱序同构”
  • 解题思路
  • 解题代码
  • 双指针
  • 题目“原串翻转”
  • 解题思路
  • 解题代码
  • 截断复制
  • 基本思路
  • 题目“空格替换”
  • 解题思路
  • 解题代码
  • 题目“字符串压缩”
  • 解题思路
  • 解题代码
  • 翻转子串
  • 解题思路
  • 解题代码


哈希法

基本思路

哈希法:哈希法在字符串类型题中,一般用于查重,查是否出现,建立数组元素与下标的关系,能够起到快速查找的作用,判断是否出现过。

题目“确认字符互异”

确认字符互异

Java 未知类型转字符串 未知字符串怎么解决_算法


解题思路

题干提醒了:
1、字符串中的字符都是ASCII字符(建立128大小映射)
2、这里不让使用额外的存储结构(自实现hash)
方法:ASCII字符共128个,建立128大小的bool数组记为bool hashchar[128]初始化为false,char类型可转为无符号整型,则能以字符为下标记为a,遍历iniString,如果第一次出现,则改为true,下次遇到同样的字符则返回。

解题代码

class Different {
public:
    bool checkDifferent(string iniString) {
        // write code here
        bool hashchar[128];
        memset(hashchar,0,sizeof(hashchar));
        for(char a:iniString){
            if(hashchar[a])//如果出现过返回
                return false;
            else hashchar[a]=true;//没出现过的字符登记
        }
        return true;
    }
};

Java 未知类型转字符串 未知字符串怎么解决_算法_02

题目“确定两串乱序同构”

确定两串乱序同构

Java 未知类型转字符串 未知字符串怎么解决_bc_03


解题思路

串A能否由串B字符重组得到?即串A的每一个字符都在串B中出现。且出现的次数一致。
方法
1、统计串A的每一个字符,再统计串B是否出现的一样多。
2、可建立128大小(ASCII表大小)的整型数组int charhash[128]初始化为0,遍历记录串A中的字符出现的次数即对每一个字符c++charhash[c]
3、再遍历一次B串,对每一个字符c--charhash[c],如果charhash[c]为0则返回错误,说明不同构。

解题代码

class Same {
public:
    bool checkSam(string stringA, string stringB) {
        // write code here
        int charhash[128];
        memset(charhash,0,sizeof(charhash));
        for(auto &c:stringA){
            charhash[c]++;
        }
        for(auto &c:stringB){
            if(!charhash[c])//为0的情况
                return false;
            else --charhash[c];
        }
        return true;
            
    }
};

双指针

思路:双指针法一般用于字符原地操作,如翻转,原地快排;滑动窗口;维护最值序列。

题目“原串翻转”

原串翻转

Java 未知类型转字符串 未知字符串怎么解决_字符串_04

解题思路

1、在不使用额外数据结构和储存空间的情况下(可以使用单个过程变量)

(原地调整:高位低位互换,如果不要求原地的话可以用个栈就解决了)

2、翻转一个给定的字符串
方法:
1、取字符串高位记为high初始化为iniString.size()-1,低位记为low初始化为0,过程变量temp初始化为iniString [low],
2、每次high low交换后,--high;++low;temp赋新的low值

解题代码

class Reverse {
public:
    string reverseString(string iniString) {
        // write code here
        if(iniString.empty())return iniString;
        
        int low=0,high=iniString.size()-1;
        char temp=iniString[0]; 
        while(low<high){
            iniString[low]=iniString[high];
            iniString[high]=temp;
            --high;
            ++low;
            temp=iniString[low];
        }
        return iniString;
    }
};

Java 未知类型转字符串 未知字符串怎么解决_算法_05

截断复制

基本思路

截断复制也谈不上是什么方法,不过是按照题意修改字符串,比如空格替换,字符压缩等等题目,把需要找到需要修改的位置执行题意要求的操作罢了,如果说有什么要记的,那应该是字符串常用函数吧。比如查找 字符位置find(),返回字串substr(),追加字符。string常用函数

题目“空格替换”

Java 未知类型转字符串 未知字符串怎么解决_bc_06


 

解题思路

找到每一个空格的位置,获得空格前面的子串,追加到结果字符串,再追加%20
重置字符串iniString为子串。

解题代码

class Replacement {
public:
    string replaceSpace(string iniString, int length) {
        // write code here
        int pos=-1;
         string ret;
        while((pos=iniString.find(' '))!=std::string::npos){
            ret+=iniString.substr(0,pos);
            ret+="%20";
            iniString=iniString.substr(pos+1);
        }
         ret+=iniString;
        return ret;
    }
};

题目“字符串压缩”

Java 未知类型转字符串 未知字符串怎么解决_bc_07


解题思路

添加个计数器,计算连续相同的字符长度,最后再比较

解题代码

class Zipper {
public:
    string zipString(string iniString) {
        string res;
        int size=iniString.size();
        for(int i=0;i<size;++i){
            int count=1;
            while(i+1<size&&iniString[i]==iniString[i+1]){
                ++i;
                ++count;
            }
            res+=iniString[i];
            res+=to_string(count);
        }
        if(res.size()>size)return iniString;
        else return res;
    }  
};

翻转子串

Java 未知类型转字符串 未知字符串怎么解决_bc_08


解题思路

1、理解题意:
这题不是普通的完全倒序,而是循环移位,如字符串 s1=“abcd”;s2可能为:循环移位多个结果:abcd->bcda->cdab->dabc;这里的4个字符串都是匹配的。
2、解决方案:如果把原来被移走的字符留下来那么有:
abcd->abcda->abcdab->abcdabc->abcdabcd。
我们可以看见原来最后的结果是s1的两倍。且包括了 1 中的所有方案。

解题代码

class ReverseEqual {
public:
    bool checkReverseEqual(string s1, string s2) {
        // write code here
        string s3=s1+s1;
        if(s3.find(s2)!=std::string::npos){
            return true;
        }
        else return false; 
    }
};