最近做的项目(自己练练手的那种)遇到了一个很有趣的问题比如这样一个字符串{field}/{field}/{field}当然这里的field个数是不确定的但是每一个field都知道其范围要实现的功能就是把所有的url计算出来 如果field的个数确定你大可放心地用for循环不断地嵌套就可以实现但是这里是不确定的我想到的方案是使用Stack用Stack来模拟嵌套的for循环 首先为field建个模型说白了就是写了class表示它 view sourceprint? public class RangeItem { private int position = ; /// <summary> /// 对应的field位置 /// </summary> public int Position { get { return position; } set { position = value; } } private int rangeMin = ; /// <summary> /// 范围最小值 /// </summary> public int RangeMin { get { return rangeMin; } set { rangeMin = value; } } private int rangeMax = ; /// <summary> /// 范围最大值 /// </summary> public int RangeMax { get { return rangeMax; } set { rangeMax = value; } } private int currentIndex = ; /// <summary> /// 在Range中的位置这个属性用于在循环中保存当前的处理序号因为我们在用Stack模拟嵌套的for循环 /// </summary> public int CurrentIndex { get { return currentIndex == ? rangeMin : currentIndex; } set { currentIndex = value; } } } 然后呢再封装一下把所有的RangeItem集中管理 view sourceprint? public class RangeItemManager { private static List<RangeItem> rangeItems = new List<RangeItem>(); /// <summary> /// 所有的RangeItem /// </summary> public static List<RangeItem> Items { get { return RangeItemManagerrangeItems; } set { RangeItemManagerrangeItems = value; } } } 核心的代码如下 view sourceprint? if (RangeItemManagerItemsCount == ) return null;
RangeItemManagerItemsSort(Compare);
RangeItem firstItem = RangeItemManagerItems[]; //如果只有一个field则简单地通过一个for处理 if (RangeItemManagerItemsCount == ) { for (int i = firstItemRangeMin; i <= firstItemRangeMax; i++) Action(i); } else { //循环最外层的对应field for (int i = firstItemRangeMin; i <= firstItemRangeMax; i++) { stack = new Stack<int>();
//把最外层的那个值入栈 stackPush(i); //循环剩余的RangeItem ProcessInnerLoop(); } }
public static int Compare(RangeItem x RangeItem y) { return xPosition > yPosition ? : ; }
private static void ProcessInnerLoop(int current) { ++current;
//如果是最里层(fieldmax)则直接进行遍历 if (current == RangeItemManagerItemsCount ) { RangeItem item = RangeItemManagerItems[current];
for (int i = itemRangeMin; i <= itemRangeMax; i++) {
//获取全部入栈的元素这样算是完成了一次处理可以产生了一个url List<int> lst = stackToList();
lstReverse(); lstAdd(i);
Action(lst); } } else { RangeItem item = RangeItemManagerItems[current];
for (int i = itemCurrentIndex; i <= itemRangeMax; i++) {
//把当前值入栈 stackPush(i);
//处理下一个RangeItem ProcessInnerLoop(current);
//修改当前RangeItem的CurrentIndex下一次循环是从CurrentIndex开始的 itemCurrentIndex = i + ;
if (itemCurrentIndex >= itemRangeMax) itemCurrentIndex = itemRangeMin;
//把当前值出栈 stackPop(); } } }
private static void Action(List<int> lst) { object[] objs = new object[lstCount]; for (int i = ; i < lstCount; i++) { objs[i] = (object)lst[i]; }
string url = StringFormat(UrlFormator objs); //TargetUrlsUrls是一个List<string> TargetUrlsUrlsAdd(url); }
private static void Action(int i) { string url = StringFormat(UrlFormator i); //TargetUrlsUrls是一个List<string> TargetUrlsUrlsAdd(url); } 贴了这么一大段代码给我的感觉就是啰嗦效率也是个问题尤其是在field很多每个RangeItem范围很广的时候写这篇post的目的就是大家一起讨论看看有没有更好的实现方式谢谢 |