A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

本帖最后由 董月峰 于 2014-3-24 14:45 编辑

/*
10、 找出多个字符串中的最大公共子字符串,如“nbitheimanb”和“itheia”的最大子串是:”ithei”。(C语言)
*/

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

//比较2个字符串最大公共子串(串1,串2,串1长,串2长)
void maxstr(char *s1,char *s2,int num1,int num2)
{
    //index表示字符相同时s1初始角标,n2表示公共子串初始长度是0,n1表示每个公共子串的长度
        int index=0,n2=0,n1;
    //遍历s1
        for(int i = 0; i <= num1; i++)
        {
        //遍历s2
                for(int j = 0; j <= num2; j++)
                {
            //若遇到相同字符
                        if(s1==s2[j])
                        {
                //先赋值子串长度是1
                                n1 = 1;
                //看从相同字符向后有多少字符还相同
                                for(int k = 1; s1[i+k]==s2[j+k]; k++)
                //每多一个相同字符,n1自增1
                {
                    n1++;
                }
                //取n2为最长的n1
                                if(n1 > n2)
                                {
                    //记录最长n2时候,s【i】的角标位置index
                                        index = i;
                                        n2 = n1;
                                }
                //再与s1比较,从s2【n1+j】即可
                                j += n1;
                        }
                }
        }
    //当存在子串时候,输出最大的
    if(n2 !=0)
    {
        printf("最长的公共子串:");
        for(int i = 0; i < n2; i++)
            printf("%c",s1[index+i]);
    }
    //不存在子串输出没有
    else
        printf("没有公共子串!\n");
}

int main()
{
    maxstr("fuckingday","doingso",10,7);
   
    /*
   
    char ss1[1024],ss2[1024];
    int c=1;
    while(c==1)
    {
        system("cls");
        printf("请输入第一个字符串 :\n");
        gets(ss1);
        int len_s1=strlen(ss1);
        printf("请输入第二个字符串 :\n");
        gets (ss2);
        int len_s2=strlen(ss2);
        maxstr(ss1,ss2,len_s1,len_s2);
        printf("是否继续?(1/其他)\n");
        scanf("%d",&c);
        getchar();
        }
     */
}

12 个回复

倒序浏览
很厉害,赞!得到结论了呀,结果是对的
回复 使用道具 举报
张海龙重新起航 发表于 2014-3-21 08:45
很厉害,赞!得到结论了呀,结果是对的

卧槽,不是吧,为啥我运行不出结果来
回复 使用道具 举报
本帖最后由 周宇华 于 2014-3-21 10:30 编辑

只查出这几个错,代码右边加了注释:
  1. /*
  2. 10、 找出多个字符串中的最大公共子字符串,如“nbitheimanb”和“itheia”的最大子串是:”ithei”。(C语言)
  3. */

  4. #include<stdio.h>
  5. #include<string.h>

  6. //比较2个字符串最大公共子串(串1,串2,串1长,串2长)
  7. void maxstr(char *s1,char *s2,int num1,int num2)
  8. {
  9.     //index表示字符相同时s1初始角标,n2表示公共子串初始长度是0,n1表示每个公共子串的长度
  10.     int index=0,n2=0,n1;
  11.     //遍历s1
  12.     for(int i = 0; i < num1; i++)//去掉=号,否则数组越界
  13.     {
  14.         //遍历s2
  15.         for(int j = 0; j < num; j++)//去掉=号,否则数组越界
  16.         {
  17.             //若遇到相同字符
  18.             if(s1[i]==s2[j]&& s1[i] != '\0')//增加s1[i] != '\0'判断,结束符相等不比较,防止数组越界
  19.             {
  20.                 //先赋值子串长度是1
  21.                 n1 = 1;
  22.                 //看从相同字符向后有多少字符还相同
  23.                 for(int k = 1; s1[i+k]==s2[j+k]&& s1[i+k] != '\0'; k++)//增加s1[i+k] != '\0'判断,结束符相等不比较,防止数组越界
  24.                     //每多一个相同字符,n1自增1
  25.                 {
  26.                     n1++;
  27.                 }
  28.                 //取n2为最长的n1
  29.                 if(n1 > n2)
  30.                 {
  31.                     //记录最长n2时候,s【i】的角标位置index
  32.                     index = i;
  33.                     n2 = n1;
  34.                 }
  35.                 //增加长度判断,超过长度数组就越界了
  36.                 if (j+n1 > num2) {
  37.                     printf("aaj=%d,n1=%d,num2=%d\n",j,n1,num2);
  38.                     break;
  39.                 }
  40.                 //再与s1[i]比较,从s2【n1+j】即可
  41.                 j += n1 -1;//循环会自动+1,这里减掉
  42.             }
  43.         }
  44.     }
  45.     //当存在子串时候,输出最大的
  46.     if(n2 !=0)
  47.     {
  48.         printf("最长的公共子串:");
  49.         for(int i = 0; i < n2; i++)
  50.             printf("%c",s1[index+i]);
  51.     }
  52.     //不存在子串输出没有
  53.     else
  54.         printf("没有公共子串!\n");
  55. }

  56. int main()
  57. {
  58.     //maxstr("fuckingday","doingso",10,7);
  59.    
  60.     /*
  61.      */
  62.      
  63.      char ss1[1024],ss2[1024];
  64.      int c=1;
  65.      while(c==1)
  66.      {
  67.      system("cls");
  68.      printf("请输入第一个字符串 :\n");
  69.          gets(ss1);printf("[%s]\n", ss1);
  70.      int len_s1=strlen(ss1);
  71.      printf("请输入第二个字符串 :\n");
  72.      gets (ss2);printf("[%s]\n", ss2);
  73.      int len_s2=strlen(ss2);
  74.      maxstr(ss1,ss2,len_s1,len_s2);
  75.      printf("是否继续?(1/其他)\n");
  76.      scanf("%d",&c);
  77.      getchar();
  78.      }
  79. }
复制代码

可能还有bug
回复 使用道具 举报
人家题目是说从“多个”字符串中找,楼主这只是从“两个”里找的啊~
回复 使用道具 举报
我也在学习这个问题
回复 使用道具 举报
很厉害的说
回复 使用道具 举报
你这是比较2个字符串不符合题意,我写了个程序实现了这个功能,还算比较完善吧,调试了一个晚上下面是代码
回复 使用道具 举报
  1. #include <stdio.h>
  2. #include <string.h>

  3. int count = 0; // 保存用户输入了多少个字符串
  4. char ages[100][100]; // 保存用户输入的字符串数组
  5. char strMax[100]; // 保存公共字符串
  6. void maxZuichangZiFu(char str[],char str1[]) //判断最长公共字符串函数
  7. {
  8.     // 定义两个指针变量,p是保存最长公共字符串首地址,q是保存相同字符的首地址
  9.     char *p=NULL,*q=NULL;
  10.    
  11.     // 定义两个整型变量,n用于保存最大公共长度,n用于保存相同字符的长度
  12.     int m=0;
  13.     int n = 0;
  14.    
  15.     // 定义两个变量,保存str和str1的长度
  16.     long l1 = strlen(str);
  17.     long l2 = strlen(str1);
  18.    
  19.     for(int i = 0; i<l1; i++) // 循环str字符串的长度
  20.     {
  21.         
  22.         for(int j = 0; j<l2; j++) // 循环str1字符串的长度
  23.         {
  24.              m = 0; // i的每次比较m清0
  25.             // 同步比较str与str1字符串中相等的字符直到为\0时结束
  26.             for(int k = 0;str[k+i]!='\0'&& str1[k+j]!='\0'&& str[k+i]==str1[k+j]; k++)
  27.             {
  28.                
  29.                     m++; // 保存相同字符的数量
  30.                     q = &str[i]; // 保存首地址
  31.                
  32.             }
  33.             
  34.             if(m>n) // 判断最大相同字符的个数
  35.             {
  36.                 p = q; // 保存最大相同字符首地址
  37.                 n = m; // 保存最大相同字符的个数
  38.             }
  39.             
  40.         }
  41.         
  42.     }
  43.    
  44.     int s=0;
  45.     while(strMax[s++]!='\0')
  46.     {
  47.         strMax[s-1]='\0'; // 每次循环之前公共字符串清0
  48.     }
  49.    
  50.     // 判断是否有公共子字符串
  51.     if(n>0){
  52.         // 保存最大公共子字符串
  53.         for(s=0;s<n;s++){
  54.             strMax[s]=*(p+s);
  55.         }
  56.         
  57.         
  58.     }
  59.    
  60.    
  61. }



  62. void yongHuShuRu() //用户输入字符串函数
  63. {
  64.     char isYes[4]; // 保存用户输入的yes或其他字符
  65.    
  66.     // 接收用户输入的字符串
  67.     printf ("请输入字符串\n");
  68.     scanf("%s",ages[count]);
  69.     printf("你存入的字符串是:ages[%d]=%s\n",count ,ages[count]);
  70.     printf ("请输入字符串\n");
  71.     scanf("%s",ages[count+1]);
  72.     printf("你存入的字符串是:ages[%d]=%s\n",count+1 ,ages[count+1]);
  73.     do
  74.     {
  75.         // 提示用户是否继续输入
  76.         printf ("是否继续输入:yes继续,其它退出。\n");
  77.         scanf("%s",isYes);
  78.         
  79.         // 判断用户输入的是否为yes,若为yes继续输入,否则退出循环
  80.         if(strcmp(isYes,"yes"))
  81.         {
  82.             break;
  83.         }
  84.         else
  85.         {
  86.             printf ("请继续输入字符串\n");
  87.             scanf("%s",ages[count+2]);
  88.             printf("你存入的字符串是:ages[%d]=%s\n",count+2 ,ages[count+2]);
  89.         }
  90.         
  91.         count++; // 保存用户输入了多少个字符串
  92.         
  93.         
  94.     }while (1);
  95.    
  96. }


  97. int main(void)
  98. {
  99.     yongHuShuRu(); // 调用用户输入函数
  100.     maxZuichangZiFu(ages[0],ages[1]); // 首先比较用户输入的第一和第二个字符串,取得最长公共字符串
  101.    
  102.     // 拿这个最长公共字符串与其他所有字符串作比较,最后取得所有字符串中最长公共字符串
  103.     for (int i =2; i<count+2; i++)
  104.     {
  105.         
  106.         maxZuichangZiFu(ages[i],strMax);
  107.     }
  108.    
  109.     printf("所有字符串中最长公共字符串:%s\n",strMax); // 所有字符串中最长公共字符串
  110.    
  111.    
  112.     return 0;
  113. }
复制代码
回复 使用道具 举报

编译不出来啊,有好多错误啊
回复 使用道具 举报
大悟云 发表于 2015-3-30 20:58
编译不出来啊,有好多错误啊

不会啊,我用xcode, 运行过没有任何问题,并且用VC6.0运行过也没问题
回复 使用道具 举报
xiezhongmin 发表于 2015-3-31 11:02
不会啊,我用xcode, 运行过没有任何问题,并且用VC6.0运行过也没问题

我运行 的结果是这样的啊

QQ图片20150331171755.png (156.47 KB, 下载次数: 55)

QQ图片20150331171755.png
回复 使用道具 举报
你们这些人太牛掰了!!
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马