检查两个字符串是否为字谜

时间:2018-11-30 12:46:11

标签: c++ string algorithm anagram onlinejudge

问题有两个字符串,请检查两个给定的字符串是否彼此 anagram 。字符串的字谜是另一个包含相同字符的字符串,只有字符顺序可以不同。例如,“ act”和“ tac”是彼此相似的词。

输入: 输入的第一行包含一个整数T,它表示测试用例的数量。每个测试用例在一行中仅由两个“小写”字符串组成。

输出: 如果两个字符串都为anagram,则打印“ YES”而不加引号,否则打印“ NO”。

约束: 1≤T≤30 1≤| s | ≤10 ^ 16

示例: 输入: 1个 过敏

输出: 否

我的方法是先检查字符串的长度,如果它们不相等,则只需打印出 NO ;如果它们相等,则对字符串进行排序,然后对元素进行明智的比较。

我在一些简单的输入上获得了正确的输出,但是在复杂的输入上却没有得到正确的输出,因为我的代码无法通过所有测试用例。我无法弄清我的错误。

#include <iostream>
using namespace std;
#include<string>
#include<algorithm>
int main() {
    int n, t=0;
    cin>>n;
    for(int i=0;i<n;i++)
    {
        string a,b;
        cin>>a>>b;
        cout<<"\n";
        if(a.length()!=b.length())
        {
            cout<<"NO";
        }
        else
        {
            sort(a.begin(),a.end());
            sort(b.begin(),b.end());
            for(int i=0;i<a.length();i++)
            {
                if(a[i]!=b[i])
                {
                    cout<<"NO";
                    break;
                }
                t++;
            }
           if(t==a.length())
           {
               cout<<"YES";
           }
        }
    }

    return 0;
}

1 个答案:

答案 0 :(得分:2)

您的代码似乎只给出2个预期的1个响应。 问题是您没有重置t变量;)因此,它总是在递增。 运行示例:https://ideone.com/IYK6Ad

输入测试:

2
aab baa
a a

输出:

YES

固定代码:

#include <iostream>
using namespace std;
#include<string>
#include<algorithm>
int main() {
    int n, t=0;
    cin>>n;
    for(int i=0;i<n;i++)
    {
        string a,b;
        cin>>a>>b;
        if(a.length()!=b.length())
        {
            cout<<"NO\n";
        }
        else
        {
            sort(a.begin(),a.end());
            sort(b.begin(),b.end());
            if(a != b)
            {
                cout<<"NO\n";
            }
            else
            {
                cout<<"YES\n";
            }
        }
    }

    return 0;
}

Example run


有关改进此算法的一些提示。 目前,我们仅考虑1个用于检查字谜的测试用例。

因此,在您的情况下,您拥有2 * O(n * log n) complexity主要是由于std::sort(检查复杂性)

检查是否有不同的大小是一种特殊情况。快速取胜。因此,您可以保留它,但可能测试程序不会使用这些;)

它的通过当然会影响多少个测试用例和多少个测试用例。

改善的想法:

  1. 计算每个字符(我们可以使用std::map<char,int>,但是访问map中的元素也需要一些时间。因此,在我们的情况下,我们对输入数据有所了解,因此可以从中受益。它应该是ASCII数据,因此我们可以放入固定数组中。)
  2. 如果特定字符的数量不同,我们就会知道答案!

对于这种解决方案,我们将获得O(n+m) + O(min(n,m)),其中n是字符串a的长度,而mb的长度。更好的复杂性。

示例:

#include <iostream>
#include <string>
#include <algorithm>
#include <vector>

using namespace std;

int main()
{
    int n;
    cin>>n;
    std::vector<int> aCountOfChars(256, 0);
    std::vector<int> bCountOfChars(256, 0);

    for(int i=0;i<n;i++)
    {
        string a,b;
        cin>>a>>b;
        std::vector<int> aCountOfChars(256, 0);
        std::vector<int> bCountOfChars(256, 0);

        for(int i=0;i<a.size();++i)
        {
            ++aCountOfChars[a[i]];  
        }
        for(int i=0;i<b.size();++i)
        {
            ++bCountOfChars[b[i]];  
        }

        if(aCountOfChars == bCountOfChars)
        {
            cout<<"YES\n";
        }
        else
        {
            cout<<"NO\n";
        }
    }
    return 0;
}

Run me


要检查的一些测试用例:

7
a b
aab baa
a a
aaaaaaaaaaaaaaaaaaaaaaaaaaaaa b
aabba bbaaa
act tac
allergy allergic

Nice article about such problem