给定一个等长字符串数组

时间:2018-09-12 22:02:47

标签: c++

给出一个等长字符串数组,检查是否有可能以这样的方式重新排列字符串:在重新排列之后,连续位置处的字符串将相差一个字符。

示例

对于inputArray = [“ aba”,“ bbb”,“ bab”],输出应为 stringsRearrangement(inputArray)= false。

所有重排都不满足描述条件。

对于inputArray = [“ ab”,“ bb”,“ aa”],输出应为 stringsRearrangement(inputArray)= true。

可以通过以下方式重新排列字符串:“ aa”,“ ab”,“ bb”。

代码:

    bool stringsRearrangement(std::vector<std::string> v) {
    sort(v.begin(), v.end());
    int i,j,count=0;
    do {
        for(i=0;i<v.size()-1;i++) {
            count=0; 
            for(j=0;j<v[0].size();j++) 
                if(v[i][j]!=v[i+1][j]) {
                    count++;
                    if(count==2)
                        break;
                }
            if(count!=1) 
                break;

        }
        if(i==v.size()-2 && j==v[0].size()-1 && count==1)
            return true;

    } while(next_permutation(v.begin(),v.end()));

    return false;
}

例如inputArray: ["ab", "bb", "aa"]inputArray: ["a", "b", "c"]的代码无法正常工作,经过4个小时的思考找不到错误的代码。

2 个答案:

答案 0 :(得分:1)

通过子问题拆分函数以简化代码:

std::size_t hamming_distance(const std::string& s1, const std::string& s2)
{
    std::size_t res = 0;
    for (std::size_t i = 0; i != s1.size(); ++i) {
        res += s1[i] != s2[i];
    }
    return res;
#if 0 // or in C++17
    return std::transform_reduce(
        s1.begin(), s1.end(),
        s2.begin(),
        0u,
        std::not_equal_to<>{},
        std::plus<>{});
#endif
}

bool isAnRearrangement(const std::vector<std::string>& v)
{
    return std::adjacent_find(v.begin(), v.end(),
                              [](const std::string& s1, const std::string& s2){
                                  return hamming_distance(s1, s2) != 1;   
                              }) == v.end();
}

bool stringsRearrangement(std::vector<std::string> v) {
    std::sort(v.begin(), v.end());
    do {
        if (isAnRearrangement(v)) {
            return true;
        }
    } while (std::next_permutation(v.begin(),v.end()));
    return false;
}

Demo

然后,您可以轻松地测试每个部分:

  • 您正确计算了hamming_distance("aba", "bbb")吗?
  • isAnRearrangement({"aa", "ab", "bb"})的结果是什么?
  • 依此类推...

对于您的代码,在发生错误的情况下会中断循环,因此您的条件是检查循环是否结束而不至于中断,但是i / j的值应分别为v.size()-1v[0].size()。因此,使用子功能,您将只用return false;而不是break;return true;来代替条件return true;

Demo

答案 1 :(得分:0)

是的,我发现了错误。 i/j的值分别为v.size()-1v[0].size()。下面是真正有效的正确代码,谢谢Jarod42

bool stringsRearrangement(std::vector<std::string> v) {
    sort(v.begin(), v.end());
    int i,j,count=0;
    do {
        for(i=0;i<v.size()-1;i++) {
            count=0; 
            for(j=0;j<v[0].size();j++) 
                if(v[i][j]!=v[i+1][j]) {
                    count++;
                    if(count==2)
                        break;
                }
            if(count!=1) 
                break;

        }
        if(i==v.size()-1 && j==v[0].size() && count==1)
            return true;

    } while(next_permutation(v.begin(),v.end()));

    return false;
}