两个字符串A、B,从A中剔除存在于B中的字符

//两个字符串A、B,从A中剔除存在于B中的字符。
//比如A = “hello world”, B = “her”,
//那么剔除之后A变为 “llo wold”

//ANSCII码总共256个字符。
//暴力思路,每删除A中一个元素都将A后面的所有元素前移,
//若A中n个字符,时间复杂度是O(n^2)。
//可以这样,设置两个指向A的快慢指针,时间复杂度就降低到了O(n)。逻辑是:
//若A中命中了B的字符,要删掉A中此字符,此时慢指针不动,
//快指针移动到下个字符,这样就直接跳过要删字符
//若A中没有命中B的字符,不删,此时快指针指向的字符赋值给慢指针指向内存空间,
//然后,快慢指针都往后移动

#include"stdio.h"
#include"string.h"
#include"assert.h"
typedef unsigned char u8;
u8 hash_table[256] = { 0 };
void initial_hash(const char* pb)
{
    assert(pb!=NULL);
    while (*pb != '\0')
    {
        hash_table[*(pb++)]++;//累计字符串B中每个ANSCII码出现次数
    }
}
void eliminate(char* pa)
{
    assert(pa!=NULL);
    char* pfast;
    char* pslow;
    pfast = pa;
    pslow = pa;
    while (*pfast !='\0')
    {
        if (hash_table[*pfast] == 0)
        {//A中没有命中B的字符,不删,此时快指针指向的字符
         //赋值给慢指针指向的内存空间(即A的内存),
         //然后,快慢指针都往后移动
            *pslow = *pfast;
            pfast++;
            pslow++;
        }
        else
        {//A中命中了B的字符,要删掉A中此字符,此时慢指针不动,
         //快指针移动到下个字符,这样就直接跳过要删字符
            pfast++;
        }
    }
    *pslow = '\0';//最后记得给慢指针指向字符串加终止符
}
void main()
{
    char a[] = "hello world";
    char b[] = "her";
    initial_hash(b);
    for (int i = 0; i < 256; i++)
    {
        printf("%d ",hash_table[i]);
    }
    printf("\n");
    eliminate(a);
    printf("%s",a);
}

猜你喜欢

转载自blog.csdn.net/acttell/article/details/73077717