微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

优化和提高比较字符串的递归算法的速度

如何解决优化和提高比较字符串的递归算法的速度

以下算法是这样工作的:给定两个字符串,如果字符串彼此相等而不管它们的元音如何,则返回 true。

"water" 和 "wtr" = true

"hello" 和 "hll" = true

"violinn" 和 "vln" = false

设置了一些参数。它必须递归解决,而不是迭代解决。此外,不允许简单地从两个字符串中删除元音并进行比较。

这是我写的一个程序来解决这个问题(调用isstringEqual("water","wtr")):

给定一个字符串和一个起始索引,它会调用自己直到找到辅音的索引。如果不存在辅音,则返回 -1。

    static int findNonVowel(String str,int strIndex) {

        if (str.length() == strIndex) return -1;

        if ("aeIoUAEIoU".indexOf(str.charat(strIndex)) == -1) return strIndex;

        strIndex++;
        return findNonVowel(str,strIndex);
    }

现在,这是解决方案的主要部分。

    static boolean isstringEqual(String strA,String strB) {
        return doIsstringEqual(strA,strB,0);
    }

    static boolean doIsstringEqual(String strA,String strB,int strAIndex,int strBIndex) {
        if (strA.length() > strB.length() && strB.length() == strBIndex && findNonVowel(strA,strAIndex) != -1)         
            return false;

        if (strB.length() > strB.length() && strA.length() == strAIndex && findNonVowel(strB,strBIndex) != -1)         
            return false;

        if (strA.length() == strAIndex || strB.length() == strBIndex) return true;

        if (strA.charat(strAIndex) != strB.charat(strBIndex)) {
            strAIndex = findNonVowel(strA,strAIndex);
            strBIndex = findNonVowel(strB,strBIndex);

            if (strA.charat(strAIndex) != strB.charat(strBIndex) && (strAIndex != -1  && strBIndex != -1)) {
                return false;
            }
        }

        strAIndex++; strBIndex++;
        return doIsstringEqual(strA,strAIndex,strBIndex);
    }

首先,我们检查两个字符串中的一个是否大于另一个,并且通过递归,它们是否超过了另一个字符串的长度。这是为了防止像“violinn”和“vln”这样的误报,但仍然允许通过 findNonVowel 使用“violiniii”和“vln”。

如果找到的两个字符彼此不匹配,我们会为每个字符获取最近的辅音的索引,并进行比较。如果它们仍然不相等,并且两个字符串都不是从起始索引开始的元音,则字符串不相等。

我正在寻找解决此问题的内存效率更高的解决方案。我已经研究过子字符串,但根据我的理解,这会慢得多,因为它们会在每次递归调用时实例化一个新字符串,而这只是在调用相同的方法

我也愿意接受可以对算法本身进行的任何改进,无论是简化算法还是修剪任何样板。

解决方法

在递归思考时,问自己以下问题通常很有用:如果我可以以某种方式减少我的输入,我将如何使用减少的输入的子结果来计算当前结果?

当我想到减少字符串时,我想到的第一件事就是去掉它们的第一个字符。然后想法来了:如果一个字符串以元音开头,我可以跳过它,结果将与丢弃该字符并比较其余字符串相同;如果两个头都是辅音,那么它们必须匹配。此外,如果我们有空字符串,则基本情况。

这是一个伪代码:

function bool equal(s,z,start_s,start_z): 

    // s starts with a vowel
    if start_s < len(s) and s[start_s].isVowel(): 
        return equal(s,start_s+1,start_z)

    // z starts with a vowel
    if start_z < len(z) and z[start_z].isVowel(): 
        return equal(s,start_z+1)

    // no vowels,maybe an empty string?
    if start_s == len(s) or start_z == len(z):
        // if we have an empty string,they should both be empty
        return start_s-len(s) == start_z - len(z)

    // no empty string,no vowels: consonants should match 
    return s[start_s] == z[start_z] and equal(s,start_z+1)

该算法在时间上是线性的,并且在额外内存中是常数。

希望对您有所帮助!

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。