最新更新 sitemap 网站制作设计本站搜索
网页设计
国外网站 韩国网站 个人主页 手提袋设计 CSS 网页特效 平面设计 网站设计 Flash CMS技巧 服装网站 php教程 photoshop 画册 服务器选用 数据库 Office
虚拟主机 域名注册 云主机 网页设计 客服QQ:8208442
当前位置:首页 > 编程开发 > asp教程

对“求数组中所有和为某固定数的所有数对”的算法

日期:08-01    来源:中国设计秀    作者:cnwebshow.com

一、题目描述lpr中国设计秀
lpr中国设计秀
    有一个数组a[1000],里面存放了1000个整数,请找出该数组中所有和为M的数对。例如数组为-1,2,4,6,5,3,4,2,9,0,8,3,那么和为8的数对有(-1,9),(2,6),(4,4),(5,3),(5,3),(0,8)。lpr中国设计秀
lpr中国设计秀
lpr中国设计秀
lpr中国设计秀
二、最普通的算法lpr中国设计秀
lpr中国设计秀
   在不可率复杂度的情况下,对于这个问题的最简单的算法如下:lpr中国设计秀
lpr中国设计秀
        PRivate static List<int[]> UseNormalWay(int[] arr, int sumTotal)lpr中国设计秀
        {lpr中国设计秀
            List<int[]> result = new List<int[]>();lpr中国设计秀
lpr中国设计秀
            for (int i = 0; i < arr.Length; i++)lpr中国设计秀
            {lpr中国设计秀
                int expectNum = sumTotal - arr[i];lpr中国设计秀
lpr中国设计秀
                for (int j = i + 1; j < arr.Length; j++)lpr中国设计秀
                {lpr中国设计秀
                    if (arr[j] == expectNum)lpr中国设计秀
                    {lpr中国设计秀
                        result.Add(new int[]{arr[i], expectNum});lpr中国设计秀
                    }lpr中国设计秀
                }lpr中国设计秀
            }lpr中国设计秀
lpr中国设计秀
            return result;lpr中国设计秀
        }lpr中国设计秀
   利用两层循环查找所有和为固定数sumTotal的所有数对,将找到的数对存入List中。但是这个算法复杂度有点高,实际上在遍历的时候做了一些重复的工作:lpr中国设计秀
lpr中国设计秀
    1) 后续循环的时候没有必要对前面已经配对的数列进行处理。lpr中国设计秀
lpr中国设计秀
    2)查找与某个数和为sumTotal的数时,应该可以有一些可以相互利用的过程。lpr中国设计秀
lpr中国设计秀
    基于这两点,可以引用一些01背包或动态规划的思想(或许引用得不恰当,我对这两种思想和理解很肤浅)来对这个算法进行改进,利用递归来操作。lpr中国设计秀
lpr中国设计秀
lpr中国设计秀
lpr中国设计秀
二、采用递归算法lpr中国设计秀
lpr中国设计秀
    采用递归算法的代码如下:lpr中国设计秀
lpr中国设计秀
       private static List<int[]> UseRecursion(int[] arr, int length, int sumTotal)lpr中国设计秀
        {lpr中国设计秀
            List<int[]> result = new List<int[]>();lpr中国设计秀
            int[] nextArr = new int[length];lpr中国设计秀
            int nextLength = 0;lpr中国设计秀
            int expectNum = sumTotal - arr[0];lpr中国设计秀
            int findStartNumCount = 0;lpr中国设计秀
            int findEndNumCount = 0;lpr中国设计秀
lpr中国设计秀
            for (int i = 1; i < length; i++)lpr中国设计秀
            {lpr中国设计秀
                if (arr[i] == expectNum)lpr中国设计秀
                {lpr中国设计秀
                    int circleCount = arr[0] == expectNum ? findEndNumCount : findStartNumCount;lpr中国设计秀
                    circleCount += 1;lpr中国设计秀
lpr中国设计秀
                    for (int j = 0; j < circleCount; j++)lpr中国设计秀
                    {lpr中国设计秀
                        result.Add(new int[] { arr[0], expectNum });    lpr中国设计秀
                    }lpr中国设计秀
lpr中国设计秀
                    findEndNumCount++;                    lpr中国设计秀
                }lpr中国设计秀
                else if (arr[i] == arr[0])lpr中国设计秀
                {lpr中国设计秀
                    for (int j = 0; j < findEndNumCount; j++)lpr中国设计秀
                    {lpr中国设计秀
                        result.Add(new int[] { expectNum, arr[0] });lpr中国设计秀
                    }lpr中国设计秀
                    findStartNumCount++;lpr中国设计秀
                }lpr中国设计秀
                elselpr中国设计秀
                {lpr中国设计秀
                    nextArr[nextLength++] = arr[i];lpr中国设计秀
                }                lpr中国设计秀
            }lpr中国设计秀
lpr中国设计秀
            if (nextLength > 0)lpr中国设计秀
            {lpr中国设计秀
                List<int[]> nextResult = UseRecursion(nextArr, nextLength, sumTotal);lpr中国设计秀
                foreach (int[] item in nextResult)lpr中国设计秀
                {lpr中国设计秀
                    result.Add(item);lpr中国设计秀
                }lpr中国设计秀
            }lpr中国设计秀
lpr中国设计秀
            return result;lpr中国设计秀
        }lpr中国设计秀
      每递归一次后,将所有没有检查过匹配的数字再组成一个新的数组以便在下一次递归中来处理,但这么做浪费了巨大的空间,特别是数组很大的情况下会消耗很多内存。为了不每次递归创建新的数组,可以在原来的数组上进行处理,将已经匹配的数字从数组中剔出,将后续数字前移替补。 lpr中国设计秀
lpr中国设计秀
三、数组动态改变算法 lpr中国设计秀
lpr中国设计秀
     这种算法的代码如下: lpr中国设计秀
lpr中国设计秀
         private static List<int[]> UseAdvancedWay(int[] arr, int sumTotal)lpr中国设计秀
        {lpr中国设计秀
            List<int[]> result = new List<int[]>();lpr中国设计秀
            int startIndex = 0, endIndex = arr.Length - 1;lpr中国设计秀
lpr中国设计秀
            while (startIndex < endIndex)lpr中国设计秀
            {lpr中国设计秀
                int expectNum = sumTotal - arr[startIndex];lpr中国设计秀
                int findStartNumCount = 0;lpr中国设计秀
                int findEndNumCount = 0;lpr中国设计秀
lpr中国设计秀
                for (int i = startIndex + 1; i <= endIndex; i++)lpr中国设计秀
                {lpr中国设计秀
                    if (findStartNumCount > 0 || findEndNumCount > 0)lpr中国设计秀
                    {lpr中国设计秀
                        arr[i] = arr[i + findStartNumCount + findEndNumCount];lpr中国设计秀
                    }lpr中国设计秀
lpr中国设计秀
                    if (arr[i] == expectNum)lpr中国设计秀
                    {lpr中国设计秀
                        int circleCount = arr[startIndex] == expectNum ? findEndNumCount : findStartNumCount;lpr中国设计秀
                        circleCount += 1;lpr中国设计秀
lpr中国设计秀
                        for (int iStart = 0; iStart < circleCount; iStart++)lpr中国设计秀
                        {lpr中国设计秀
                            result.Add(new int[] { arr[startIndex], arr[i] });lpr中国设计秀
                        }lpr中国设计秀
lpr中国设计秀
                        findEndNumCount++;lpr中国设计秀
                        endIndex--;lpr中国设计秀
                        i--;lpr中国设计秀
                    }lpr中国设计秀
                    else if (arr[i] == arr[startIndex] && arr[startIndex] != expectNum)lpr中国设计秀
                    {lpr中国设计秀
                        for (int iEnd = 0; iEnd < findEndNumCount; iEnd++)lpr中国设计秀
                        {lpr中国设计秀
                            result.Add(new int[] { expectNum, arr[i] });lpr中国设计秀
                        }lpr中国设计秀
lpr中国设计秀
                        findStartNumCount++;lpr中国设计秀
                        endIndex--;lpr中国设计秀
                        i--;lpr中国设计秀
                    }lpr中国设计秀
                }lpr中国设计秀
                startIndex++;lpr中国设计秀
            }lpr中国设计秀
lpr中国设计秀
            return result;lpr中国设计秀
        }lpr中国设计秀
lpr中国设计秀
       这种算法会破坏原有数组的数据的。lpr中国设计秀
lpr中国设计秀
四、三种算法时间的比较lpr中国设计秀
lpr中国设计秀
     虽然后两种算法的初衷是为了减少时间复杂度,但在具体测试中并没有比第一种算法优越多少,特别是递归的算法比第一种算法所用的时间还明显加长。或许我的想法从基础上就有问题,也或许是这个例子过于简单使得移动数据占用的时间明显凸现出来了。lpr中国设计秀
lpr中国设计秀
     一直未对算法有过多研究,希望高手们能指点一二,我相信有肯定有更完美的解决方案。lpr中国设计秀
lpr中国设计秀
五、所有码 lpr中国设计秀
lpr中国设计秀
        static void Main(string[] args)lpr中国设计秀
        {lpr中国设计秀
            const int NUM_COUNT = 8000;lpr中国设计秀
            const int MIN_NUM = -4;lpr中国设计秀
            const int MAX_NUM = 12;lpr中国设计秀
            const int TOTAL = 8;lpr中国设计秀
lpr中国设计秀
            int[] arr = GenerateArray(NUM_COUNT, MIN_NUM, MAX_NUM);lpr中国设计秀
lpr中国设计秀
            //Console.WriteLine("The numbers generated are:n-------------------------------------");lpr中国设计秀
            //PrintNumArray(arr);lpr中国设计秀
lpr中国设计秀
            // Normal waylpr中国设计秀
            TimeSpan normalTimeStart = Process.GetCurrentProcess().TotalProcessorTime;lpr中国设计秀
            Stopwatch normalStw = new Stopwatch();lpr中国设计秀
            normalStw.Start();lpr中国设计秀
lpr中国设计秀
            List<int[]> resultUseNormalWay = UseNormalWay(arr, TOTAL);lpr中国设计秀
lpr中国设计秀
            double normalCupTime = Process.GetCurrentProcess().TotalProcessorTime.Subtract(normalTimeStart).TotalMilliseconds;lpr中国设计秀
            normalStw.Stop();lpr中国设计秀
            double normalRealTime = normalStw.Elapsed.TotalMilliseconds;lpr中国设计秀
lpr中国设计秀
            // Print Normal Resultlpr中国设计秀
            //Console.WriteLine("The result number pairs using normal way are:n----------------------------------");lpr中国设计秀
            //PrintNumPairs(resultUseNormalWay);lpr中国设计秀
lpr中国设计秀
            // Recursion waylpr中国设计秀
            TimeSpan recuTimeStart = Process.GetCurrentProcess().TotalProcessorTime;lpr中国设计秀
            Stopwatch recuStw = new Stopwatch();lpr中国设计秀
            recuStw.Start();lpr中国设计秀
lpr中国设计秀
            List<int[]> resultUseRecursionWay = UseRecursion(arr, arr.Length, TOTAL);lpr中国设计秀
lpr中国设计秀
            double recuCupTime = Process.GetCurrentProcess().TotalProcessorTime.Subtract(recuTimeStart).TotalMilliseconds;lpr中国设计秀
            recuStw.Stop();lpr中国设计秀
            double recuRealTime = recuStw.Elapsed.TotalMilliseconds;lpr中国设计秀
lpr中国设计秀
            // Print Recursion Resultlpr中国设计秀
            //Console.WriteLine("The result number pairs using recusion way are:n----------------------------------");lpr中国设计秀
            //PrintNumPairs(resultUseRecursionWay);lpr中国设计秀
lpr中国设计秀
            // Advanced waylpr中国设计秀
            TimeSpan advTimeStart = Process.GetCurrentProcess().TotalProcessorTime;lpr中国设计秀
            Stopwatch advStw = new Stopwatch();lpr中国设计秀
            advStw.Start();lpr中国设计秀
lpr中国设计秀
            List<int[]> resultUseAdvancedWay = UseAdvancedWay(arr, TOTAL);lpr中国设计秀
lpr中国设计秀
            double advCupTime = Process.GetCurrentProcess().TotalProcessorTime.Subtract(advTimeStart).TotalMilliseconds;lpr中国设计秀
            advStw.Stop();lpr中国设计秀
            double advRealTime = advStw.Elapsed.TotalMilliseconds;lpr中国设计秀
lpr中国设计秀
            // Print Advanced Resultlpr中国设计秀
            //Console.WriteLine("The result number pairs using advanced way are:n----------------------------------");lpr中国设计秀
            //PrintNumPairs(resultUseAdvancedWay);lpr中国设计秀
lpr中国设计秀
lpr中国设计秀
            Console.WriteLine("n================================nThe time used:n-----------------------------------");lpr中国设计秀
            Console.WriteLine(String.Format("Normal   : count - {0}   Cpu Time - {1}  Real Time - {2}", resultUseNormalWay.Count, normalCupTime, normalRealTime));lpr中国设计秀
            Console.WriteLine(String.Format("Recursion: count - {0}   Cpu Time - {1}  Real Time - {2}", resultUseRecursionWay.Count, recuCupTime, recuRealTime));lpr中国设计秀
            Console.WriteLine(String.Format("Advanced : count - {0}   Cpu Time - {1}  Real Time - {2}", resultUseAdvancedWay.Count, advCupTime, advRealTime));lpr中国设计秀
lpr中国设计秀
            Console.Read();lpr中国设计秀
        }lpr中国设计秀
lpr中国设计秀
        private static int[] GenerateArray(int numCount, int minValue, int maxValue)lpr中国设计秀
        {lpr中国设计秀
            int[] arr = new int[numCount];lpr中国设计秀
lpr中国设计秀
            Random rdm = new Random((int)DateTime.Now.Ticks);lpr中国设计秀
            for (int i = 0; i < arr.Length; i++)lpr中国设计秀
            {lpr中国设计秀
                arr[i] = rdm.Next(minValue, maxValue);lpr中国设计秀
            }lpr中国设计秀
lpr中国设计秀
            return arr;lpr中国设计秀
        }lpr中国设计秀
lpr中国设计秀
        private static void PrintNumArray(int[] arr)lpr中国设计秀
        {lpr中国设计秀
            for (int i = 0; i < arr.Length; i++)lpr中国设计秀
            {lpr中国设计秀
                if (i > 0 && i % 20 == 0)lpr中国设计秀
                {lpr中国设计秀
                    Console.Write("n");lpr中国设计秀
                }lpr中国设计秀
                Console.Write(String.Format("{0,2}  ", arr[i]));lpr中国设计秀
            }lpr中国设计秀
            Console.Write("n");lpr中国设计秀
        }lpr中国设计秀
lpr中国设计秀
        private static void PrintNumPairs(List<int[]> numList)lpr中国设计秀
        {lpr中国设计秀
            for (int i = 0; i < numList.Count; i++)lpr中国设计秀
            {lpr中国设计秀
                if (i > 0 && i % 10 == 0)lpr中国设计秀
                {lpr中国设计秀
                    Console.Write("n");lpr中国设计秀
                }lpr中国设计秀
                Console.Write(string.Format("({0,2},{1,2})  ", numList[i][0], numList[i][1]));lpr中国设计秀
            }lpr中国设计秀
            Console.Write("n");lpr中国设计秀
        }lpr中国设计秀
lpr中国设计秀
        private static List<int[]> UseNormalWay(int[] arr, int sumTotal)lpr中国设计秀
        {lpr中国设计秀
            List<int[]> result = new List<int[]>();lpr中国设计秀
lpr中国设计秀
            for (int i = 0; i < arr.Length; i++)lpr中国设计秀
            {lpr中国设计秀
                int expectNum = sumTotal - arr[i];lpr中国设计秀
lpr中国设计秀
                for (int j = i + 1; j < arr.Length; j++)lpr中国设计秀
                {lpr中国设计秀
                    if (arr[j] == expectNum)lpr中国设计秀
                    {lpr中国设计秀
                        result.Add(new int[]{arr[i], expectNum});lpr中国设计秀
                    }lpr中国设计秀
                }lpr中国设计秀
            }lpr中国设计秀
lpr中国设计秀
            return result;lpr中国设计秀
        }lpr中国设计秀
lpr中国设计秀
        private static List<int[]> UseRecursion(int[] arr, int length, int sumTotal)lpr中国设计秀
        {lpr中国设计秀
            List<int[]> result = new List<int[]>();lpr中国设计秀
            int[] nextArr = new int[length];lpr中国设计秀
            int nextLength = 0;lpr中国设计秀
            int expectNum = sumTotal - arr[0];lpr中国设计秀
            int findStartNumCount = 0;lpr中国设计秀
            int findEndNumCount = 0;lpr中国设计秀
lpr中国设计秀
            for (int i = 1; i < length; i++)lpr中国设计秀
            {lpr中国设计秀
                if (arr[i] == expectNum)lpr中国设计秀
                {lpr中国设计秀
                    int circleCount = arr[0] == expectNum ? findEndNumCount : findStartNumCount;lpr中国设计秀
                    circleCount += 1;lpr中国设计秀
lpr中国设计秀
                    for (int j = 0; j < circleCount; j++)lpr中国设计秀
                    {lpr中国设计秀
                        result.Add(new int[] { arr[0], expectNum });    lpr中国设计秀
                    }lpr中国设计秀
lpr中国设计秀
                    findEndNumCount++;                    lpr中国设计秀
                }lpr中国设计秀
                else if (arr[i] == arr[0])lpr中国设计秀
                {lpr中国设计秀
                    for (int j = 0; j < findEndNumCount; j++)lpr中国设计秀
                    {lpr中国设计秀
                        result.Add(new int[] { expectNum, arr[0] });lpr中国设计秀
                    }lpr中国设计秀
                    findStartNumCount++;lpr中国设计秀
                }lpr中国设计秀
                elselpr中国设计秀
                {lpr中国设计秀
                    nextArr[nextLength++] = arr[i];lpr中国设计秀
                }                lpr中国设计秀
            }lpr中国设计秀
lpr中国设计秀
            if (nextLength > 0)lpr中国设计秀
            {lpr中国设计秀
                List<int[]> nextResult = UseRecursion(nextArr, nextLength, sumTotal);lpr中国设计秀
                foreach (int[] item in nextResult)lpr中国设计秀
                {lpr中国设计秀
                    result.Add(item);lpr中国设计秀
                }lpr中国设计秀
            }lpr中国设计秀
lpr中国设计秀
            return result;lpr中国设计秀
        }lpr中国设计秀
lpr中国设计秀
        private static List<int[]> UseAdvancedWay(int[] arr, int sumTotal)lpr中国设计秀
        {lpr中国设计秀
            List<int[]> result = new List<int[]>();lpr中国设计秀
            int startIndex = 0, endIndex = arr.Length - 1;lpr中国设计秀
lpr中国设计秀
            while (startIndex < endIndex)lpr中国设计秀
            {lpr中国设计秀
                int expectNum = sumTotal - arr[startIndex];lpr中国设计秀
                int findStartNumCount = 0;lpr中国设计秀
                int findEndNumCount = 0;lpr中国设计秀
lpr中国设计秀
                for (int i = startIndex + 1; i <= endIndex; i++)lpr中国设计秀
                {lpr中国设计秀
                    if (findStartNumCount > 0 || findEndNumCount > 0)lpr中国设计秀
                    {lpr中国设计秀
                        arr[i] = arr[i + findStartNumCount + findEndNumCount];lpr中国设计秀
                    }lpr中国设计秀
lpr中国设计秀
                    if (arr[i] == expectNum)lpr中国设计秀
                    {lpr中国设计秀
                        int circleCount = arr[startIndex] == expectNum ? findEndNumCount : findStartNumCount;lpr中国设计秀
                        circleCount += 1;lpr中国设计秀
lpr中国设计秀
                        for (int iStart = 0; iStart < circleCount; iStart++)lpr中国设计秀
                        {lpr中国设计秀
                            result.Add(new int[] { arr[startIndex], arr[i] });lpr中国设计秀
                        }lpr中国设计秀
lpr中国设计秀
                        findEndNumCount++;lpr中国设计秀
                        endIndex--;lpr中国设计秀
                        i--;lpr中国设计秀
                    }lpr中国设计秀
                    else if (arr[i] == arr[startIndex] && arr[startIndex] != expectNum)lpr中国设计秀
                    {lpr中国设计秀
                        for (int iEnd = 0; iEnd < findEndNumCount; iEnd++)lpr中国设计秀
                        {lpr中国设计秀
                            result.Add(new int[] { expectNum, arr[i] });lpr中国设计秀
                        }lpr中国设计秀
lpr中国设计秀
                        findStartNumCount++;lpr中国设计秀
                        endIndex--;lpr中国设计秀
                        i--;lpr中国设计秀
                    }lpr中国设计秀
                }lpr中国设计秀
                startIndex++;lpr中国设计秀
            }lpr中国设计秀
lpr中国设计秀
            return result;lpr中国设计秀
        }lpr中国设计秀
 lpr中国设计秀

本文引用地址:/bc/article_46129.html
网站地图 | 关于我们 | 联系我们 | 网站建设 | 广告服务 | 版权声明 | 免责声明