C++ 检查C+中的一个字符串是否是另一个字符串的置换+;
我一直在研究一些编程问题,试图用数据结构和算法刷新我的记忆。问题是检查一个字符串是否是另一个字符串的排列 我看到的许多代码解决方案对每个字符串进行排序,然后检查排序后的字符串是否彼此相等。这通常是通过以下方式完成的:C++ 检查C+中的一个字符串是否是另一个字符串的置换+;,c++,string,algorithm,C++,String,Algorithm,我一直在研究一些编程问题,试图用数据结构和算法刷新我的记忆。问题是检查一个字符串是否是另一个字符串的排列 我看到的许多代码解决方案对每个字符串进行排序,然后检查排序后的字符串是否彼此相等。这通常是通过以下方式完成的: sort(strOne.begin(), strOne.end()); sort(strTwo.begin(), strTwo.end()); for (int i = 0; i < strOne.length(); i++) { if (strO
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循环来迭代字符串
提前谢谢 您可以使用str1.compare(str2),它将按字母顺序比较字符串,如果它们相等,则返回0
但是,您的解决方案具有O(nlogn)复杂性,并且可以在线性时间内求解…请在所有可能的条件下显式返回true或false。否则你可能得不到想要的结果 在第一个代码块中,在for循环之外没有定义返回值。 因此,如果两个字符串相等,函数将显式不返回任何内容。 在第二段代码中,在if语句之外没有定义返回值。 因此,如果两个字符串不相等,函数将显式不返回任何内容。STL方法是:
std::string str0, str1;
bool IsPermutation = std::is_permutation(str0.begin(), str0.end(), str1.begin(), str1.end());
是的,您可以直接比较字符串。在函数中使用字符串比较的正确方法是
return str1 == str2;
迂回的道路
if (str1 == str2) {
return true;
}
else {
return false;
}
它有一些主要的缺点:它的长度是原来的几倍,很容易忘记else
部分(您刚刚忘记了),而且在重构过程中很容易中断
std::sort( strOne.begin(), strOne.end() );
std::sort( strTwo.begin(), strTwo.end() );
return strOne == strTwo;
这就足够了
我的建议是使用
std::unordered_map
i、 e
更好的
std::无序地图解决方案
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;
作为对其他答案的补充,如果您事先知道两个字符串('a'-'z')或类似字符串的字符范围,那么您可以在线性时间内解决问题。在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;
}
#包括
#包括
#包括
#包括
使用名称空间std;
int main()
{
a、b串;
cin>>a>>b;
字母的矢量频率rsa(26,0);
矢量频率b(26,0);
用于(字符c:a)
字母的频率a[c-'a']++;
用于(字符c:b)
字母B的频率[c-'a']++;
bool isPermutation=true;
对于(int i=0;i<26;++i)
{
if(LettersA[i]!=LettersB[i]的频率)
{
isPermutation=false;
打破
}
}
if(isPermutation)
coutstd::is_permutation
。只要使用它。或者,如果你想知道它是如何工作的,你可以阅读它的代码。举个例子……没有合理的理由推荐str1。比较(str2)!=0
overstr1==str2
;我只见过缺少运算符重载的语言程序员提出的这样一个建议。不过,线性时间的重要意义在于:只需迭代第一个字符串,执行++freq[s[I]]
,其中freq
可以通过字符值进行索引,默认值为0,然后第二个字符串--freq[s[i]
,然后检查没有非零值。(仔细考虑一下,如果字符串长度不同,假设返回false
,可以使用if(--freq[s[i]<0)返回false;
用于早期纾困,然后在返回true之前不需要最后检查非零。如果str1.compare(str2)
有效,则std::set_symmetric_difference
也应有效
if( strOne.size() != strTwo.size() ) return false;
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;
return std::is_permutation( strOne.begin(), strOne.end(), strTwo.begin(), strTwo.end() );
#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;
}