最近做的項目(自己練練手的那種)遇到了一個很有趣的問題比如這樣一個字符串{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的目的就是大家一起討論看看有沒有更好的實現方式謝謝
From:http://tw.wingwit.com/Article/program/net/201311/11500.html