由字符串是否包含想到的字符串的排序

比如,如果是下面两个字符串:
String 1: ABCDEFGHLMNOPQRS
String 2: DCGSRQPOM
答案是true,所有在string2里的字母string1也都有。

如果是下面两个字符串:
String 1: ABCDEFGHLMNOPQRS
String 2: DCGSRQPOZ
答案是false,因为第二个字符串里的Z字母不在第一个字符串里。

1.1、O(n*m)的轮询方法

判断string2中的字符是否在string1中?:
String 1: ABCDEFGHLMNOPQRS
String 2: DCGSRQPOM

判断一个字符串是否在另一个字符串中,最直观也是最简单的思路是,针对第二个字符串string2中每一个字符,一一与第一个字符串string1中每个字符依次轮询比较,看它是否在第一个字符串string1中。

假设n是字符串string1的长度,m是字符串string2的长度,那么此算法,需要O(n*m)次操作,拿上面的例子来说,最坏的情况下将会有16*8 = 128次操作

我们不难写出以下代码:

[cpp:nogutter] view plain copy print ?
  1. #include<iostream>
  2. usingnamespacestd;
  3. intCompareSting(stringLongSting,stringShortSting)
  4. {
  5. for(inti=0;i<ShortString.length();i++)
  6. {
  7. for(intj=0;j<LongString.length();j++)//O(n*m)
  8. {
  9. if(LongString[i]==ShortString[j])//一一比较
  10. {
  11. break;
  12. }
  13. }
  14. if(j==LongString.length())
  15. {
  16. cout<<"false"<<endl;
  17. return0;
  18. }
  19. }
  20. cout<<"true"<<endl;
  21. return1;
  22. }
  23. intmain()
  24. {
  25. stringLongString="ABCDEFGHLMNOPQRS";
  26. stringShortString="DCGSRQPOM";
  27. compare(LongString,ShortString);
  28. return0;
  29. }

#include <iostream> using namespace std; int CompareSting(string LongSting,string ShortSting) { for (int i=0; i<ShortString.length(); i++) { for (int j=0; j<LongString.length(); j++) //O(n*m) { if (LongString[i] == ShortString[j]) //一一比较 { break; } } if (j==LongString.length()) { cout << "false" << endl; return 0; } } cout << "true" << endl; return 1; } int main() { string LongString="ABCDEFGHLMNOPQRS"; string ShortString="DCGSRQPOM"; compare(LongString,ShortString); return 0; }

上述代码的时间复杂度为O(n*m),显然,时间开销太大,我们需要找到一种更好的办法。

1.2、O(mlogm)+O(nlogn)+O(m+n)的排序方法
一个稍微好一点的方案是先对这两个字符串的字母进行排序,然后同时对两个字串依次轮询。两个字串的排序需要(常规情况)O(m log m) + O(n log n)次操作,之后的线性扫描需要O(m+n)次操作

同样拿上面的字串做例子,将会需要16*4 + 8*3 = 88加上对两个字串线性扫描的16 + 8 = 24的操作。(随着字串长度的增长,你会发现这个算法的效果会越来越好)

关于采用何种排序方法,我们采用最常用的快速排序,下面的快速排序的代码用的是以前写的,比较好懂,并且,我执意不用库函数的qsort代码。唯一的问题是,此前写的代码是针对整数进行排序的,不过,难不倒我们,稍微改一下参数,即可,如下:

int Divition(string& str,int left,int right)
{
int base=str[left];
while (left<right)
{
while (left<right && str[right]>base)
{
right--;
}
swap(str[left],str[right]);
while (left<right && str[left]<base)
{
left++;
}
swap(str[right],str[left]);
}
str[left]=base;
return left;
}

void QucikSort(string &str,int left,int right)
{
if (left<right)
{
int i=Divition(str,left,right);
QucikSort(str,left,i-1);
QucikSort(str,i+1,right);
}

}

int Divition(string& str,int left,int right)
{
	int base=str[left];
	while (left<right)
	{
		while (left<right && str[right]>base)
		{
			right--;
		}
		swap(str[left],str[right]);
		while (left<right && str[left]<base)
		{
			left++;
		}
		swap(str[right],str[left]);
	}
	str[left]=base;
	return left;
}

void QucikSort(string &str,int left,int right)
{
	if (left<right)
	{
		int i=Divition(str,left,right);
		QucikSort(str,left,i-1);
		QucikSort(str,i+1,right);
	}

}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值