避免回溯方法
半月没来博客园,换了一份新工作,开始繁琐的事情一大堆,实在没闲工夫写什么了,这篇大概是我半年前写在别处的,不过我觉得是不错的方法,至少我个人这么觉得。回溯法是不可控的,有时候会超出我们意料之外产生不妙的结果,最常见的也就是内存泄漏。一下是原文照搬过来的,不过是我自己写的,我也不加出处了。(如果是引用别人的我会加上出处,咱不埋没别人的智慧。)
回溯方法是很容易想到,又不容易想到的,往往,我们思维更容易进入的是回溯法。但是回溯法有着它的弊端,非常明显的弊端是作用域内产生的变量和引用在回溯法调用未完成时,不能释放(对于大部分编辑器来说,排除有着优化能力的编辑器)。如果我们在某一方法中使用极多的回溯调用,在方法中不能及时的对方法作用域内的变量和引用释放,最终会造成内存不足和cpu的计算负荷增大(内存机制中可以将过剩的数据转存到虚拟内存、硬盘,这个就不说了)。使用栈(队)式的循环,可以轻易避免回溯法,而且栈(队)式的数据再使用之后可以很方便的抛出移除。某些时候就是这样,一个小小的改动,可以让一个程序在某种特定的环境中起死回生。(之前做过一个数独运算器的算法,后来的优化改进就是为了避免回溯)
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.IO; 6 7 namespace 避免回溯方法 8 { 9 class Program 10 { 11 static void Main(string[] args) 12 { 13 string path = AppDomain.CurrentDomain.BaseDirectory; 14 15 List<string> fileList1 = new List<string>(); 16 FunctionHuishuo(path, ref fileList1); 17 18 List<string> fileList2 = new List<string>(); 19 FunctionQueue(path, ref fileList2); 20 21 List<string> fileList3 = new List<string>(); 22 FunctionStack(path, ref fileList3); 23 } 24 25 /// <summary> 26 /// 回溯法 27 /// </summary> 28 /// <param name="path"></param> 29 /// <param name="fileList"></param> 30 private static void FunctionHuishuo(string path, ref List<string> fileList) 31 { 32 if (true) 33 { 34 string[] files = null; 35 try 36 { 37 files = Directory.GetFiles(path); 38 } 39 catch { } 40 41 if (files != null && files.Length > 0) 42 { 43 fileList.AddRange(files); 44 } 45 } 46 47 if (true) 48 { 49 string[] folders = null; 50 try 51 { 52 folders = Directory.GetDirectories(path); 53 } 54 catch { } 55 56 if (folders != null && folders.Length > 0) 57 { 58 foreach (string folder in folders) 59 { 60 FunctionHuishuo(folder, ref fileList); 61 } 62 } 63 } 64 } 65 66 /// <summary> 67 /// 堆栈法 68 /// </summary> 69 /// <param name="path"></param> 70 private static void FunctionStack(string path, ref List<string> fileList) 71 { 72 Stack<string> stack = new Stack<string>(); 73 stack.Push(path); 74 75 while (stack.Count > 0) 76 { 77 string dir = stack.Pop(); 78 79 string[] files = null; 80 try 81 { 82 files = Directory.GetFiles(dir); 83 } 84 catch { } 85 86 if (files != null && files.Length > 0) 87 { 88 fileList.AddRange(files); 89 } 90 91 string[] folders = null; 92 try 93 { 94 folders = Directory.GetDirectories(dir); 95 } 96 catch { } 97 98 if (folders != null && folders.Length > 0) 99 { 100 foreach (string folder in folders) 101 { 102 stack.Push(folder); 103 } 104 } 105 } 106 } 107 108 /// <summary> 109 /// 队列法 110 /// </summary> 111 /// <param name="path"></param> 112 private static void FunctionQueue(string path, ref List<string> fileList) 113 { 114 Queue<string> queue = new Queue<string>(); 115 116 queue.Enqueue(path); 117 118 while (queue.Count > 0) 119 { 120 string dir = queue.Dequeue(); 121 122 string[] files = null; 123 try 124 { 125 files = Directory.GetFiles(dir); 126 } 127 catch { } 128 129 if (files != null && files.Length > 0) 130 { 131 fileList.AddRange(files); 132 } 133 134 string[] folders = null; 135 try 136 { 137 folders = Directory.GetDirectories(dir); 138 } 139 catch { } 140 141 if (folders != null && folders.Length > 0) 142 { 143 foreach (string folder in folders) 144 { 145 queue.Enqueue(folder); 146 } 147 } 148 } 149 } 150 } 151 }
请仔细对比下三种循环结构的写法,特别注意下里面有用到 if(true){...} ,这种方式在某些编辑环境中可以产生非常美妙的效果,你造吗?
好了,就这么多吧,实在没时间写新东西了。以后出贴应该很慢了,不过会出点服务器集群方面的帖子,这些帖子现存的已经很多,但是大部分都是视图文字说明,对于新手来说很难掌握,我自己曾经摸索的时候,可是煞费苦心啊。它需要的条件非常苛刻,需要大量服务器、高并发访问、以及核心数据库和分化数据库策略等等,如果用一帖把它给解释清楚,我感觉就是天方夜谭,它完全可以出成一本书,所以在一帖中讲解集群使用图文方式是最好的方式,比较全面概括,所以我没怪过前辈们写集群方面的知识写的太笼统,完全不明所以。前辈们写这么高明的帖子是给有心人看的,他想把他的思想教给我们;我写帖子完全是给屌丝看的,做个知识的入门引导吧,呵呵。(预先掌握golang,erlang编程)