关于“从第一字符串中删除第二个字符串中所有的字符”方法学习

本文介绍了一种高效的字符串处理算法,用于从一个字符串中删除另一个字符串包含的所有字符。通过使用哈希表来标记待删除字符,将时间复杂度降低到O(n),并提供了具体的C/C++代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这个算是比较经典的题目之一,之前在华为的笔试题目中也遇到过。具体题目忘记了,从网上找来了一个基本一致的题目进行学习,也针对网上现有的代码做一下简单的讨论。话不多说,我们便进入正题。

题目:输入两个字符串,从第一字符串中删除第二个字符串中所有的字符。例如,输入”They are students.””aeiou”,则删除之后的第一个字符串变成”Thy r stdnts.”

首先,一种简明的低效方法:

通过遍历,我们依次判定第一个字符串中是否存在第二个字符串中的第i个字符,如果存在,则删除该字符,因此该方法就删除而言的时间复杂度为O(n^2)。

显然,整个算法的时间复杂度还是较大的。

空间兑换时间的方法:

对于字符串,由于ASCII码的所有符号为256个(包括了拓展表,参见http://wenku.baidu.com/linkurl=RH03r9polKdSfErbTthsNKglrjkMW4ISjHo1unYB1XQva03p7C1_eSuzsLZX6fd1AhlYzRlq_ciHGG8I2g7lDUuZ_kOngUHxoMIV7KFyae3),那么,我们可以申请一个数组用来代表这256个字符是否存在于第二个字符串中,如果有,则标记为1,如果没有则标记为0.同理,我们通过查询,对应ASCII值号下,数组是否为1,来判定是否删除。汉字描述确实费劲,我们便看看实例:

第一步,

第二个字符串为“aeiou”,对应的ascii为97,101,105,111,117,也就是说,需要将数组hashTable[97],hashTable[101],hashTable[105],hashTable[111],hashTable[117]的值赋值为1,其他为0;

第二步,

依次查找第一个字符串”They are students.”如,第一个字符为‘T’,对应ASCII码为84,因此查看hashTable[84]的值,发现为0,因此不删除,同理,以此类推即可。最后时间复杂度为o(n).

字符串删除元素的一个好思路:

    代码里,关于删除字符串的方式个人觉得是很不错的。之前,遇到类似的问题,我的思路一般为,通过创建一个字符串,将不需要删除的字符填入这个字符串中,然后再进行字符串的拷贝。而代码中通过指针实现了类似的方案,并且不需要进行赋值字符串且减少了空间的浪费,具体操作便看代码吧。

完整的代码如下:


// 从str中,删除一个指定的字符
void deleteOneChar(char* str, char toBeDelete)
{
    if(str == NULL)  return;
    int length = strlen(str);
    char* p = str;
    // 遍历str,删除和toBeDelete相等的字符
    for(int i=0; str[i]!='\0'&&i<length; i++)
    {
        // 如果相等则用后面的元素进行覆盖
        if(str[i] == toBeDelete)
        {
                int j=i;
                for(; str[j]!='\0'&&j<length-1;j++)
                    str[j]=str[j+1];
                str[j]='\0';
        }
    }
    return;
}

// 使用第一种方法实现 复杂度O(n^2)
void deleteChars1(char* str,const char* chars)
{
    if(str==NULL)  return;
    if(chars == NULL) return;
    // 依次删除chars中的每一个元素
    for(int i=0; i<strlen(chars); i++)
        deleteOneChar(str,chars[i]);
    return;
}
// 使用第二种方法实现复杂度O(n)
void deleteChars2(char* pStrSource, const char* pStrDelete)  
{  
      if(NULL == pStrSource || NULL == pStrDelete)  
  
            return;  
  
      const unsigned int nTableSize = 256;  
      int hashTable[nTableSize];  
      memset(hashTable, 0, sizeof(hashTable));  
      const char* pTemp = pStrDelete;  
      while ('\0' != *pTemp)  
      {  
            hashTable[*pTemp] = 1;  
            ++ pTemp;  
      }  
      char* pSlow = pStrSource;  
      char* pFast = pStrSource;  
      while ('\0' != *pFast)  
      {  

            if(1 != hashTable[*pFast])  
            {  
                  *pSlow = *pFast;  
                  ++ pSlow;  
            }  
            ++pFast;  
      }  
      *pSlow = '\0';  
  
}  

int main()
{
    char* str = "they are students";
    char* p = (char*)malloc((strlen(str)+1)*sizeof(char));
    strcpy(p,str);
    const char*q = "aeiou";
    deleteChars2(p,q);
    cout<<p<<endl;


    free(p);
    p = NULL;

}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值