【问题标题】:Keep getting out of bound exception不断越界异常
【发布时间】:2013-11-28 08:46:32
【问题描述】:

我在 C# 中实现了以下两种方法

private static string FindLongestPalindrome(string s) 
{
    string largest = "";

    for (int i = 1; i < s.Length-1; i++)
    {
        for (int j = i+1; j <= s.Length; j++)
        {
            if (IsPalindrome(s.Substring(i, j)))
            {
                largest = s.Substring(i, j);
            }
        }
    }

    return largest;
}

private static bool IsPalindrome(string s)
{
    bool isPalindrome = true;
    int j = s.Length-1;

    for (int i = 0; i < s.Length; i++)
    {
        if (s[i].ToString().ToLower() != s[j].ToString().ToLower())
        {
            isPalindrome = false;
            break;
        }

        j--;
    }

    return isPalindrome;
}

IsPalindrome 检查字符串是否为回文,FindLongestPalindrome 查找字符串中最长的回文。是的,我意识到FindLongestPalindrome 不是最有效的并且是二次的。不过,我目前对此并不担心。我只是想知道为什么程序在以下点不断超出范围并抛出异常:

if (IsPalindrome(s.Substring(i, j))) {...}

如何修改这部分,使代码不会超出每个字符串输入的范围?

【问题讨论】:

    标签: c# loops indexoutofboundsexception


    【解决方案1】:

    正因为如此:

    for (int j = i+1; j <= s.Length; j++)
    

    应该是:

    for (int j = i+1; j < s.Length; j++)
    

    【讨论】:

    • 嗯,我不太确定。我只是复制/粘贴了代码,但仍然出错。我认为这是因为Subtring 电话。它最终试图访问太多的字符。假设i2,随着您的代码更新,它会尝试输入Substring(2, s.Length -1),这会出错。如果您输入 j &lt; s.Length - i 它不再出错,但它也不会返回 actual 最长的回文(它返回的是一个回文,只是对我来说不是最长的。例如,“banana”返回“nan”而不是“anana”)
    • 仅仅删除等号并不能解决问题。仍然得到异常。
    • @Zolt 你能举个例子吗?
    • 我的输入是abaccddccefe
    【解决方案2】:

    您的问题是您试图从子字符串中检索太多字符。

    你的 for 循环:

    for (int j = i+1; j <= s.Length; j++)
    

    应该是:

    for (int j = i; j <= s.Length - i; j++)
    

    注意s.Length - i

    你的下一行:

    if (IsPalindrome(s.Substring(i, j)))
    

    您的第一个代码将失败,因为如果 i2,您最终会请求:s.Substring(2, s.Length),它将尝试检索比字符串中剩余的字符更多的字符。 真的,你想要(我认为)得到字符串的 rest,好吧,你可以保持原样,或者只使用从该索引开始并抓取字符串的其余部分。 编辑:不,抱歉,这是一个坏主意,并且在某些测试中失败了。

    很遗憾,您的代码中还有其他一些错误。例如,“banana”返回“ana”而不是“anana”。此外,如果最长的回文以您输入的第一个字母开头,它会忽略它(因为您从 i = 1 而不是 0 开始)这里有一个固定版本:

    private static string FindLongestPalindrome(string s) 
    {
        string largest = "";
    
        //start at i = 0 instead
        //Also needs to be to i < s.Length or fails some tests
        for (int i = 0; i < s.Length; i++)
        {
            for (int j = i; j <= s.Length-i; j++)
            {
                string substring = s.Substring(i, j);
    
                //you also need to check that you're looking at a longer string
                //this really could be optimized anyway, but here it is for simplicity
                if (substring.Length > largest.Length && IsPalindrome(substring))
                {
                    largest = substring;
                }
            }
        }
    
        return largest;
    }
    

    有了这个,一些测试:

    banana --> anana
    bananab --> bananab
    zzz --> zzz
    abcdddeeedddc --> cdddeeedddc
    a --> a
    abcbabbbbbbab --> babbbbbbab
    

    【讨论】:

    • 您的第二个 for 循环代码帮助我修复了错误。但是,您对该方法的新实现存在问题。它不适用于abaccddccefe
    • @Zolt:很抱歉。我对s.Substring(i) 是如何在你的算法中使用的想法搞砸了。如果你把它放回原来的s.Substring(i, j),它就可以工作。
    【解决方案3】:

    c# 不是 c++....

       public static bool IsPalindrome(string s)
       {
          return s == new string(s.Reverse().ToArray());
       }
    

    建议,将其添加为字符串的扩展方法

    public static class StringSupport
    {
        public static bool IsPalindrome(this string s)
        {
            return s == new string(s.Reverse().ToArray());
        }
    }
    

    用作这个

    bool palindrome = "string".IsPalindrome();
    

    【讨论】:

    • 我真的很喜欢你对IsPalindrome 的实现。它有效,但我不确定为什么。我真的很想知道。你能解释一下这条线在做什么吗? return s == new string(s.Reverse().ToArray());
    • 实际上,现在我更多地查看您的代码,这很有意义。您返回原始字符串和反转字符串之间比较的真值。我现在很好,谢谢。
    • 代码把字符串倒转成一个char数组,创建一个新的字符串进行比较后,就很容易理解了:)
    猜你喜欢
    • 1970-01-01
    • 2018-06-07
    • 2013-03-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-19
    相关资源
    最近更新 更多