002字符串包含

2014.6.17

題目描述:

給定兩個分別由字母組成的字符串A和字符串B,字符串B的長度比字符串A短。請問,如何最快地判斷字符串B中所有字母是否都在字符串A裏?

爲了簡單起見,我們規定輸入的字符串只包含大寫英文字母,請實現函數bool StringContains(string &A, string &B)

比如,如果是下面兩個字符串:

String 1:ABCD

String 2:BAD

答案是true,即String2裏的字母在String1裏也都有,或者說String2是String1的真子集。

如果是下面兩個字符串:

String 1:ABCD

String 2:BCE

答案是false,因爲字符串String2裏的E字母不在字符串String1裏。

同時,如果string1:ABCD,string 2:AA,同樣返回true。

方案一:

暴力法——將string2中的每個字符與string1中的進行比較,如果所有的都能匹配則true,否則false。


方案二:

先排序後匹配——排序可以用快排<時間複雜度爲O(nlongn)>,將排好序的兩個字符串進行線性匹配,時間複雜度是O(n+m),因此整體時間複雜度是O(nlongn)+O(mlongm)+O(n+m)。

int partition(string &str,int start, int end)
{
	int key = str[end];
	int i = start - 1 ;
	for(int j=start;j<end;j++)
	{
		if(str[j]<key)
		{
			i++;
			swap(str[i],str[j]);
		}
	}
	swap(str[i+1],str[end]);
	return i+1;
}
void quickSort(string &str, int start, int end)
{
	if(start<end)
	{
		int k = partition(str,start,end);
		quickSort(str,0,k-1);
		quickSort(str,k+1,end);
	}
}

bool stringContain1(string &str1,string &str2)
{
	int n1=str1.length();
	int n2=str2.length();
	quickSort(str1,0,n1-1);
	quickSort(str2,0,n2-1);

	for(int s1=0,s2=0;s2<n2;s2++)
	{
		while((s1<n1) && (str1[s1]<str2[s2]))
		{
			s1++;
		}
		if(s1>=n1 || str1[s1]>str2[s2])
			return false;

	}
	return true;
}

或者排序利用計數排序,然後進行線性匹配

計數排序就是首先掃描一遍數組,將每個元素的排序順序編號存儲起來,然後將確定將各個元素填到相應的位置時間複雜度O(n+m)+O(n+m)=O(n+m),空間複雜度爲O(n+m)

void countSort(string str,string &help_str)
{
	int helparr[26]={0};
	for(int i=0;i<str.length();i++)
	{
		int index = str[i] - 'A';
		helparr[index] +=1;
	}
	for(int j=1;j<26;j++)
	{
		helparr[j] += helparr[j-1];
	}
	for(int k=str.length()-1;k>=0;k--)
	{
		int index = str[k] - 'A';
		int pos = helparr[index]-1;
		help_str[pos] = str[k];
		helparr[index]--;
	}

	cout<<"sortArry: "<<help_str<<endl;
}

bool stringContain2(string &str1,string &str2)
{
	int n1=str1.length();
	int n2=str2.length();
	
	countSort(str1,str1);
	countSort(str2,str2);

	for(int s1=0,s2=0;s2<n2;s2++)
	{
		while((s1<n1) && (str1[s1]<str2[s2]))
		{
			s1++;
		}
		if(s1>=n1 || str1[s1]>str2[s2])
			return false;

	}
	return true;
}

方案三:hash表,時間複雜度O(n+m),段字符串存入hash表,然後用長字符串的元素進行查找,找到繼續,否則爲false。

方案四:利用輔助整型數組初始爲0,由26個元素構成,首先遍歷short_str將其擁有的字符對應的輔助數組元素加1,遍歷long_str,將輔助數組中對應的元素減1,最後判斷輔助數組的元素值,如果有正值,則false,否則爲true。時間和空間複雜度都是O(n+m)。

方案五:利用素數的不可分性,將每個字母與一個素數唯一對應,對於long_sr中的每個元素,找到其對應的素數,然後相乘,形成一個大的整數,然後用這個整數去除short_str中的元素對應的素數,如果有餘數則爲false,除到最後都可整除則爲true。




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章