【问题标题】:C# merging two for loops, the second loop is the first upside downC#合并两个for循环,第二个循环是第一个倒置
【发布时间】:2018-03-22 08:59:43
【问题描述】:

我有 2 个 for 循环:

    for (int i = n; i >= 1; i -= 2)
    {
          ....
    }

    for(int i = 3; i <= n; i += 2)
    {
          ....
    }

类似,如果n = 7,那么i 将获得值(按此顺序):

7, 5, 3, 1, 3, 5, 7

代码与 for 循环相同。如果我可以合并这两个 for 循环会更好。我是 C# 新手。有什么建议吗?

编辑:n 总是奇怪的

【问题讨论】:

  • 这真的取决于循环体中发生的事情。
  • “如果我可以合并这两个 for 循环会更好” - 为什么,你尝试了什么?
  • 你的循环是不等价的,你在 1 结束第一个但在 3 开始第二个......
  • 您是在向我们询问您的业务逻辑吗?我们应该怎么知道?如果你合并它们,那就不同了,所以这真的取决于你的要求。
  • n 是否总是奇数(7、9、13 等)?

标签: c# for-loop merge


【解决方案1】:

这样做很有趣,所以我会发布我的答案。不确定它是否比仅以单独的方法提取循环的内容更好。

using System.Linq;
var n = 18;
var odds = Enumerable.Range(1,n-1).Where(i=>i%2==1).ToList();
var reverseOdds = new List<int>(odds);
reverseOdds.Reverse();
var indexes = reverseOdds.Concat(odds.Skip(1));
and then your loop

foreach (var index in indexes)
{
...
}

【讨论】:

  • 最好避免使用 ToList() 和 new List 以获得更好的性能(IEnumerable 扩展应该足够了)
  • 我知道这段代码效率很低(不是为了让它准备好生产)。但是,除了比复制慢得多的 orderby 之外,我没有找到一种 linq 方法来编写反向代码(它会改变集合)。如果您有提示,我将不胜感激。
【解决方案2】:

为什么不将循环提取作为方法?特别是如果

代码是相同是for循环。

类似这样的:

  private static IEnumerable<int> MyLoop(int n) {
    for (int i = n; i >= 1; i -= 2)
      yield return i;

    // Let's support even n like 10
    for (int i = n % 2 == 0 ? 2 : 3; i <= n; i += 2)
      yield return i; 
  }   

然后你可以把它当成一个循环

  n = 7;

  foreach (int i in MyLoop(7)) {
    ...
  }

并且可以轻松玩的方法:

  // Obtain an array: [8, 6, 4, 2, 0, 2, 4, 6, 8]
  int[] array = MyLoop(8).ToArray();

  // Join items and print them on the console
  Console.Write(string.Join(", ", MyLoop(7)));

结果:

  7, 5, 3, 1, 3, 5, 7

【讨论】:

    【解决方案3】:

    我不确定它是否会有所帮助,但这是使用单个 for 循环获取该输出的一种方法:

    var list = new List<int>() {1};
    for(var i = 3; i <= n; i+=2)
    {
        list.Insert(0, i);
        list.Add(i);
    }
    // if n is 7, list now contains 7,5,3,1,3,5,7.
    

    You can see a live demo on rextester.

    【讨论】:

    • 你的现场演示不会运行,你的意思是这样吗rextester.com/UJW58096
    • @MattBeldon 是的,对不起。我玩过名字,忘了改回来。现已修复。
    【解决方案4】:

    “简单”for 循环:

    int max = 7;
    int min = 1;
    bool up = false;
    
    for (int i = max; i <= max; up |= (i == min), i = (up ? i + 2 : i - 2))
    {
        ...
    }
    

    很遗憾,您不能在 for 循环定义本身中声明 up...

    【讨论】:

      【解决方案5】:

      这是我的解决方案:

          public static void Main(string[] args)
          {
              int N = 7;
              Console.WriteLine("Sequence: " + string.Join(", ", genSequence(new List<int>(), N)));
          }
      
          private static List<int> genSequence(List<int> lst, int n)
          {
              lst.Add(n);
              if (n > 1)
                  genSequence(lst, n - 2).Add(n);
              return lst;
          }
      

      现场演示:http://rextester.com/QXNH15306

      【讨论】:

        猜你喜欢
        • 2013-08-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-02-08
        • 2014-07-21
        • 2014-08-28
        • 1970-01-01
        相关资源
        最近更新 更多