求数组中两个字符串的最小距离--C语言

题目解析

给定一个字符串数组strs,再给定两个字符串str1和str2,返回在strs中str1和str2的最小距离,如果Str1或str2为null,或不在strs中,返回-1。

输入描述

输入描述:
输入包含有多行,第一输入一个整数n(1≤n≤100000),代表数组strs的长度,第二行有两个字符串分别代表str1和str2,接下来n行,每行一个字符串,代表数组strs (保证题目中出现的所有字符串长度均小于等于10)。

输出描述

输出描述:
输出一行,包含一个整数,代表返回的值。

示例

输入:
1
CD AB
CD
输出:
-1

输入:
5
QWER 666
QWER
1234
qwe
666
QWER
输出:
1

解法

解法一:暴力求解法(列出所有出现的情况)

用两个for循环遍历,外层循环在strs数组中找到str1 或str2 后固定住,内层循环就在外层循环的基础上,向后遍历,找到相应的字符串,如果前面找的是str1并且后来找的是str2,或者是前面找的是str2并且后来找的是str1,就将对应的下标相减得到之间的距离 ,紧接着与ret 比较一下,如果ret 较大,就将相减的值赋给ret.ret初始化的值必须>=n,原因在下面代码中解释。

代码

int main()
{
	int n = 0;
	scanf("%d", &n);
	char str1[10] = { 0 };
	char str2[10] = { 0 };
	scanf("%s %s", str1, str2);
	getchar();//吸收一个回车键
	char strs[100000][10];//整数n(1≤n≤100000)
	int i = 0;
	int j = 0;
	for (i = 0; i < n; i++)//输入
	{
	gets(strs[i]);// i 是行
	}
	//暴力解法
	int ret = n;//字符串之间距必须>=n,如果小于n,举个例子
	            //我输入n=3,ret=2,str1=abc,str2=bcd,strs输入abc ewq bcd ,ret==j-i=2,就不满足ret>j-i,就进不了if语句,就实现不了ret=j-i,所以ret=2,if (ret==2)就执行 ret=-1。
	for (i = 0; i < n; i++)
	{
		if (strcmp(str1, strs[i]) == 0 || strcmp(str2, strs[i]) == 0)//遍历定位
		{
			for (j = i+1; j < n; j++)//从被固定的位置向后遍历
			{
				if (strcmp(str1, strs[i]) == 0 && strcmp(str2, strs[j])==0|| strcmp(str2, strs[i]) == 0 && strcmp(str1, strs[j]) == 0 )//固定的是 str1,那后面找str2.或者是固定的是 str2,那后面找str1. 就满足条件
				{
					if (ret > j - i)//j-i就是字符串之间的距离
						ret = j - i;
				}
			}
		}
	}
	if (ret == n)//说明不满足:固定的是 str1,那后面找str2.或者是固定的是 str2,那后面找str1.就表明strs中不同时存在str1和str2
		         // 进不了内层for循环中的外层for语句,所以 ret 没变
	{
		ret = -1;
	}
	printf("%d", ret);
	return 0;
}

运行结果

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

解法二:预处理方法

引入两个变量prev1和prev2来记录下标,先初始化为-1,prev1是记录strs中是str1的下标,那么prev2就是str2的下标。只遍历一次,在遍历的过程中,若遇到了str1就把其对应的下标赋给prev1,遇到了str2就赋值给prev2。如果prev1不为-1同时prev2也不为-1,就说明strs中存在str1和str2,紧接着就下标相减得到距离,然后与ret比较,如果ret比较大,就把值赋给ret.

代码

int main()
{
	int n = 0;
	scanf("%d", &n);
	char str1[10] = { 0 };
	char str2[10] = { 0 };
	scanf("%s %s", str1, str2);
	getchar();
	char strs[10][10];
	int i = 0;
	int j = 0;
	for (i = 0; i < n; i++)
	{
		gets(strs[i]);
	}

	int ret = n;//ret必须>=n.
	
	int prev1 = -1;//strs中str1的下标
	int prev2 = -1;
	for (i = 0; i < n; i++)
	{
		if (strcmp(str1, strs[i]) == 0)
			prev1 = i;//prev1= 0 
		if (strcmp(str2, strs[i]) == 0)
			prev2 = i;//prev2= 3
		if (prev1 != -1 && prev2 != -1)//进得去就说明在strs中存在str1和str2
		{
			if(ret> fabs(prev1 - prev2))
			ret = fabs(prev1 - prev2);
		}
	}
	if (ret == n)//若ret ==n,就表明在strs中不存在str1和str2
		{
			ret = -1;
		}
		printf("%d", ret);
	return 0;
}

运行结果

5
QWER 666
QWER
1234
qwe
666
QWER
1
6
qwe asd
qwe
123
678
yui
tyupo
asd
5
  • 32
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值