是否可以在引发异常时退出循环?

问题描述 投票:0回答:4

我在Hackerrank.com上解决了一个任务,其中的问题是这样的:

您有一个数组。该数组包含数字。现在您输入两个数字:

  • 第一个描述总和
  • 第二个描述您加在一起的索引数量(序列长度)

最后得到的序列数量之和是您定义的数量

例如:

您的数组为[1,2,3,4],总和为3,序列长度为2。现在,您获取前两个索引并输出总和:[1,2] = 3。这等于您的总和,所以现在您找到了一个序列。下一个序列是[2,3] =5。这不等于3,因此您的序列计数器保持为1。最后一个序列是[3,4] =7。这也不等于3,最后找到一个序列。

我为此编写了这段代码:

static int GetSequences(List<int> s, int d, int m)
{
    //m = segment-length
    //d = sum

    int count = 0;
    int j = 0;
    int k = 0; 

    do
    {
        try
        {
            List<int> temp = new List<int>();

            for (int i = 0; i < m; i++)
            {
                temp.Add(s[i + k]);
            }
            if (temp.Sum() == d)
            {
                count++;
            }
            j++;
            k++;
        }
        catch (ArgumentOutOfRangeException)
        {
            break;
        }

    } while (true);

    return count;
}

由于我不知道我必须多久计数一次(例如,序列长度为3的6长度数组有4个序列(1,2,3 | 2,3,4 | 3,4,5 | 4,5,6)),当索引超出范围时,我正在停止while循环。但我不确定此解决方案是否可行。不仅具有程序速度,还具有代码清洁度。此代码是否可以接受,还是使用for循环更好?对于具有3个长度序列的6长度数组,该循环可以精确地循环4次?]

c# arrays
4个回答
3
投票

不推荐,不。异常应该保留给不应该发生的事情,而不是流控制或验证。

您想要的是使用条件逻辑(if语句)和break关键字。

而且,codereview.stackexchange.com更适合此类问题。


2
投票

最好修复您的代码,以免其例行抛出异常:

您将这些细分的每一个相加:

0  1  2  3    start = 0
|  |          summing indexes: 0, 1
+--+

0  1  2  3    start = 1
   |  |       summing indexes: 1, 2
   +--+

0  1  2  3    start = 2
      |  |    summing indexes: 2, 3
      +--+

括号从索引start开始,大小为ms的长度由s.Count给出。因此,我们要一直继续到start + m == s.Count

((我总是发现将这些内容画出来,并放入样本编号,以确保您数学正确,这很有用。在上面的样本中,您可以看到当start (2) + m (2) == the array size (4)时我们停止了)] >

static int GetSequences(List<int> s, int d, int m)
{
    //m = segment-length
    //d = sum

    int count = 0;

    for (int start = 0; start + m <= s.Count; start++)
    {
        List<int> temp = new List<int>();
        for (int i = 0; i < m; i++)
        {
            temp.Add(s[start + i]);
        }
        if (temp.Sum() == d)
        {
            count++;
        }
    }

    return count;
}

但是,您可以稍微改善代码:

  1. 使用有意义的变量名
  2. 不要每次都创建一个新的临时列表,只是为了求和
  3. 检查您的输入
  4. static int GetSequences(List<int> numbers, int targetSum, int segmentLength)
    {
        if (numbers == null)
            throw new ArgumentNullException(nameof(numbers));
        if (segmentLength > numbers.Count)
            throw new ArgumentException("segmentLength must be <= numbers.Count");
    
        int count = 0;
    
        for (int start = 0; start + segmentLength <= numbers.Count; start++)
        {
            int sum = 0;
            for (int i = 0; i < segmentLength; i++)
            {
                sum += numbers[start + i];
            }
            if (sum == targetSum)
            {
                count++;
            }   
        }
    }
    

0
投票

通常,除了开关/情况外,通常没有使用中断的真正原因。顾名思义,异常MUST


0
投票

“抛出异常后可以退出循环吗?”

© www.soinside.com 2019 - 2024. All rights reserved.