继续离开约束异常

时间:2013-11-15 03:23:26

标签: c# loops indexoutofboundsexception

我在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))) {...}

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

3 个答案:

答案 0 :(得分:2)

正因为如此:

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

它应该是:

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

答案 1 :(得分:1)

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

答案 2 :(得分:1)

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

你的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 ,好吧,你可以保持原样,或者只使用从那个索引开始的String.Substring(int) overload和抓住其余的字符串。编辑:没有,对不起,这是一个坏主意,但未能通过一些测试。

不幸的是,您的代码中还存在其他一些错误。例如,“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