CTCI系列--1.1 判断一个字符串中的字符是否唯一(C语言)

本文介绍了一种不使用额外数据结构判断字符串中字符是否唯一的算法。通过定义一个特定大小的数组来跟踪字符出现的状态,实现了高效的判断。并给出了两种实现方式及其测试代码。

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

原题:

Implement an algorithm to determine if a string has all unique characters.What if you cannot use additional data structures?

实现一个算法,判断一个字符串中的字符是否是唯一的。不能够使用额外的数据结构。


首先得确定构成字符串的字符集有多大?是ASCII字符,还是只是26个字母?根据不同情况,我们的解决方案可能不同。

下面我们以ASCII字符为例,ASCII码字符可以使用一个字节来表示,有效取值范围为0~127,总共128个字符。
解题思路为,定义一个128字节大小char型数组,数组初始化为0,。遍历字符串中的字符,当我们定义的数组中该字符对应位置为1则代表该字符在字符串中已出现过,即该字符串中的字符不是唯一的;否则将数据中该字符对应位置置1。完整遍历一遍字符串,知道到达字符串末尾(‘\0’)。

int check_uniq(char *str)
{
    char flag[128];
    int ret = 0;
    memset(flag, 0, sizeof(flag));
    while (*str++!= '\0')
    {
        if (flag[*str])
        {
            ret = 1; //有重复
            break;
        }
        else
        {
            flag[*str] = 1;
        }
    }
    return ret;
}

该算法时间复杂度为O(n)。算法中标志数组使用了128Byte,我们还可以进一步减少空间占用到原来的1/8。即每个ASCII码字符的出现状况使用一个bit位来指示。算法如下:

int check_uniq2(char *str)
{
    int flag[4];
    int ret = 0;
    memset(flag, 0, sizeof(flag));
    while (*str++ != '\0')
    {
        if (flag[*str/32] & 1<<(*str%32))
        {
            ret = 1; //有重复
            break;
        }
        else
        {
            flag[*str / 32] |= 1 << (*str % 32);
        }
    }
    return ret;
}

测试代码如下:

int main(void)
{
    char buf[100];
    while (1)
    {
        memset(buf, 0, sizeof(buf));
        printf("please input string:");
        scanf("%s", buf);
        if (check_uniq2(buf))
        {
            printf("not uniq !\n");
        }
        else
        {
            printf("is uniq !\n");
        }
    }
    return 0;
}

运行结果:

运行结果


文章转载自我的个人博客
本文固定链接为:http://linuxue.com/archives/13

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值