常见的字符串面试问题(二)

本文提供了一系列实用的字符串操作函数实现,包括查找子串、字符串翻转、寻找最长公共子串等,帮助开发者掌握基本的字符串处理技能。

1)写出在母串中查找子串出现次数的代码.

int count1(char* str,char* s)

{

    char* s1;

    char* s2;

    int count = 0;

    while(*str!='\0')

    {

        s1 = str;

        s2 = s;

        while(*s2 == *s1&&(*s2!='\0')&&(*s1!='\0'))

        {

            s2++;

            s1++;

        }

        if(*s2 == '\0')

            count++;

        str++;

    }

    return count;

}

2)查找第一个匹配子串位置,如果返回的是s1长度len1表示没有找到

size_t find(char* s1,char* s2)

    {

        size_t i=0;

         size_t len1 = strlen(s1)

        size_t len2 = strlen(s2);

        if(len1-len2<0) return len1;

        for(;i<len1-len2;i++)

        {

            size_t m = i;

            for(size_t j=0;j<len2;j++)

            {

                if(s1[m]!=s2[j])

                    break;

                m++;

            }

            if(j==len)

                break;

        }

        return i<len1-len2?i:len1;

    }

3)实现strcpy函数

char *strcpy(char *destination, const char *source)

{

    assert(destination!=NULL&&source!=NULL);

    char* target = destinaton;

    while(*destinaton++=*source++);

    return target ;

}

出现次数相当频繁

4)实现strcmp函数

int strcmp11(char* l,char* r)

{

    assert(l!=0&&r!=0);

    while(*l == *r &&*l != '\0') l++,r++;

    if(*l > *r)

        return 1;

    else if(*l == *r)

        return 0;

    return -1;

}

5) 实现字符串翻转

void reserve(char* str)

{

    assert(str != NULL);

    char * p1 = str;

    char * p2 = str-1;

    while(*++p2);         //一般要求不能使用strlen

    p2 -= 1;

    while(p1<p2)

    {

        char c = *p1;

        *p1++ = *p2;

        *p2-- = c;

   }

}

6)、用指针的方法,将字符串“ABCD1234efgh”前后对调显示

//不要用strlen求字符串长度,这样就没分了

代码如下:

    char str123[] = "ABCD1234efgh";

    char * p1 = str123;

    char * p2 = str123-1;

    while(*++p2);

    p2 -= 1;

    while(p1<p2)

    {

        char c = *p1;

        *p1++ = *p2;

        *p2-- = c;

    }

7) 给定字符串A和B,输出A和B中的最大公共子串。比如A="aocdfe" B="pmcdfa" 则输出"cdf"

#i nclude<stdio.h>

#i nclude<stdlib.h>

#i nclude<string.h>

char *commanstring(char shortstring[], char longstring[])

{

    int i, j;

    char *substring=malloc(256);

    if(strstr(longstring, shortstring)!=NULL)              //如果……,那么返回shortstring

        return shortstring;

    for(i=strlen(shortstring)-1;i>0; i--)                 //否则,开始循环计算

    {

        for(j=0; j<=strlen(shortstring)-i; j++)

        {

            memcpy(substring, &shortstring[j], i);

            substring[i]='\0';

            if(strstr(longstring, substring)!=NULL)

            return substring;

        }

    }

    return NULL;

}

main()

{

    char *str1=malloc(256);

    char *str2=malloc(256);

    char *comman=NULL;

    gets(str1);

    gets(str2);

    if(strlen(str1)>strlen(str2))                         //将短的字符串放前面

        comman=commanstring(str2, str1);

    else

        comman=commanstring(str1, str2);

    printf("the longest comman string is: %s\n", comman);

}

8) 判断一个字符串是不是回文

int IsReverseStr(char *str)

{

    int i,j;

    int found=1;

    if(str==NULL)

        return -1;

    char* p = str-1;

    while(*++p!= '\0');

    --p;

    while(*str==*p&&str<p) str++,p--;

    if(str < p)

        found = 0;

    return found;

}

9)写函数完成内存的拷贝

void* memcpy( void *dst, const void *src, unsigned int len )

{

    register char *d;

    register char *s;

    if (len == 0)

        return dst;

    if ( dst > src )   //考虑覆盖情况

    {

        d = (char *)dst + len - 1;

        s = (char *)src + len - 1;

        while ( len >= 4 )   //循环展开,提高执行效率

        {

            *d-- = *s--;

            *d-- = *s--;

            *d-- = *s--;

            *d-- = *s--;

            len -= 4;

        }

        while ( len-- )

        {

            *d-- = *s--;

        }

    }

    else if ( dst < src )

    {

        d = (char *)dst;

        s = (char *)src;

        while ( len >= 4 )

        {

            *d++ = *s++;

            *d++ = *s++;

            *d++ = *s++;

            *d++ = *s++;

            len -= 4;

        }

        while ( len-- )

        {

            *d++ = *s++;

        }

    }

    return dst;

}

10)写一个函数,它的原形是int continumax(char *outputstr,char *intputstr)

功能:

在字符串中找出连续最长的数字串,并把这个串的长度返回,并把这个最长数字串付给其中一个函数参数outputstr所指内存。例如:"abcd12345ed125ss123456789"的首地址传给intputstr后,函数将返回

9,outputstr所指的值为123456789

int continumax(char *outputstr, char *inputstr)

{

    char *in = inputstr, *out = outputstr, *temp, *final;

    int count = 0, maxlen = 0;

    while( *in != '\0' )

    {

        if( *in > 47 && *in < 58 )

        {

            for(temp = in; *in > 47 && *in < 58 ; in++ )

            count++;

        }

    else

    in++;

    if( maxlen < count )

    {

        maxlen = count;

        count = 0;

        final = temp;

    }

    }

    for(int i = 0; i < maxlen; i++)

    {

        *out = *final;

        out++;

        final++;

    }

    *out = '\0';

    return maxlen;

}

11) 编写一个 C 函数,该函数在一个字符串中找到可能的最长的子字符串,且该字符串是由同一字符组成的。

char * search(char *cpSource, char ch)

{

         char *cpTemp=NULL, *cpDest=NULL;

         int iTemp, iCount=0;

         while(*cpSource)

         {

                 if(*cpSource == ch)

                 {

                          iTemp = 0;

                          cpTemp = cpSource;

                          while(*cpSource == ch)

                                   ++iTemp, ++cpSource;

                          if(iTemp > iCount)

                                iCount = iTemp, cpDest = cpTemp;

                      if(!*cpSource)

                            break;

                 }

                 ++cpSource;

     }

     return cpDest;

    

<think>嗯,用户想了解Python中常见字符串面试题。首先,我得回忆一下常见的考点。字符串在Python里是基础但重要的类型,面试题通常涉及基本操作、特性以及算法应用。 首先想到的是字符串的不可变性。这个点经常被考到,比如修改字符串中的某个字符,或者拼接字符串的效率问题。需要解释为什么字符串不可变,以及这样设计的优缺点。例如,使用加号拼接字符串和join方法的区别,可能涉及到内存和性能的问题。 然后是反转字符串,这应该是一个常见的题目。可能有多种方法,比如切片[::-1],或者使用循环逆序拼接。还有递归的方法,不过可能效率不高。此外,要考虑Unicode字符的情况,比如处理包含多字节字符的字符串,比如emoji或者中文,这时候反转会不会出问题? 接下来是字符串的常用方法,比如split()、strip()、replace()、find()、startswith()、endswith()等。这些方法在面试中可能会被问到具体用法或者应用场景。比如如何去除字符串两边的空格,如何分割字符串,替换子串等等。 字符串的格式化也是一个考点,包括旧式的%格式化,str.format()方法,以及Python3.6引入的f-string。需要比较它们的优缺点,比如f-string的可读性和执行效率更高。 检查字符串是否由数字构成,这个问题可能涉及到isdigit()方法,但也要注意全角数字或者其他语言中的数字字符的情况,这时候可能需要更全面的判断方法,比如尝试转换成float或者int,捕获异常来判断。 回文串的判断也是一个经典题目。回文是指正读反读都一样的字符串,比如"level"。常见的方法是将字符串反转后比较,或者用双指针法从两端向中间检查。需要注意大小写的处理,以及是否忽略空格和标点符号,不同的题目要求可能不同。 统计字符出现次数,可以用字典或者collections模块的Counter类。比如统计每个字符出现的次数,或者找出出现最多的字符。这可能需要遍历字符串,然后使用哈希表来记录频率。 字符串的排列组合问题,比如找出所有可能的排列,或者检查两个字符串是否为彼此的排列(即字符相同但顺序不同)。这可能涉及到排序后比较,或者用哈希表统计各字符的出现次数是否一致。 子串查找问题,比如实现类似str.find()的功能,或者KMP算法解决高效查找。不过在实际面试中,可能更关注暴力解法或者对内置方法的了解,以及时间复杂度分析。 字符串的编码问题,比如ASCII、Unicode、UTF-8的区别,如何处理中文字符,编码和解码的方法。可能还会问到字符串在Python2和Python3中的区别,比如Python3的str是Unicode,而bytes是字节序列。 另外,内存管理方面的问题,比如字符串驻留(interning),小字符串的缓存机制。例如,a = 'hello'和b = 'hello'是否指向同一个对象,而大字符串可能不会。这涉及到Python的优化机制。 还有,字符串和列表的转换,比如将字符串转换为列表进行修改后再转回字符串。例如,处理不可变字符串时,可能需要先转成列表,修改特定位置字符,再join成字符串。 可能还有一些算法题,比如最长不重复子串、最长回文子串、字符串转换整数(atoi)等。这些题目需要更复杂的逻辑和算法设计,比如滑动窗口、动态规划等。 需要分门别类,把这些知识点整理出来,用清晰的例子说明。比如反转字符串,给出不同的实现方法,比较它们的优缺点。对于字符串方法,举几个常用的例子,说明应用场景。在检查回文时,指出可能的陷阱,比如大小写和空格的处理。 还要注意,Python中的字符串是不可变的,所以每次操作都会生成新的字符串对象,这在涉及大量字符串拼接时会影响性能,这时候应该使用join方法而不是多次加号拼接。 可能还需要提到正则表达式的应用,比如用re模块进行复杂的字符串匹配和替换,这在处理复杂模式时非常有用,比如验证电子邮件格式、提取URL等。 最后,总结常见面试题类型,帮助用户系统地复习字符串相关的知识点,并给出练习的建议,比如刷LeetCode上的相关题目,或者手动实现一些字符串操作函数来加深理解。</think>以下是一些Python中常见字符串相关面试题及解析,按知识点分类整理: --- ### 一、基础操作与特性 1. **字符串不可变性** Q: 为什么说Python字符串是不可变的? A: 字符串对象创建后无法修改,任何操作(如拼接、替换)都会生成新对象。 ```python s = "hello" s[0] = 'H' # 报错:TypeError ``` 2. **拼接效率** Q: `s1 + s2` 和 `"".join([s1, s2])` 哪个更高效? A: `join()` 更高效,因为`+`会反复创建新对象,而`join()`一次性分配内存。 --- ### 、反转字符串 1. **切片法** ```python s = "hello" reversed_s = s[::-1] # "olleh" ``` 2. **递归法** ```python def reverse_str(s): return reverse_str(s[1:]) + s[0] if s else "" ``` 3. **Unicode字符处理** 注意多字节字符(如emoji)的反转可能出错,需确保正确处理Unicode。 --- ### 三、字符串方法应用 1. **常用方法** ```python " abc ".strip() # "abc" "a,b,c".split(",") # ["a", "b", "c"] "hello".replace("l", "x") # "hexxo" ``` 2. **格式化方法** ```python name = "Alice" f_str = f"Hello {name}" # f-string(推荐) ``` --- ### 四、算法问题 1. **回文判断** ```python def is_palindrome(s): s = s.lower().replace(" ", "") return s == s[::-1] ``` 2. **最长不重复子串** **滑动窗口法**: ```python def length_of_longest_substring(s): char_map = {} left = max_len = 0 for right, c in enumerate(s): if c in char_map and char_map[c] >= left: left = char_map[c] + 1 char_map[c] = right max_len = max(max_len, right - left + 1) return max_len ``` --- ### 五、编码与内存 1. **编码问题** ```python s = "你好" bytes_s = s.encode("utf-8") # b'\xe4\xbd\xa0\xe5\xa5\xbd' ``` 2. **字符串驻留(Interning)** Python会缓存小字符串(如单单词),`a = "hello"; b = "hello"`,`a is b` 返回`True`。 --- ### 六、其他高频问题 1. **检查字符串是否为数字** ```python def is_number(s): try: float(s) return True except ValueError: return False ``` 2. **统计字符频率** ```python from collections import Counter s = "abracadabra" counter = Counter(s) print(counter) # Counter({'a': 5, 'b': 2, 'r': 2, 'c': 1, 'd': 1}) ``` --- ### 练习建议 - 刷题平台:LeetCode(如题目:反转字符串、有效括号、字符串转换整数等)。 - 手动实现:`split()`、`strip()`等基础方法,加深理解底层逻辑。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值