每日一道算法题——最长公共前缀(6.17)

题目:

编写一个函数来查找字符串数组中的最长公共前缀。

如果不存在公共前缀,返回空字符串 “”。

示例 1:

输入: [“flower”,“flow”,“flight”]
输出: “fl”
示例 2:

输入: [“dog”,“racecar”,“car”]
输出: “”
解释: 输入不存在公共前缀。
说明:

所有输入只包含小写字母 a-z 。

解答:

char * longestCommonPrefix(char ** strs, int strsSize)
{
	char * temp = (char*)malloc(128);			//用来存储公共前缀
	memset(temp, 0, 128);

	if (strsSize == 0)
	{
		return "";
	}

	strcpy(temp, strs[0]);
	int len= strlen(temp);		//用来计数,公共前缀字符数为0时,则没有

	for (int i = 0; i < strsSize; i++)
	{
		char * currentStr = strs[i];

		if (len == 0)
		{
			return "";
		}
		int j;
		for (j = 0; j < len; j++)
		{
			if (temp[j] != currentStr[j])
			{
				break;
			}
		}

		len = j;
		temp[j] = 0;
	}

	return temp;

}

解题思路:

① 先比较第一和第二个,如果有公共的前缀,则用前缀和第三个比较
②如果没有公共前缀,就直接返回,后面的不需要比较

完整代码可以这样写:

 #include<stdio.h>
 #include<string.h>
 #include<stdlib.h>
 char * longestCommonPrefix(char ** strs, int strsSize)
 {
     char *temp=(char*)malloc(128);//定义一个字符串指针,用来存储公共前缀的指针
     memset(temp,0,128);//初始化内存单元
     if(strsSize==0)//数组长度为0
         return “”;                                        
 
     strcpy(temp,strs[0]);//将二维数组首元素赋值给temp
     int len=strlen(temp);//求其长度
     int i;
     for(i=0;i<=strsSize;i++)//从二维数组首元素开始逐一进行比较
     {
         char *curr=strs[i];//定义一个字符串指针指向数组第i个元素
         if(len==0)//若长度为0
             return “”;
         int j;
         for(j=0;j<len;j++)//对第i个元素,从第一个字符逐一比较
         {
             if(temp[j]!=curr[j])//若字符不相等,终止循环
                 break;
         }
         len=j;
         temp[j]=0;//将第j个元素设置成0
         printf("%s\n",temp);//打印每一次的最长前缀
     }
     return temp;//返回最长前缀
 }
 
 int main(int argc, const char *argv[])
 {
     char a[3][20];//定义一个二维数组
     int i;
     for(i=0;i<3;i++)//给二位数组手动赋值
             gets(a[i]);           
    char *p[3];//定义一个字符串指针数组
    p[0]=&a[0][0];
    p[1]=a[1];
    p[2]=a[2];
    longestCommonPrefix(p,3);
    return 0;
}


注意:

①关于memset函数:

每种类型的变量都有各自的初始化方法,memset() 函数可以说是初始化内存的“万能函数”,通常为新申请的内存进行初始化工作。它是直接操作内存空间,mem即“内存”(memory)的意思。该函数的原型为:# include <string.h>
void *memset(void *s, int c, unsigned long n);

函数的功能是:将指针变量 s 所指向的前 n 字节的内存单元用一个“整数” c 替换,注意 c 是 int 型。s 是 void* 型的指针变量,所以它可以为任何类型的数据进行初始化。

memset() 的作用是在一段内存块中填充某个给定的值。因为它只能填充一个值,所以该函数的初始化为原始初始化,无法将变量初始化为程序中需要的数据。用memset初始化完后,后面程序中再向该内存空间中存放需要的数据。

memset 一般使用“0”初始化内存单元,而且通常是给数组或结构体进行初始化。一般的变量如 char、int、float、double 等类型的变量直接初始化即可,没有必要用 memset。如果用 memset 的话反而显得麻烦。

②二维数组指针表示:

在一维数组中,数组名表示的是数组第一个元素的地址,那么二维数组呢? a 表示的是元素 a[0][0] 的地址吗?不是!我们说过,二维数组就是一维数组,二维数组 a[3][4] 就是有三个元素 a[0]、a[1]、a[2] 的一维数组,所以数组 a 的第一个元素不是 a[0][0],而是 a[0],所以数组名 a 表示的不是元素 a[0][0] 的地址,而是 a[0] 的地址,即:
a == &a[0]

而 a[0] 又是 a[0][0] 的地址,即:
a[0] == &a[0][0]

所以二维数组名 a 和元素 a[0][0] 的关系是:
a == &(&a[0][0])

即二维数组名 a 是地址的地址,必须两次取值才可以取出数组中存储的数据。对于二维数组 a[M][N],数组名 a 的类型为 int(*)[N],所以如果定义了一个指针变量 p:
int *p;

并希望这个指针变量指向二维数组 a,那么不能把 a 赋给 p,因为它们的类型不一样。要么把 &a[0][0] 赋给 p,要么把 a[0] 赋给 p,要么把 *a 赋给 p。前两个好理解,可为什么可以把 *a 赋给 p?因为 a==&(&a[0][0]),所以 a==(&(&a[0][0]))==&a[0][0]。

在此例中,要传递一个二维数组,即一个二级指针,必须首先定义一个指针数组,并赋值。

char *p[3];//定义一个字符串指针数组
    p[0]=&a[0][0];
    p[1]=a[1];
    p[2]=a[2];
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值