在C ++中检查一个字符串是否是另一个字符串的排列

时间:2016-06-07 02:50:51

标签: c++ string algorithm

我一直在研究一些编程问题,试图用数据结构和算法来刷新我的记忆。问题是检查一个字符串是否是另一个字符串的排列。

我见过的很多代码解决方案都会对每个字符串进行排序,然后检查排序的字符串是否彼此相等。这通常通过以下方式完成:

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循环来迭代字符串。

提前致谢!

6 个答案:

答案 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() );