寻找最大连续子序列/Find the max contiguous subsequence

寻找最大连续子序列

给定一个实数序列X1,X2,...Xn(不需要是正数),寻找一个(连续的)子序列Xi,Xi+1,...Xj,使得其数值之和在所有的连续子序列数值之和中为最大。

一般称这个子序列为最大子序列,例如,在序列(2,-3,1.5,-1,3,-2,-3,3)中,最大的子序列是(1.5,-1,3)它的和是3.5,在一个给定的序列中可能有几个最大子序列。

如果所有的数值为负数,则最大子序列为空(由定义,空的子序列之和为0)。我们希望有一个解决该问题的算法,并且仅对此序列扫描一次。

扩展问题,算法至少还求出一个最大子序列,并且输出。

算法要点:当临时子序列之和小于零时,需要重置临时子序列之和为零,相当于重新起点计算子序列。

如下方法定义于工具类:MaxSubsequenceUtil

public static double FindMaxSubsequence(double[] array, out int startIndex)
        {
            double GlobeMax = 0, tmpMax = 0;
            startIndex = -1;
            for (int i = array.Length - 1; i >= 0; i--)
            {
                tmpMax = tmpMax + array[i];
                if (GlobeMax < tmpMax)
                {
                    GlobeMax = tmpMax;
                    startIndex = i;
                }
                else if (tmpMax < 0)
                {
                    tmpMax = 0;
                }
            }
            return GlobeMax;
        }

方法调用和输出子序列方法:

static void Main(string[] args)
        {
            double[] dArray = new double[] { 2, -3, 1.5, -1, 3, -2, -3, 3 };
            dArray.ToList<double>().ForEach(d => Console.Write("{0} ", d));
            int startIndex;
            double max = MaxSubsequenceUtil.FindMaxSubsequence(dArray, out startIndex);
            if (max == 0)
            {
                Console.WriteLine("No max subsequence exist!");
            }
            else
            {
                Console.WriteLine();
                Console.WriteLine("The max total is:{0}", max);
                Console.WriteLine("The max subsequence is:");
                double t = 0;
                for (int i = startIndex; i < dArray.Length; i++)
                {
                    t += dArray[i];
                    if (t == max)
                    {
                        Console.Write("{0} ", dArray[i]);
                        break;
                    }
                    Console.Write("{0} ", dArray[i]);
                }
            }
            Console.ReadKey();
        }

完毕。

下载源码

作者:Andy Zeng
欢迎任何形式的转载,但请务必注明出处。

http://www.cnblogs.com/andyzeng/p/3672547.html

原文地址:https://www.cnblogs.com/andyzeng/p/3672547.html