2016-04-14 31 views
0

次の問題で数時間待たずに、パッケージに収まるボックスの数を計算するコードがあります。そのためには、パッケージごとのパッケージとボックスのチェックボックスを計算します。ここでループ内でループを再帰的に書き直してループを使用する

は、コードは次のとおりです。

private bool CalculateOnePackage(Package package, List<Item> workItems, List<Item> packagedItemsList) 
{ 
    if (workItems.Count == 0) 
    { 
    return true; 
    } 

    var packages = new List<Package>(); 
    Item tempItem = null; 
    foreach (Item entity in workItems) 
    { 
    if (/* execude code that changes entity and packages */) 
    { 
     tempItem = entity; 
     break; 
    } 
    } 

    if (tempItem == null) 
    { 
    return false; 
    } 

    packagedItemsList.Add(tempItem); 
    workItems.Remove(tempItem); 

    foreach (var p in packages) 
    { 
    this.CalculateOnePackage(p, workItems, packagedItemsList); 
    } 

    return true; 
} 

どのように私は使用のみループにコードを書き換えることができますか?このコードでは、StackoverflowExceptionが発生するという問題があります。

+0

使用あなたはこのことを理解していればループを壊すパッケージのボックスのあなたの最大の限界に達し、その後、私は、同様のコードを掲載します – rashfmnb

+1

の音でそれから、すでに入っているパッケージを含むすべてのパッケージをループしています。 – BugFinder

+0

['Queue <' -class](https://msdn.microsoft.com/ja -us/library/7977ey2c(v = vs.110).aspx)を使用して、 'StackOverFlowException'を回避します。したがって、パッケージをキューに追加して処理し、パッケージをキューから削除します。 'queue.Count> 0'の間にキューをループしてください。 –

答えて

0

このようなことを書いてください。しかし、最初は返品をデバッグし修正する必要があります。また、あなたの関数はPackageパッケージを使用しません。

さらに、関数は内部再帰呼び出しの結果を使用しません。 (this.CalculateOnePackage(p、workItems、packagedItemsList);)を返すか使用しません。私がそれを理解した後、あなたのコードを書き直そうとするのをやめました。

private bool CalculateOnePackage(Package package0, List<Item> workItems0, List<Item> packagedItemsList0) 
    { 
     var q = new Queue<Tuple<Package, List<Item>, List<Item>>>(); 
     q.Enqueue(new Tuple<Package, List<Item>, List<Item>>(package0, workItems0, packagedItemsList0)); 
     while (q.Count != 0) 
     { 
      var state = q.Dequeue(); 
      var package = state.Item1; 
      var workItems = state.Item2; 
      var packagedItemsList = state.Item3; 

      if (workItems.Count == 0) 
      { 
       return true; 
      } 

      var packages = new List<Package>(); 
      Item tempItem = null; 
      foreach (Item entity in workItems) 
      { 
       if (/* execude code that changes entity */) 
       { 
        tempItem = entity; 
        break; 
       } 
      } 

      if (tempItem == null) 
      { 
       return false; 
      } 

      packagedItemsList.Add(tempItem); 
      workItems.Remove(tempItem); 

      foreach (var p in packages) 
      { 
       q.Enqueue(new Tuple<Package, List<Item>, List<Item>>(p, workItems, packagedItemsList)); 
      } 
     } 


     return true; 
    } 
1

あなたはStackOverFlowExceptionを避けるためにQueue<-classを使用することができます。しかし、あなたは以下の私のuncomplete結果を読むことができます。したがって、パッケージをキューに追加し、処理してから削除してください。 queue.Count > 0の間にキューをループします。

私は方法が何をすべきかわからないので、良い例を示すのは難しいです。おそらく、(また、簡単なLINQクエリを使用してループを置き換える):

private void CalculateOnePackage(Package package, List<Item> workItems) 
{ 
    Queue<Package> packages = new Queue<Package>(); 
    packages.Enqueue(package); 

    while (packages.Count > 0) 
    { 
     // method ProcessEntity adds package(s) to the queue 
     Item entityItem = workItems 
      .FirstOrDefault(item => ProcessEntity(item, packages)); 
     // do something with it if entityItem != null 
    } 
} 
休憩を持つforループ
関連する問題