我一直在研究一些编程问题,试图用数据结构和算法来刷新我的记忆。问题是检查一个字符串是否是另一个字符串的排列。
我见过的很多代码解决方案都会对每个字符串进行排序,然后检查排序的字符串是否彼此相等。这通常通过以下方式完成:
sort(strOne.begin(), strOne.end());
sort(strTwo.begin(), strTwo.end());
for (int i = 0; i < strOne.length(); i++)
{
if (strOne[i] != strTwo[i])
{
return false;
}
}
但是,我想知道在排序字符串之后你是否可以直接比较字符串而不是使用for循环。例如,
if (strOne == strTwo) {
return true;
}
我是否缺少第二种选择不起作用的东西?我觉得我错过了一个基本概念,因为似乎大多数解决方案都有for循环来迭代字符串。
提前致谢!
答案 0 :(得分:4)
你可以使用str1.compare(str2)来比较字符串,如果它们相等则返回0。
但是,你的解决方案是采用O(nlogn)复杂度,它可以在线性时间内解决......
答案 1 :(得分:2)
请在所有可能的条件下明确返回true或false。否则你可能得不到理想的结果。
在第一个代码块中,没有在for循环外定义的返回值。 所以,如果两个字符串相等,显式地你的函数将不会返回任何内容。
在第二个代码块中,您没有在if语句之外定义的返回值。 所以,如果两个字符串不相等,显式地你的函数将不会返回任何内容。
答案 2 :(得分:1)
只是为了补充其他答案,如果您事先知道两个字符串的字符范围(&#39; a&#39; - &#39; z&#39;)或类似的字符,那么你可以在线性时间内解决问题。在O(n log n)中解决它可能没问题,但情况并非总是如此。
这是我的版本来解决这个问题。它使用的事实是,如果两个单词的每个字符的频率相等,则可以将其重新排列到另一个字符中。
#include <string>
#include <vector>
#include <map>
#include <iostream>
using namespace std;
int main()
{
string a, b;
cin >> a >> b;
vector<int> frequencyOfLettersA(26, 0);
vector<int> frequencyOfLettersB(26, 0);
for(char c : a)
frequencyOfLettersA[c - 'a']++;
for(char c : b)
frequencyOfLettersB[c - 'a']++;
bool isPermutation = true;
for(int i = 0; i < 26; ++i)
{
if(frequencyOfLettersA[i] != frequencyOfLettersB[i])
{
isPermutation = false;
break;
}
}
if(isPermutation)
cout << "Yes" << endl;
else
cout << "No" << endl;
}
答案 3 :(得分:0)
STL的方式是:
std::string str0, str1;
bool IsPermutation = std::is_permutation(str0.begin(), str0.end(), str1.begin(), str1.end());
答案 4 :(得分:0)
是的,你可以直接比较字符串。在函数中使用字符串比较的正确方法是
return str1 == str2;
迂回的方式
if (str1 == str2) {
return true;
}
else {
return false;
}
有一个主要缺点:它的时间要长几倍,很容易忘记else
部分(你刚刚做过),而且在重构过程中它更容易破解。 / p>
答案 5 :(得分:0)
std::sort( strOne.begin(), strOne.end() );
std::sort( strTwo.begin(), strTwo.end() );
return strOne == strTwo;
就足够了。
我的建议是使用std::unordered_map
即
std::unordered_map< char, unsigned > umapOne;
std::unordered_map< char, unsigned > umapTwo;
for( char c : strOne ) ++umapOne[c];
for( char c : strTwo ) ++umapTwo[c];
return umapOne == umapTwo;
作为优化,您可以在顶部添加解决方案
if( strOne.size() != strTwo.size() ) return false;
更好的std::unordered_map
解决方案,
if( strOne.size() != strTwo.size() ) return false; // required
std::unordered_map< char, int > umap;
for( char c : strOne ) ++umap[c];
for( char c : strTwo ) if( --umap[c] < 0 ) return false;
return true;
如果您需要在不知道如何解决问题的情况下解决问题,可以使用std::is_permutation
return std::is_permutation( strOne.begin(), strOne.end(), strTwo.begin(), strTwo.end() );