簡體   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;
        }
        
        };

嗨,這是我在 c++ 中的代碼,我從https://www.geeksforgeeks.org/check-if-two-given-strings-are-isomorphic-to-each-other/中看到了類似的內容,但我的回答顯示它是錯誤的. 誰能告訴我為什么錯了?

你完全誤解了描述。

您的問題表明輸入中字符的任何排列都不會改變答案。 您還假設直方圖是相等的。

性格的Position很重要。 兩個字符串中的每個 position 都會創建一個唯一的對。

這是我通過的代碼:

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);
    }
};

以及可用於測試代碼的測試用例:

s 回答
“一個” “乙” 真的
“啊” “bb” 真的
“ab” “啊” 錯誤的
“aabbcc” “aabcbc” 錯誤的

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

因為你錯過了一個循環。

請注意,它仍然需要更多的極端情況檢查才能使其完全工作。 第二種方法可以正確處理所有情況。

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;
    }
};

但上述解決方案僅適用於字符之間存在直接索引映射的情況。 比如, AAABBCAXXXYYZX 但是bbbaaabaaaabbbba失敗了。 此外,沒有大寫,小寫處理。 您共享的鏈接包含評論中提到的錯誤實現。

下面的解決方案在我測試時有效。

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;
    }
};

這不是關於字謎或直接關於字符頻率的問題。 這是關於模式。 它是關於具有將一個字符串轉換為另一個字符串的逐個字符映射。 AABC 與 XXYZ 同構,但與 BCAA 不同構。

當我們談論同構(相同形式)時,尋找簽名表示通常是個好主意。 因此,我決定定義一個唯一的簽名表示並確定兩個字符串 map 是否具有相同的簽名,而不是確定兩個字符串是否同構。

我使用std::vector<char>作為簽名表示,這樣第一個字符(如果有的話)被分配 0 第二個(以前看不見的)字符 1 等等。

所以像MOON這樣的字符串有簽名{0,1,1,2}因為中間的字符是唯一的重復。 MOONBOOK同構,但與NOON不同。

這種策略的優點是,如果要比較多個字符串以找到相互同構的字符串組,則每個字符串只需要轉換為其簽名一次。

#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;
}

預期 Output: SUCCESS

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM