黑马程序员技术交流社区

标题: 最大公共字符串题目 [打印本页]

作者: 流转少年    时间: 2015-4-5 14:44
标题: 最大公共字符串题目
关于最大公共字符串真的难为我这0基础的同学了,花了我整整5个小时,爬了好几个帖子,看不懂的居多,有用指针的,有用strstr这个没有学过的函数的。指针变量虽然说能看懂一部分,但是还是有点吃力,最后看到一个帖子说用二维数组来计数,就看了一下,只可惜他并没有用纯数组来做。所以我就根据学过的C语言,花了近3个小时,写出了下面的这些代码。
  1. //10、 找出多个字符串中的最大公共子字符串,如“nbitheimanb”和“itheia”的最大子串是:”ithei”。(C语言)
  2. #include <stdio.h>
  3. #include <string.h>
  4. int main()
  5. {
  6.     //1.定义字符串数组
  7.     char s1[100], s2[100];
  8.     //2.定义一个二维数组存放指定变量(两个字母相等,值为1,不相等,值为0)
  9.     int a[100][100];
  10.     //3.定义变量记录公共字符串长度
  11.     int MaxLenth = 0;
  12.     //4.定义变量记录相等字符的最后的地址
  13.     int adds = 0;
  14.     //5.提示用户输入第一个字符串
  15.     printf("请输入第一个字符串:\n");
  16.     //6.接收用户输入的第一个字符串数组
  17.     scanf("%s", s1);
  18.     //7.提示用户输入第二个字符串
  19.     printf("请输入第二个字符串\n");
  20.     //8.接收用户输入的第二个字符串数组
  21.     scanf("%s", s2);
  22.     //9.遍历字符串s1
  23.     for(int i = 0; i < strlen(s1); i++)
  24.     {
  25.         //10.遍历字符串s2
  26.         for(int j = 0; j < strlen(s2); j++)
  27.         {
  28.             //11.判断相应字符是否相等
  29.             if(s1[i] == s2[j])
  30.             {
  31.                 //12.如果对应字符相等,则在二维数组对应坐标赋值为1
  32.                 a[i][j] = 1;
  33.             }
  34.             //13.如果对应字符不相等,则在二维数组对应坐标赋值为0
  35.             else
  36.                 a[i][j] = 0;
  37.         }
  38.     }
  39.     //14.打印说明
  40.     printf("------------上方为输入数据-----------\n");
  41.     printf("----------下方为二维数组数据-----------\n");
  42.     //15.遍历输出二维数组(此处作为查看使用)
  43.     for(int i = 0; i < strlen(s1); i++)
  44.     {
  45.         for(int j = 0; j < strlen(s2); j++)
  46.         {
  47.             printf("%d ",a[i][j]);
  48.         }
  49.         //16.每打印完一行,换行
  50.         printf("\n");
  51.     }
  52.     //17.打印说明(分隔符)
  53.     printf("----------下方为结果数据-----------\n");
  54.     //18.遍历二维数组的行元素
  55.     for(int i = 0; i < strlen(s1); i++)
  56.     {
  57.         //19.遍历二维数组的列元素
  58.         for(int j = 0; j < strlen(s2); j++)
  59.         {
  60.             //20.判断该坐标处值是否为1,值为1代表是两个字符串开始字符开始相等的位置
  61.             if(a[i][j] == 1)
  62.             {
  63.                 //21.定义并初始化临时变量,记录存放公共字符串长度
  64.                 int temp = 0;
  65.                 //22.定义新的变量,存放i值,避免更改i值
  66.                 int i1 = i;
  67.                 //23.定义新的变量,存放j值,避免更改j值
  68.                 int j1 = j;
  69.                 //24.当该坐标的值为1时,进入循环,判断该坐标右下角坐标是否为1,如果为1,代表两个字符串下一个字符也相等
  70.                 while(a[i1][j1] == 1)
  71.                 {
  72.                     //25.自增1,为下次判断做准备
  73.                     i1++;
  74.                     //26.自增1,为下次判断做准备
  75.                     j1++;
  76.                     //27.记录公共字符串的长度
  77.                     temp++;
  78.                 }
  79.                 //28.判断新的公共字符串长度是否大于上一次公共字符串长度,如果不大于,则互换值。保证所取公共字符串的长度是最大。
  80.                 if(temp > MaxLenth)
  81.                 {
  82.                     MaxLenth = temp;
  83.                     //29.把最长公共字符串地址赋值给adds
  84.                     adds = j1;
  85.                 }
  86.             }
  87.         }
  88.     }
  89.     //30.输出最大公共字符串长度值
  90.     printf("最大公共字符串长度:%d\n",MaxLenth);
  91.     //31.输出标题
  92.     printf("最大公共字符串是:");
  93.     //32.循环输出公共字符串
  94.     for(int i = 0 ; i < MaxLenth; i++)
  95.     {
  96.         //33.因为所取地址值是最后的地址,所以要提取公共字符串的首字符地址,为 adds - MaxLenth
  97.         printf("%c",s2[adds - MaxLenth + i]);
  98.     }
  99.     //34.输入换行符
  100.     printf("\n");
  101.     return 0;
  102. }
复制代码
  1. 请输入第一个字符串:
  2. nbitheimanb
  3. 请输入第二个字符串
  4. itheia
  5. ------------上方为输入数据-----------
  6. ----------下方为二维数组数据-----------
  7. 0 0 0 0 0 0
  8. 0 0 0 0 0 0
  9. 1 0 0 0 1 0
  10. 0 1 0 0 0 0
  11. 0 0 1 0 0 0
  12. 0 0 0 1 0 0
  13. 1 0 0 0 1 0
  14. 0 0 0 0 0 0
  15. 0 0 0 0 0 1
  16. 0 0 0 0 0 0
  17. 0 0 0 0 0 0
  18. ----------下方为结果数据-----------
  19. 最大公共字符串长度:5
  20. 最大公共字符串是:ithei
复制代码
上面是代码,下面是运行结果。
此理论是根据,二维数组,存放0,1,对于字符串中的某个字符,把它s1位置作为横坐标,把它s2的位置作为纵坐标,在二维数组里面赋值。如果相等,赋值为1,如果不相等,赋值为0。在例子中可以看到,二维数组输出的结果。然后用for循环遍历二维数组,找出值为1的元素,当找到这个元素时,接着判断该元素的右下角的元素是否为1,如果为1,则计数,直到不为1退出。这步的作用,就是判断公共字符串的个数,至于怎么来判断的,大家可以看数组,顺序必须得时由左上角到右下角的斜线上相同为1,不能是其它的方向。看数组可以看到2、3、4、5、6行(首行为0行)对应的0、1、2、3、4列,值为1。那么在数组s1中的2、3、4、5、6号元素,和s2的0、1、2、3、4号元素就是公共字符串。如此判断,找出最长的一个,用adds记录最后一位元素的横坐标或者是纵坐标,在这里我记录的是纵坐标也就是s2数组元素序号。输出的时候注意,记录的时最后一位元素序号,所以要减去该字符长度,才是公共字符串首元素的序号。然后循环输出。
PS:语文不是特别好,希望能大家能看的懂~~~



作者: 流转少年    时间: 2015-4-5 20:15
为什么帖子沉那么深呢???
作者: 梦想中前行    时间: 2015-4-5 20:56
看不懂下边二维数据,结果数据。:L




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2