简体   繁体   English

检查两个给定的字符串是否彼此同构c++,不知道为什么错了

[英]Check if two given strings are isomorphic to each other c++, not sure why it's wrong


class Solution {
public:
    bool isIsomorphic(string s, string t) {
        vector <int> sfreq (26,0);
        vector <int> tfreq (26,0);
        for (int i=0; i<s.size(); i++) {
            sfreq[s[i]-'a']++;
            tfreq[t[i]-'a']++; 
        }
        
        if (sfreq != tfreq) {
            return false;
        }
        return true;
        }
        
        };

Hi, this is my code in c++, I saw something similar from https://www.geeksforgeeks.org/check-if-two-given-strings-are-isomorphic-to-each-other/ but my answer shows it's wrong.嗨,这是我在 c++ 中的代码,我从https://www.geeksforgeeks.org/check-if-two-given-strings-are-isomorphic-to-each-other/中看到了类似的内容,但我的回答显示它是错误的. Can anyone please tell me why it's wrong?谁能告诉我为什么错了?

You completely misunderstood the description.你完全误解了描述。

Your question suggests that any permutation of characters in input do not change answer.您的问题表明输入中字符的任何排列都不会改变答案。 Also you assumed that histograms are equal.您还假设直方图是相等的。

Position of character is important.性格的Position很重要。 Each position in both strings creates a unique pair.两个字符串中的每个 position 都会创建一个唯一的对。

Here my code which passed:这是我通过的代码:

class Solution {
public:
    static bool canMapInOneDirection(std::string_view s, std::string_view t)
    {
        const auto n = s.size();
        std::array<char, 128> mapping{};
        for(size_t i = 0; i < n; ++i) {
            if (mapping[s[i]] == 0) mapping[s[i]] = t[i];
            else if (mapping[s[i]] != t[i]) return false;
        }
        return true;   
        
    }
    bool isIsomorphic(string s, string t)
    {
        return s.size() == t.size() && canMapInOneDirection(s, t) && canMapInOneDirection(t, s);
    }
};

And test cases you can use to test your code:以及可用于测试代码的测试用例:

s s t answear回答
"a" “一个” "b" “乙” true真的
"aa" “啊” "bb" “bb” true真的
"ab" “ab” "aa" “啊” false错误的
"aabbcc" “aabbcc” "aabcbc" “aabcbc” false错误的

https://godbolt.org/z/61EcTK5fq https://godbolt.org/z/61EcTK5fq

Because you are missing a loop.因为你错过了一个循环。

Note that, it still requires more corner case checking to make it fully work.请注意,它仍然需要更多的极端情况检查才能使其完全工作。 The second approach properly handles all cases.第二种方法可以正确处理所有情况。

class Solution {
public:
    bool isIsomorphic(string s, string t) {
        vector <int> sfreq (26,0);
        vector <int> tfreq (26,0);

        for (int i=0; i < s.size(); i++) {
            sfreq[s[i]-'a']++;
            tfreq[t[i]-'a']++; 
        }
        
        // character at the same index (can be different character) should have the same count.
        for(int i= 0; i < s.size(); i++)
            if (sfreq[s[i]-'a'] != tfreq[t[i]-'a']) return false;

        return true;
    }
};

But the above solution only works if there is direct index mappping between characters.但上述解决方案仅适用于字符之间存在直接索引映射的情况。 Like, AAABBCA and XXXYYZX .比如, AAABBCAXXXYYZX But fails for bbbaaaba and aaabbbba .但是bbbaaabaaaabbbba失败了。 Also, no uppercase, lowercase handled.此外,没有大写,小写处理。 The link you shared contains the wrong implementation which is mentioned in the comment.您共享的链接包含评论中提到的错误实现。

The solution below works as I tested.下面的解决方案在我测试时有效。

class Solution {
public:
    bool isIsomorphic(string s, string t) {
        vector<int> scount(128, -1), tcount(128, -1);
        for (int i = 0; i < s.size(); ++i) {
            auto schar = s[i], tchar = t[i];
            if (scount[schar] == -1) {
                scount[schar] = tchar;
                if (tcount[tchar] != -1) return false;
                else tcount[tchar] = schar;
            } else if (scount[schar] != tchar) return false;
        }
        return true;
    }
};

This not a question about anagrams or directly about character frequencies.这不是关于字谜或直接关于字符频率的问题。 It is about pattern.这是关于模式。 It's about having a character-by-character mapping that makes one string into the other.它是关于具有将一个字符串转换为另一个字符串的逐个字符映射。 AABC is isomorphic to XXYZ but not isomorphic to BCAA. AABC 与 XXYZ 同构,但与 BCAA 不同构。

When we talk about Isomorphism (same form) it's often a good idea to look for a signature representation.当我们谈论同构(相同形式)时,寻找签名表示通常是个好主意。 So instead of determining if two strings are isomorphic I've decided to define a unique signature representation and determine isomorphism if two strings map to the same signature.因此,我决定定义一个唯一的签名表示并确定两个字符串 map 是否具有相同的签名,而不是确定两个字符串是否同构。

I've used std::vector<char> for the signature representation such that the first character (if any) is assigned 0 the second (previously unseen) character 1 and so on.我使用std::vector<char>作为签名表示,这样第一个字符(如果有的话)被分配 0 第二个(以前看不见的)字符 1 等等。

So a string like MOON has signature {0,1,1,2} because the middle characters are the only repeats.所以像MOON这样的字符串有签名{0,1,1,2}因为中间的字符是唯一的重复。 MOON is isomorphic to BOOK but not NOON . MOONBOOK同构,但与NOON不同。

The advantage of such a strategy is that if many strings are to be compared to find groups of mutually isomorphic strings each string need only be converted to its signature once.这种策略的优点是,如果要比较多个字符串以找到相互同构的字符串组,则每个字符串只需要转换为其签名一次。

#include <iostream>
#include <string>
#include <vector>
#include <unordered_map>


std::vector<char> get_signature(const std::string& str){
    std::vector<char> result;
    std::unordered_map<char,char> map;
    char curr{1};
     
  for(auto cchar : str){
    char& c{map[cchar]};
    if(c==0){
        c=curr++;
     }
     result.emplace_back(c-1);
   }
    return result;
}


int check_signature(const std::string& str, const std::vector<char>& expect ){
    const auto result{get_signature(str)};
    return result==expect?0:1;
}


int main() {
     int errors{0};
     {
        const std::string str{"ABCDE"};
        const std::vector<char> signat{0,1,2,3,4};
        errors+=check_signature(str,signat);
     }
     {
        const std::string str{"BABY"};
        const std::vector<char> signat{0,1,0,2};
        errors+=check_signature(str,signat);
     }
     {
        const std::string str{"XXYZX"};
        const std::vector<char> signat{0,0,1,2,0};
        errors+=check_signature(str,signat);
     }
     {
        const std::string str{"AABCA"};
        const std::vector<char> signat{0,0,1,2,0};
        errors+=check_signature(str,signat);
     }
     {
        const std::string str{""};
        const std::vector<char> signat{};
        errors+=check_signature(str,signat);
     }
     {
        const std::string str{"Z"};
        const std::vector<char> signat{0};
        errors+=check_signature(str,signat);
     }
     if(get_signature("XXYZX")!=get_signature("AABCA")){
        ++errors;
     }
     
      if(get_signature("MOON")==get_signature("AABCA")){
        ++errors;
     }
     if(get_signature("MOON")!=get_signature("BOOK")){
        ++errors;
     }
     if(get_signature("MOON")==get_signature("NOON")){
        ++errors;
     }

     if(errors!=0){
        std::cout << "ERRORS\n";
     }else{
        std::cout << "SUCCESS\n";
     }
    return 0;
}

Expected Output: SUCCESS预期 Output: SUCCESS

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM