如果两个字符串中的字符一样,出现次数也一样,只是出现的顺序不一样,则认为这两个字符串是兄弟字符串。例如:“bad”和“adb”即为兄弟字符串。现提供一个字符串,如何在字典中快速找到它的兄弟字符串?
思路一:蛮力查找
因为字符串a,b的长度、所含有的字符都是一样的,所以可以使用b的每一个字符与a中的每一个字符进行比较,若出现一个不相同的字符则返回false;字符出现的次数不一样也返回false。
问题1:如果字符串中的一个/几个字符出现的次数不为1时,需要统计每个字符出现的次数,这就意味着每次的暴力查找前需要知道字符串b的中各个字符出现的次数。
每次都需要将主串a遍历一次。
思路二:分别将字符串a和b排序(按照相同的规则),然后进行对应位置的匹配即可,若有一位不同即返回false。
思路三:哈希表的使用(不可行)时间复杂度O(m+n) 思路参考性很强
先将字符串a中的所有字符都放入一个散列表(hash table)中,然后轮询字符串b,看b中的每一个字符是否都在散列表里。
由于涉及到字符的次数必须一样,在这样的情况即使两个字符串不一样,输出也会是兄弟串:
string a ="babbda";
string b ="adbbaa";
不过这种方法在判断字符串的包含问题上效果还是很好的。
C/C++代码:
//思路一:暴力查找 时间复杂度O(n^2) n为字符串的长度
#include"stdafx.h"
#include<iostream>
using namespace std;
bool Ref(string a, string b)
{
for (int i = 0; i < b.length(); i++)
{
int j = 0;
while (a[j] != b[i] && j < a.length())
{
j++;
}
if (j >= a.length())
{
return false;
}
}
return true;
}
int main()
{
string a = "bae";
string b = "adb";
bool flag=Ref(a, b);
if (flag == true)
{
cout << "Yes,两个字符串是兄弟字符串." << endl;
}
else
{
cout << "Sorry,两个字符串不是兄弟字符串." << endl;
}
return 0;
}
//当字符串中的一个/几个字符出现的次数不为1时
//暴力查找(改进版)
#include"stdafx.h"
#include<iostream>
using namespace std;
bool Ref(string a, string b)
{
if (a.length() != b.length())
{
return false;
}
int count2[26] = { 0 };
for (int k = 0; k < b.length(); k++)
{
int pp = b[k] - 'a';
count2[pp]++;
}
for (int i = 0; i < b.length(); i++)
{
bool flg = false;
int j = 0;
int count[26] = { 0 };
while (j < a.length())
{
if (a[j] != b[i])
{
j++;
}
else
{
int p = a[j] - 'a';
count[p]++;
cout << count2[p] << endl;
if (count[p] == count2[p])
{
flg = true;
j++;
}
else
{
j++;
}
}
}
if (flg==false)
{
return false;
}
}
return true;
}
int main()
{
string a = "baaedae";
string b = "adbbea";
bool flag=Ref(a, b);
if (flag == true)
{
cout << "Yes,两个字符串是兄弟字符串." << endl;
}
else
{
cout << "Sorry,两个字符串不是兄弟字符串." << endl;
}
return 0;
}
//思路二:先排序再匹配
//时间复杂度:快速排序O(2log(n))+匹配O(n)
#include"stdafx.h"
#include<iostream>
#include<algorithm>
using namespace std;
//查询
bool Ref(string &a, string &b)
{
int i, j;
if (a.length() != b.length())
{
return false;
}
sort(a.begin(), a.end());
sort(b.begin(), b.end());
for (i = 0, j = 0; i < a.length() && j < b.length();)
{
if (a[i] == b[j])
{
i++;
j++;
}
else
{
return false;
}
}
return true;
}
int main()
{
string a = "babeda";
string b = "adbbea";
bool flag=Ref(a, b);
if (flag == true)
{
cout << "Yes,两个字符串是兄弟字符串." << endl;
}
else
{
cout << "Sorry,两个字符串不是兄弟字符串." << endl;
}
return 0;
}
“哈希表”法,仅供参考:
//思路三:使用哈希表(不可行)
#include"stdafx.h"
#include<iostream>
#include<algorithm>
using namespace std;
//查询
bool Ref(string &a, string &b)
{
if (a.length() != b.length())
{
return false;
}
int hash = 0;
for (int i = 0; i < a.length(); i++)
{
hash |= (1 << (a[i]-'a'));
}
cout << hash << endl;
for (int j = 0; j < b.length(); j++)
{
if ((hash & (1 << (b[j] - 'a'))) == 0)
{
return false;
}
}
return true;
}
int main()
{
string a = "babeda";
string b = "adbbeag";
bool flag=Ref(a, b);
if (flag == true)
{
cout << "Yes,两个字符串是兄弟字符串." << endl;
}
else
{
cout << "Sorry,两个字符串不是兄弟字符串." << endl;
}
return 0;
}