C++ 比较字符串模式的更好解决方案。?

C++ 比较字符串模式的更好解决方案。?,c++,algorithm,C++,Algorithm,任务:创建一个函数,如果两个字符串共享相同的字母模式,则返回true,否则返回false 我找到了解决这项任务的方法,但我认为它可以更简单、更简短。我将所有相同的字母转换为两个字符串的特定字符。然后在流程结束时检查它们是否相同。有更简单的解决方案吗 #include <iostream> #include <string> using namespace std; bool LetterPattern(string str1, string str2) {

任务:创建一个函数,如果两个字符串共享相同的字母模式,则返回true,否则返回false

我找到了解决这项任务的方法,但我认为它可以更简单、更简短。我将所有相同的字母转换为两个字符串的特定字符。然后在流程结束时检查它们是否相同。有更简单的解决方案吗

#include <iostream>
#include <string>

using namespace std;

bool LetterPattern(string str1, string str2) { 
    // Controlling whether they have same size or not
    if (str1.length() != str2.length()) {
        return false; 
    }
    else {
        // Checking for ABC XYZ format type 
        int counter = 0;
        for (int i = 0; i < str1.length()-1; i++) {
            for (int k = i+1; k < str1.length(); k++) {
                if (str1[i] == str1[k]) {
                    counter++;
                }
            }
        }
        int counter2 = 0;
        for (int i = 0; i < str2.length() - 1; i++) {
            for (int k = i + 1; k < str2.length(); k++) {
                if (str2[i] == str2[k]) {
                    counter2++;
                }
            }
        }
        
        if (counter == 0 && counter2 == 0) {
            return true;
        }
        // I added the above part because program below couldn't return 1 for completely different letter formats
        // like XYZ ABC DEF etc.
        
        //Converting same letters to same chars for str1
        for (int i = 0; i < str1.length()-1; i++) {
            for (int k = i+1; k < str1.length(); k++) { 
                if (str1[i] == str1[k]) {
                    str1[k] = (char)i;
                }
            }
            str1[i] = (char)i;
        }
    }
    //Converting same letters to same chars for str1
    for (int i = 0; i < str2.length() - 1; i++) {
        for (int k = i + 1; k < str2.length(); k++) { 
            if (str2[i] == str2[k]) {
                str2[k] = (char)i;
            }
        }
        str2[i] = (char)i;
    }
    if (str1 == str2) { // After converting strings, it checks whether they are same or not
        return true;
    }
    else {
        return false;
    }
}
    

int main(){
    cout << "Please enter two string variable: ";
    string str1, str2;
    cin >> str1 >> str2;
    cout << "Same Letter Pattern: " << LetterPattern(str1, str2);

    system("pause>0");
}
#包括
#包括
使用名称空间std;
bool字母模式(字符串str1,字符串str2){
//控制它们是否具有相同的大小
如果(str1.length()!=str2.length()){
返回false;
}
否则{
//检查ABC XYZ格式类型
int计数器=0;
对于(int i=0;istr1>>str2;

如果我理解正确并且:

AABB - CCDD = true
AAFFG - AAFGF = false
asdasd - qweqwe = true
这不是模式,而是通过替换第一个字符串来检查第二个字符串是否是加密的结果。您可以通过尝试构建替换表以更简单的方式来完成。如果失败,即源和结果之间存在多个关联,则结果为
false

最简单的情况是,我们必须检查整个字符串。如果我们需要发现,如果任何子字符串都是第二个字符串中包含的模式的替换,那么复杂度就会平方:

#include <string>
#include <vector>
#include <map>
#include <optional>
#include <limits>

bool is_similar (const std::string& s1, const std::string& s2)
{
    if(s1.length() != s2.length()) return false;
    using TCh = std::decay_t<decltype(s1)>::value_type;
    // for non-unicode characters can use an array
    //std::optional<TCh> table[ std::numeric_limits<TCh>::max ];
    // std::optional used for clarity, in reality may use `TCh`
    // and compare with zero char
    std::map< TCh, std::optional<TCh>> table;
    
    for (size_t it = 0; it < s1.length(); ++it)
    {
       if( table[s1[it]].has_value() && table[s1[it]] != s2[it] ) return false;
       if( table[s2[it]].has_value() && table[s2[it]] != s1[it] ) return false;
       table[s1[it]] = s2[it];
       //table[s2[it]] = s1[it]; if symmetric
    }
    return true;
}
#包括
#包括
#包括
#包括
#包括
bool与之类似(const std::string&s1,const std::string&s2)
{
如果(s1.length()!=s2.length())返回false;
使用TCh=std::decage\u t::value\u type;
//对于非unicode字符,可以使用数组
//std::可选表格[std::数值_限制::最大];
//std::为清晰起见,可选择使用,实际上可以使用'TCh'`
//并与零字符进行比较
标准::映射表;
对于(size_t it=0;it
首先,正如您所做的那样,我们可以比较两个字符串的大小。 如果他们平等,我们继续

通过迭代其中一个字符串,我们可以填充一个映射。映射的键是第一个字符串中的字符,其值是第二个字符串中的对应字符

通过到达第n个字符,我们检查是否有与此字符相同的密钥

如果是:请检查等于第二个字符串第n个字符的值

如果否:我们向映射添加一个新的键值。(键值是第一个字符串的第n个字符,值是第二个字符串的第n个字符)

一,。 在这样做之后,我们应该对另一个字符串再次这样做。我的意思是,如果在第一步中,第一个字符串的字符是键,那么在第二步中,我们应该以第二个字符串的字符成为键的方式替换该字符串

如果两者都为真,则答案为真,否则为假

二,。 我们可以避免向映射中添加重复的值,而不是替换字符串并重复迭代

要理解第1段和第2段,请想象在字符串“ABC”和“ZZZ”上进行1次迭代

请注意,可以使用数组代替映射。

一种简单(可能不是很有效)的方法:

#包括
#包括
使用名称空间std;
内部主(空){
字符串s1、s2;
无序映射子;
couts1>>s2;
如果(s1.length()!=s2.length())

cout当您想查看一个字符串是否是另一个字符串的凯撒密码时,可以执行以下操作:

bool LetterPatternImpl(const std::string& str1, const std::string& str2) { 
    if (str1.length() != str2.length()) { return false; }

    std::array<std::optional<char>, 256> mapping; // char has limited range,
                                                  // else we might use std::map
    for (std::size_t i = 0; i != str1.length(); ++i) {
        auto index = static_cast<unsigned char>(str1[i]);

        if (!mapping[index]) { mapping[index] = str2[i]; }
        if (*mapping[index] != str2[i]) { return false; }
    }
    return true;
}

bool LetterPattern(const std::string& str1, const std::string& str2) {
    // Both ways needed
    // so ABC <-> ZZZ should return false.
    return LetterPatternImpl(str1, str2) && LetterPatternImpl(str2, str1);
}
bool-LetterPatternImpl(常量std::string和str1,常量std::string和str2){
if(str1.length()!=str2.length()){返回false;}
std::数组映射;//字符的范围有限,
//否则我们可能会使用std::map
对于(std::size_t i=0;i!=str1.length();++i){
自动索引=静态_cast(str1[i]);
如果(!mapping[index]){mapping[index]=str2[i];}
if(*mapping[index]!=str2[i]){返回false;}
}
返回true;
}
bool字母模式(常量标准::字符串和str1,常量标准::字符串和str2){
//两方面都需要
//所以abczzz应该返回false。
返回LetterPatternImpl(str1,str2)和&LetterPatternImpl(str2,str1);
}
不确定是否更好,但C++17解决方案基于第一个字符串的字母构建正则表达式并与第二个字符串匹配:<
#include <iostream>
#include <string>
#include <unordered_map>
#include <utility>
#include <set>

bool letterPattern(const std::string& s1, const std::string& s2) {

    // Here we will store the result of the function
    bool result{ s1.length() == s2.length() };

    // And here all associations
    std::unordered_map<char, std::set<char>> association{};

    // Add associations. Stop if result = false
    for (size_t index{}; result && index < s1.length(); ++index)
        if (const auto& [iter, ok] {association[s1[index]].insert(s2[index])}; ok)
            result = association[s1[index]].size() == 1;

    return result;
}
// Some driver test code
int main() {
    std::vector<std::pair<std::string,std::string>> testData{
        {"AABB", "CCDD"},
        {"ABAB", "CDCD"},
        {"AAFFG", "AAFGF"},
        {"asdasd", "qweqwe"}
    };

    for (const auto& p : testData)
        std::cout << std::boolalpha << letterPattern(p.first, p.second) << "\t for: '" << p.first << "' and '" << p.second << "'\n";

    return 0;
}