zoukankan      html  css  js  c++  java
  • 实现一些字符串操作标准库函数、解决一些字符串问题

     
    一、实现字符串操作标准库函数

    (1)、strcpy、strncpy、memmove、memcpy、strlen、strncat 的实现

     C++ Code 
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
     
    // The  strcpy()  function  copies  the  string  pointed to by src, including the terminating null byte (''), to the buffer
    // pointed to by dest.  The strings may not overlap, and the destination string dest must be  large  enough  to  receive  thecopy.
    char *strcpy( char *dest,  const  char *src)
    {
        assert((src !=  NULL) && (dest !=  NULL));
        size_t i;
         for (i =  0; src[i] !=  ''; i++)
            dest[i] = src[i];
        dest[i] =  '';
         return dest;
    }

    // The strncpy() function is similar, except that at most n bytes of src are copied.  Warning: If there is no null byte among the first n bytes of src,
    // the string placed in dest will not be null-terminated. If the length of src is less than n, strncpy() pads the remainder of dest with null bytes.
    char *strncpy( char *dest,  const  char *src, size_t n)
    {
        assert((src !=  NULL) && (dest !=  NULL));
        size_t i;
         for (i =  0; i < n && src[i] !=  ''; i++)
            dest[i] = src[i];
         for (; i < n; i++)
            dest[i] =  '';
         return dest;
    }

    /* 借助于一个临时缓冲区temp ,即使src 和dest 所指的内存区间有重叠也能正确拷贝。*/
    void *memmove( void *dest,  const  void *src, size_t n)
    {
        assert((src !=  NULL) && (dest !=  NULL));
         char temp[n];
         int i;
         char *d = dest;
         const  char *s = src;

         for (i =  0; i < n; i++)
            temp[i] = s[i];
         for (i =  0; i < n; i++)
            d[i] = temp[i];

         return dest;
    }

    /* 在32位的x86平台上,每次拷贝1个字节需要一条指令,每次拷贝4个字节也只需要一条指
     * 令,memcpy函数的实现尽可能4个字节4个字节地拷贝 */

    void *memcpy( void *dest,  const  void *src, size_t n)
    {
        assert((src !=  NULL) && (dest !=  NULL));
         char *d = dest;
         const  char *s = src;
         int *di;
         const  int *si;
         int r = n %  4;
         while (r--)
            *d++ = *s++;
        di = ( int *)d;
        si = ( const  int *)s;
        n /=  4;
         while (n--)
            *di++ = *si++;
         return dest;
    }



     C++ Code 
    1
    2
    3
    4
    5
    6
    7
     
    size_t strlen( const  char *p)
    {
        assert(p !=   NULL);
        size_t size =  0;
         while (*p++ !=  '')
            ++size;
         return size;
    }

     C++ Code 
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    char *strncat( char *dest,  const  char *src, size_t n)
    {
        size_t dest_len = strlen(dest);
        size_t i;

         for (i =  0 ; i < n && src[i] !=  '' ; i++)
            dest[dest_len + i] = src[i];
        dest[dest_len + i] =  '';

         return dest;
    }

    二、解决字符串问题

    (1)、将单词之间出现一个或多个连续的空白字符都压缩为1个。

     C++ Code 
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
     
    //编一个函数,输入一个字符串,要求做一个新字符串,把其中所有的一个或多个连续的空白字符都压缩为一个空格。这里所说的空白包括空格、' '、' '、' '。
    char *shrink_space( char *dest,  const  char *src, size_t n)
    {
        assert((src !=  NULL) && (dest !=  NULL));
        size_t i, j;

        dest[ 0] = src[ 0];

         for (i =  1, j =  1; src[i] !=  ''; i++, j++)
        {
             if (src[i] ==  ' ' || src[i] ==  ' '
                    || src[i] ==  ' ' || src[i] ==  ' ')

                 if (src[i -  1] !=  ' ' && src[i -  1] !=  ' '
                        && src[i -  1] !=  ' ' && src[i -  1] !=  ' ')

                    dest[j] =  ' ';
                 else
                    j--;
             else
                dest[j] = src[i];
        }
        dest[j] =  '';

         return dest;
    }

    (2)、 解析 URL  中的路径和查询字符串。? 号后面是查询字符串,  “key=value” 形式的键值对 组成,以 & 隔开。

     C++ Code 
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
     
    /*************************************************************************
        > File Name: find_url_token.c
        > Author: Simba
        > Mail: dameng34@163.com
        > Created Time: Sat 26 Jan 2013 04:05:32 PM CST
     ************************************************************************/


    #include<stdio.h>
    #include<string.h>
    #include<stdlib.h>

    #define N  10
    typedef  struct
    {
         char *tokens[N];
         int count;
    } unit_t;

    void find_url_token( char str[],  const  char tok[], unit_t *ptr)
    {
         int i;
         char *token =  NULL;
         char *saveptr =  NULL;

        ptr->count =  0;
         const  char *needle =  "://";

         if (strstr(str, needle))
        {
             for (i =  0; ; str =  NULL, i++)
            {
                token = strtok_r(str, tok, &saveptr);
                 if (token ==  NULL)
                     break;
                 else
                {
                    ptr->tokens[i] = token;
                    ptr->count++;
                }
            }
        }
    }

    int main( void)
    {
         /* 不能定义为char *url = "..."; 因为此时是定义一个指向字符串字面值(位于.rodata段)的指针,而
           调用strtok_r函数会修改这个字符串,运行时会产生段错误 */

         char url[] =  "http://www.google.cn/search?complete=1&hl=zh-CN&ie=GB2312&q=linux&meta=";
         /* 给url初始化用的这个字符串并没有分配在.rodata段,而是直接写在指令里了,
         * 运行程序时通过三条movl 指令把12个字节写到栈上,这就是url的存储空间*/

        unit_t *ptr = malloc( sizeof(unit_t));
        find_url_token(url,  "?&", ptr);
         int i;
         for (i =  0; i < ptr->count; i++)
            printf( "%s ", ptr->tokens[i]);
        free(ptr);
         return  0;
    }




    (3)、去除 ,去除左右空白字符

     C++ Code 
    1
    2
    3
    4
    5
    6
    7
     
    void str_trim_crlf( char *str)
    {
         char *p = &str[strlen(str) -  1];
         while (*p ==  ' ' || *p ==  ' ')
            *p-- =  '';

    }

     C++ Code 
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
     
    void AllTrim(  char *str )
    {
         char *head, *tail;

         if ( str ==  NULL )
             return;

         for( head = str; *head ==  ' ' || *head ==  ' '; head ++ );

         for( tail = str + strlen(str) -  1; (*tail ==  ' ' || *tail ==  ' ' ) && tail >= head; tail -- );

         while( head <= tail )
            *str ++ = *head ++;

        *str =  0;
    }

    (4)、判断字符串是否为回文

     C++ Code 
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
     
    // 判断字符串是否为回文
    bool isSysmmetry( const  char *src)
    {
        assert(src !=  NULL);
         int len = strlen(src);
        assert(len !=  0);
         const  char *tmp = src + len -  1;

         int i;
         for (i =  0; i < len /  2; i++)
        {
             if (*src++ != *tmp--)
                 break;
        }

         if (i == len /  2)
             return  true;
         else
             return  false;

    }

    (5)、google笔试:编码实现求给定字符串(全为小写英文字母)的最小后继,如 “abc” 的最小后继为“abd”, "dhz" 的最小后继为“di"。

     C++ Code 
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
     
    int MinNextStr( const  char *src,  char *&minnext)
    {
         int srclen = strlen(src);
        minnext = ( char *)malloc((srclen +  1) *  sizeof( char));
         if (minnext ==  NULL)
             return - 1;
        strcpy(minnext, src);

         int i = srclen -  1;
         while (i >=  0)
        {
            minnext[i]++;
             if (minnext[i] <=  'z')
                 break;
            i--;
        }

         if (i <  0)
             return  0;
         else
        {
            minnext[++i] =  '';
             return  1;

        }
    }

    如果把给定字符串全为小写英文字母改为大小写英文字母,则只要把 第13行改为:

    if (minnext[i] <= 'z' && minnext[i] >= 'a' || minnext[i] <= 'Z');

    (6)、中兴:编码实现字符串右移n位,如“diopheg” 右移2位为“egdioph”。

     C++ Code 
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
     
    bool RightMoveStr( char *src,  int n)
    {
         int len = strlen(src);
         int mov = n % len;
         char *rstr = ( char *)malloc((mov +  1) *  sizeof( char));
         if (rstr ==  NULL)
             return  false;

         int i =  0;
         while (i < mov)
        {
            rstr[i] = src[len - mov + i];
            i++;
        }
        rstr[i] =  '';

        i = len - mov -  1;
         while (i >=  0)
        {
            src[i + mov] = src[i];
            i--;
        }

        i =  0;
         while (i < mov)
        {
            src[i] = rstr[i];
            i++;
        }

        free(rstr);
         return  true;
    }

    bool RightMove( char *src,  char *&ssrc,  int n)
    {
         int len = strlen(src);
        ssrc = ( char *)malloc( sizeof( char) * (len +  1));
         if (ssrc ==  NULL)
             return  false;

        n = n % len;
         char *tmp = src + len - n;

        strcpy(ssrc, tmp);
        strncat(ssrc, src, len - n);

         return  true;

    }

    (7)、新邮通:字符串反转:给定字符串“we;tonight;you;”,编码实现输出”ew;thginot;uoy;“

     C++ Code 
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
     
    void ReverseStr( char *src)
    {
         int len = strlen(src);
         int i =  0;
         int first =  0;
         int end =  0;
         while (i < len)
        {
             if (src[i] ==  ';')
            {
                end = i -  1;
                 while (first < end)
                {
                     char tmp = src[first];
                    src[first] = src[end];
                    src[end] = tmp;
                    first++;
                    end--;
                }
                first = i +  1;

            }
            i++;
        }
    }

    如果给定字符串末尾没有';',只需要修改9,10,11行

     C++ Code 
    1
    2
    3
    4
    5
    6
    7
    8
     
    if (src[i] ==  ';' || i == len -  1)
    {
         if (src[i] ==  ';')
            end = i -  1;
         else
            end = i;
         while...
    }



  • 相关阅读:
    SpringBoot全局日志管理(AOP)
    SpringBoot集成Shiro
    MybatisPlus使用介绍
    SpringBoot集成MybatisPlus
    SpringBoot集成多数据源
    SpringBoot事务管理
    ETL 工具和 BI 工具
    oracle中行转列操作
    Oracle基本数据类型总结
    LINUX中lrzsz软件的使用
  • 原文地址:https://www.cnblogs.com/pangblog/p/3324861.html
Copyright © 2011-2022 走看看