使用C语言提取子字符串及判断对称子字符串最大长度_C 语言

先来看一个使用C语言从字符串中提取子字符串的基本方法总结:

#include <stdio.h>

/*处理中文字符*/
/*遍历字符串,非ASCII字符读取2个字节,ASCII读取一个字节,获取字符串长度*/
int StrLenU(const char* string)
{
   int len = 0 ;
   const char* p = string;
   while(*p++ != '\0')
   {
     if(*p > 0x80 || *p < 0)
     {
      p++;
     }
     len++;
   }
   return len;
}
/*遍历字符串,非ASCII字符读取2个字节,ASCII读取一个字节,返回指定位置的字符串指针,默认从1开始*/
char* StrSetPosU(const char* string,int pos)
{
   char* result;
   result = string;
   while (result != NULL && *result != '\0' && pos > 1)
   {
     if(*result > 0x80 || *result < 0)
     {
       result++;
     }
     result++;
     pos--;
   }
   if(pos!=0)
     return result;
   return '\0';
}
/*获取指定内存中的字符串个数,中文字符作为一个字符*/
int StrLenMemU(const char* string,int size)
{
   int len = 0 ;
   const char* p = string;
   while(*p++ != '\0' && size > 0)
   {
     if(*p > 0x80 || *p < 0)
     {
      p++;
      size--;
     }
     size-- ;
     len++;
   }
   return len;
}
/*可取中文字符串,当number为-1等负数时,取从start开始的剩余所有字符,默认从1开始*/
char* StringSubU(const char* string,int start,int number)
{
   int len = StrLenU(string) ;
   if(start>len)
   {
     printf("Start %d is too big than string length %d!\n",start,len);
     return NULL;
   }
   int bufsize = 0;
   int num = number;
   const char* p = string;
   const char* start_char =string;
   /*重置指针,获取指定开始位置*/
   p = StrSetPosU(string,start);
   start_char = p;
   /*当取值为负值时,则取全部值*/
   if(number < 0)
   {
     while(*p != '\0')
     {
      p++;
      bufsize++;
     }
   }
   else
   {
     while(1)
     {
      /*当指针移到末尾,而且还没有获取指定数的字符时,说明此时指定字符数过多,将会取剩下的所有值*/
      if(*p == '\0' && num > 0)
      {
        printf("Number : %d is to big!\n",number);
        break;
      }
      /*当num为0时,说明读取字符已经满足要求*/
      else if(num ==0 )
        break;
      /*当字符为ASCII时,*/
      if(*p > 0x80 || *p < 0)
      {
        bufsize++;
        p++;
      }
      bufsize++;
      p++;
      num--;
     }
   }
   num = bufsize;
   /*开始分配内存*/
   char* result ;
   result = (char*)malloc(sizeof(char)*(bufsize+1));
   memset(result,0,sizeof(char)*(bufsize+1));
   /*开始复制字符串*/
   int i = 0;
   int j = 0;
   while(num != 0)
   {
     result[i++] = start_char[j++];
     num--;
   }
   /*尾部置零*/
   result[bufsize] = '\0';
   return result;
}

int main()
{
   /*进行测试*/
   char* t = "a哈哈aab和c哈";
   printf("length: %d\n",StrLenU("哈哈a哈a哈"));
   printf("指向前%s\n指向后:%s\n",t,StrSetPosU(t,3));
   printf("全字符时字符个数:%d\n",StrLenMemU(t,6));
   printf("半个字符时字符个数:%d\n",StrLenMemU(t,4));
   printf("1.正常取值:%s\n",StringSubU("a哈aa哈a",1,2));
   printf("2.负值取值:%s\n",StringSubU("a哈aa哈a",-1,2));
   printf("3.起始值过大:%s\n",StringSubU("a哈aa哈a",7,2));
   printf("4.取值过大:%s\n",StringSubU("a哈aa哈a",5,3));
   printf("5.负值取全部:%s\n",StringSubU("a哈aa哈a",4,-1));

   return 0;
}

判断对称子字符串最大长度的方法

判断回文
先重写一个判断回文字串的方法,用指针实现,而不是数组了

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

  void isSymmetrical(char *str)
  {
    char *begin, *end;
    int flag, len = strlen(str); 

    for (begin = str, end = str + len - 1, flag = 1; begin <= end; begin ++, end --) {
      if (*begin != *end) {
        flag = 0;
        break;
      }
    } 

    if (flag)
      printf("Yes!\n");
    else
      printf("No!\n");
  } 

  int main(void)
  {
    char str[1001]; 

    while (gets(str)) {
      isSymmetrical(str);
    } 

    return 0;
  } 

/**************************************************************
        Problem: 1192
        User: wangzhengyi
        Language: C
        Result: Accepted
        Time:10 ms
        Memory:912 kb
    ****************************************************************/ 

判断回文子串
判断子串是否为回文,可以考虑从内向外比较。例如字符串“google”,如果我们判断第二个字符o是对称的,只需要再向左、和向右各移一位就可以判断下一个字符串是否是对称的了
需要注意的一点是,针对原字符串中的每一个字符有两种情况:

    以该字符为中心的对称分布,也就是回文子串为奇数
    以该字符和该字符前一个字符为中心的对称分布,也就是说回文子串是偶数

时间复杂度分析:

外层需要n - 1层循环,内层对于每个字符,都由中间向两边遍历一遍,为n,因此总的时间复杂度为O(n * n)

题目

    题目描述: 
    输入一个字符串,输出该字符串中对称的子字符串的最大长度。 
    比如输入字符串“google”,由于该字符串里最长的对称子字符串是“goog”,因此输出4。 
    输入: 
    存在多组数据,每组数据一行字符串,长度不大于100。 
    输出: 
    输出回文子串的最大长度。 
    样例输入: 
    google 
    样例输出: 
    4 

ac代码

 

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

  /**
   * 最长回文字串的长度
   */
  void maxSymmetricalSubstring(char *str)
  {
    int maxlength, len;
    char *pre, *next, *current; 

    current = str + 1;
    maxlength = 0; 

    while (*current != '\0') {
      pre = current - 1;
      next = current + 1; 

      while (pre >= str && *next != '\0' && *pre == *next) {
        pre --;
        next ++;
      } 

      len = (next - 1) - (pre + 1) + 1; 

      if (len > maxlength) {
        maxlength = len;
      } 

      pre = current - 1;
      next = current; 

      while (pre >= str && *next != '\0' && *pre == *next) {
        pre --;
        next ++;
      }
      len = (next - 1) - (pre + 1) + 1; 

      if (len > maxlength) {
        maxlength = len;
      } 

      current ++;
    } 

    printf("%d\n", maxlength);
  }   

  int main(void)
  {
    char str[101]; 

    while (gets(str)) {
      maxSymmetricalSubstring(str);
    } 

    return 0;
  }

    /**************************************************************
        Problem: 1252
        User: wangzhengyi
        Language: C
        Result: Accepted
        Time:0 ms
        Memory:912 kb
    ****************************************************************/ 

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索c
子字符串
对称字符串的最大长度、c语言字符串长度、c语言获取字符串长度、c语言字符串长度函数、c语言求字符串长度,以便于您获取更多的相关知识。

时间: 2024-09-19 21:44:43

使用C语言提取子字符串及判断对称子字符串最大长度_C 语言的相关文章

C语言中字符串的内存地址操作的相关函数简介_C 语言

C语言bcopy()函数:复制内存(字符串)头文件: #include <string.h> bcopy() 函数用来复制内存(字符串),其原型为: void bcopy(const void *src, void *dest, int n); [参数]src 为源内存块(字符串)指针,dest 为目标内存块(字符串)指针,n 为要复制的内存(字符串)的前 n 个字节长度. bcopy()与memcpy()一样都是用来拷贝src 所指的内存内容前n 个字节到dest 所指的地址,不过参数src

C++中字符串查找操作的两则实例分享_C 语言

在一个字符串中找到第一个只出现一次的字符题目:     在一个字符串中找到第一个只出现一次的字符.如输入 abaccdeff,则输出 b. 分析:     一个字符串存储的都是ASCII字符,其ASCII范围不超过255.     因此可以再创建一个255个元素的数组存储字符串中字符出现的个数.     通过两次遍历即可求得. 代码实现(GCC编译通过): #include "stdio.h" #include "stdlib.h" //查找字符串中第一个只出现一次

C语言入门的一些基本资源推荐和程序语法概览_C 语言

为什么要学习C语言? 为什么要学习.使用C语言?为什么要学习一个可能比自己都岁数大的编程语言? 选择一门编程语言,"为什么而学"这个目的是最重要的,目的不明确就没法学好.这也是为什么很多学生朋友在大学里必修C语言却觉得没学明白的原因.因为学习的目的不明确,学习当然也没有动力.还有一个原因是C语言是工程实践性很强的语言,它不是来自某个研究所某个大学学院,而是实实在在从项目需要中产生,伴随着Unix的兴起而流行,语义简明清晰,功能强大而不臃肿,简洁而又不过分简单,实在是居家旅行工作学习必备

C 语言基础教程(我的C之旅开始了)[二]_C 语言

3. C 程序的结构    C 程序由一个以上的函数组成,而且必须有 main 函数.此外,C 程序一般还有一些预处理指令.例如 #include 指令.当然并不是必须要有 #include 指令.函数由函数头和函数体组成.函数头由返回值.函数名以及参数列表(可以是void)组成.函数体从 { 开始,以 } 结束.函数体里可以有一系列的语句,每个语句以分号(;)结束.例如:        预处理指令     --〉   #include <stdio.h>        函数头        

使用C语言判断英文字符大小写的方法_C 语言

C语言isupper()函数:判断字符是否为大写英文字母头文件: #include <ctype.h> 定义函数: int isupper(int c); 函数说明:检查参数c是否为大写英文字母. 返回值:若参数c 为大写英文字母,则返回非 0,否则返回 0. 附加说明:此为宏定义,非真正函数. 范例:找出字符串str 中为大写英文字母的字符. #include <ctype.h> main(){ char str[] = "123c@#FDsP[e?"; in

详解C++循环创建多级目录及判断目录是否存在的方法_C 语言

C++循环创建多级目录 #include "unitfiles.h" #ifdef WIN32 #include <direct.h> #include <io.h> #elif LINUX #include <stdarg.h> #include <sys/stat.h> #endif #ifdef WIN32 #define ACCESS _access #define MKDIR(a) _mkdir((a)) #elif LINUX

C++将二叉树转为双向链表及判断两个链表是否相交_C 语言

把二叉查找树转变成排序的双向链表例如: 转换成双向链表 4=6=8=10=12=14=16 struct BSTreeNode { int m_nValue; // value of node BSTreeNode *m_pLeft; // left child of node BSTreeNode *m_pRight; // right child of node }; 首先阐述下二叉排序树: 它首先要是一棵二元树,在这基础上它或者是一棵空树:或者是具有下列性质的二元树: (1)若左子树不空,

如何判断一个数是否为4的幂次方?若是,并判断出来是多少次方?_C 语言

将4的幂次方写成二进制形式后,很容易就会发现有一个特点:二进制中只有一个1(1在奇数位置),并且1后面跟了偶数个0: 因此问题可以转化为判断1后面是否跟了偶数个0就可以了.4的整数次幂的二进制数都为 (4)100.(16)10000.(64)1000000......另外,4的幂次方4^n也可以写为2^(2*n),即也可以写为2的幂次方,当然就满足2的幂次方的条件了,即num & num-1==0.思路:首先用条件num & num-1==0来判断是否为2的幂次方,若不满足,则不是.若满足

C语言小程序 如何判断两个日期之差_C 语言

1.普通的写法 复制代码 代码如下: #include <stdio.h>int leapyear(int year){ if((year%4==0 && year%100!=0) || year%400==0)  return 1; else   return 0;}int days(int *day1, int *day2){ int i=0; int *tmp; int diff = 0; const int month[13]={0,31,28,31,30,31,30,