最大空间序列 C语言实现

2 篇文章 0 订阅

      这段时间,一直再看《算法导论》,现在看到了动态规划这部分,其中的一个  最大公共序列的问题,挺有意思,用到了动态规划的思想,具体的原理可以参考《算法导论》的第15章,page208.


      于是就用C语言实现了一下,具体的代码如下:

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

char *getString(void);   //获取输入的字符序列函数

// 用于计算公共序列长度数组的函数
void LCS_length(char *str1, char* str2, int m[strlen(str1)+1][strlen(str2)+1], int b[strlen(str1)+1][strlen(str2)+1]);

// 输出最大公共子序列的函数
void PrintLCS( char *str1,char *str2,int b[strlen(str1)+1][strlen(str2)+1], int len1, int len2);

int main()
{
	char *s1 = getString();
	char *s2 = getString();
	int len1 = strlen(s1);
	int len2 = strlen(s2);
	int m[len1][len2];
	int b[len1][len2];

	LCS_length(s1,s2,m,b);
	PrintLCS(s1,s2,b,len1,len2);
	return 0;
}


char *getString(void)
{
	int c,i=0;
	char *s = (char *)malloc(MAX*sizeof(char));     //字符串数组申明了指针之后,必须给予相应的初值

	printf("Please Input the String:");
	while((c = getchar()) != '\n')
		s[i++] = c;
    s[i] = '\0';
	return s;
}

void LCS_length(char *s1, char* s2, int m[strlen(s1)+1][strlen(s2)+1], int b[strlen(s1)+1][strlen(s2)+1])
{
	int len1 = strlen(s1);
	int len2 = strlen(s2);
	int i,j;

	for(i=0;i<=len1;i++)                           //初始化,将所有m[0,i] 和 m[i,0]的字串都设置长度为0
		m[i][0] = 0;
	for(i=1;i<=len2;i++)
		m[0][i] = 0;

	for(i = 1; i <=len1; i++)
		{
		    for(j = 1; j<=len2; j++)
			{
				if(s1[i-1]==s2[j-1])
					{
					 	m[i][j] = m[i-1][j-1] + 1;
						b[i][j] = 0;
				 	}
				else if(m[i-1][j] >= m[i][j-1])     
					{
						m[i][j] = m[i-1][j];
						b[i][j] = 1;
					}
				else
					{
						m[i][j] = m[i][j-1];
						b[i][j] = -1;
					}
			}
        }

        for(i=0;i<=len1;i++)
            {
                for(j=0;j<=len2;j++)
                   printf(" %d ",m[i][j]);
                printf("\n");
            }
}

void PrintLCS( char *str1,char *str2,int b[strlen(str1)+1][strlen(str2)+1], int len1, int len2)
{
	if((len1 == 0)||(len2 == 0))
		return;
	if(b[len1][len2] == 0)
		{
			PrintLCS(str1,str2, b, len1-1, len2-1);    //注意,这里的顺序会有影响,先递归调用前面的子序列,再打印后面的相同字符
			printf("%c",str1[len1-1]);                   
		}
	else if(b[len1][len2] == 1)
		PrintLCS(str1,str2, b, len1-1, len2);
	else
		PrintLCS(str1,str2,b, len1, len2-1);
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值