(0001)删除字符串中的公共字符

(0001)删除字符串中的公共字符

题目: 输入两个字符串, 从第一字符串(下文称为x)中删除第二个字符串(下文简称为y)中所有的字符. 例如, 输入They are students.aeiou, 则删除之后的第一个字符串变成Thy r stdnts.

解题思路

最简单的思路

两层循环遍历, 每遍历到字符串 y 中的一个字符, 就在字符串 x 中找到相同的字符, 找到之后删除它,并将字符串 x 后面的字符整体向前移动1位。所以这个过程的时间复杂度是O(n³).

优化 - 解决顺序存储结构中删除后整体移动的问题

删除一个字符的另一个思路是: 不是某个指定的字符就保留, 按照这种思维方式, 可以将需要保留的字符覆盖在原来的字符串上, 此时需要两个标记变量(或者说指针), 一个用于控制字符串 x 的整体遍历过程,一个记录要覆盖的位置, 这样的话,我们就能避免每一次删除后的整体平移,时间复杂度优化为O(n²), 如下图所示.

在这里插入图片描述


优化 - 引入hash表, 避免双层遍历
  1. O(n²)的时间复杂度是由遍历两个字符串产生的,引入hash表能够避免循环嵌套的问题,我采用的方式是对字符串 y, 建立一个hash表, 在字符串 y 中出现的字符, 在hash表中的值为1, 反之为0.
  2. 参考标点符号和字母的ASCII码值, hash范围选成256就足够了.

关于选用hash表的方式: 用一个O(256)的空间复杂度,将时间复杂度从O(n^2)将为O(n),如果n很大的话,这个替换是值得的。

show the code
#include "iostream"    

using namespace std;
void  DeleteChar(char arr1[], char arr2[]);

int main()
{   
  char str1[] = "They are students.";
  char str2[] = "aeiou";
  cout<<str1<<endl;
  DeleteChar(str1, str2);
  cout<<str1<<endl;
  getchar();
  return 0;
}

void  DeleteChar(char *arr1, char *arr2)
{
    if (arr1 == NULL && arr2 == NULL) return;
    // 创建hash表
    int hash_table[256] = { 0 };
    char *p1 = arr1;
    char *p2 = arr2;
    int index =0;
    // 遍历字符串y
    while(*p2 != '\0')
    {
        hash_table[(int)*p2] = 1;
        p2++;
    }
    // 遍历字符串x
    while (*p1 != '\0')
    {
        // 该字符不需要删除
        if( 0 == hash_table[(int)*p1] )
        {
            arr1[index]= *p1;
            index++;
        }
        p1++;
    }
    arr1[index]='\0';
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

依旧风轻

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值