【问题标题】:Some loop with conditions. Specific problem一些带有条件的循环。具体问题
【发布时间】:2019-09-07 11:43:49
【问题描述】:

我的 C# 代码中有数学或组合学方面的小问题。我不知道怎么写这个最简单的。

我有一个类 Section 和 TestClass 但没有返回预期结果的方法。

public class Section
{
    public int Id { get; set; }
    public int Pages { get; set; }
    public string Name { get; set; }
}

[TestFixture]
public class PermutatorTest
{
    private IList<Section> _sections;
    private int _targetPage;

    [SetUp]
    public void SetUp()
    {
        _targetPage = 30;
        _sections = new List<Section>
        {
            new Section {Id = 1, Pages = 15, Name = "A"},
            new Section {Id = 2, Pages = 15, Name = "B"},
            new Section {Id = 3, Pages = 10, Name = "C" },
            new Section {Id = 4, Pages = 10, Name = "D"},
            new Section {Id = 5, Pages = 10, Name = "E"},
            new Section {Id = 6, Pages = 5, Name = "F"}
        };
    }

    [Test]
    public void GetPermutationsTest()
    {
        // Code to return list of all combinations
    }
}

我想得到每个组合,总页数为 30。 它可以根据名称或 Id 作为字符串返回,例如 AA 或 11 、 AB 或 12 当然,顺序并不重要(AB和BA是一样的......CCD和CDC和DCC也是)

最终结果应如下所示:(30 个正确结果)

AA
AB
ACF
ADF
AEF
AFFF
BB
BCF
BDF
BEF
BFFF
CCC
CCD
CCE
CDD
CEE
CDE
CFFFF
CDFF
CCFF
CEFF
DDFF
DEFF
DFFFF
DDD
DDE
EFFFF
EEE
EEFF
FFFFFF

例如DDE = 10+10+10 = 30 正常 CFFFF = 10 + 5 +5 +5 +5 = 30 好 等等

我不知道为此创建循环并将记录放入列表的最佳方法 非常感谢您每次尝试帮助我。

【问题讨论】:

  • 递归应该更容易,而不是循环
  • 我认为应该有 31 个结果 - 为什么 DEE (10+10+10) 不在您的列表中?
  • 事实上 .. DEE 也是 :) 我也尝试通过递归来制作一些东西。

标签: c# loops conditional-statements permutation


【解决方案1】:

仅适用于信息和搜索者。 我知道,这段代码不是那么干净 但我把它作为一个 nUnit 测试放在这里......

它返回我想要的......我想。

using System;
using System.Collections.Generic;
using NUnit.Framework;

[TestFixture]
public class PermutatorTest
{
    private IList<Section> _sections;
    private int _targetPage;
    private IList<Config> _result;
    [SetUp]
    public void SetUp()
    {
        _targetPage = 30;
        _sections = new List<Section>
        {
            new Section {Id = 1, Pages = 15, Name = "A"},
            new Section {Id = 2, Pages = 15, Name = "B"},
            new Section {Id = 3, Pages = 10, Name = "C" },
            new Section {Id = 4, Pages = 10, Name = "D"},
            new Section {Id = 5, Pages = 10, Name = "E"},
            new Section {Id = 6, Pages = 5, Name = "F"}
        };

        _result = new List<Config>();
    }

    [Test]
    public void GetPermutationsTest()
    {

        for (var b =0 ; b<=_sections.Count-1; b++)
        {
            var config = new Config
            {
                Name = _sections[b].Name,
                Ids =  _sections[b].Id.ToString(),
                Pages = _sections[b].Pages
            };
            GoDeeperAndAddToResult(config, b);
        }

        Console.WriteLine(_result.Count);

        foreach (var item in _result)
        {
            Console.WriteLine($"{item.Name} - {item.Ids} - {item.Pages}");
        }
    }

    private void GoDeeperAndAddToResult(Config config, int startIndex)
    {
        for (var b = startIndex; b <= _sections.Count-1; b++)
        {
            var section = _sections[b];

            var combName = config.Name;
            var combIds = config.Ids;
            var combPages = config.Pages;

            var maxSec = _targetPage / section.Pages;
            for (var a = 1; a <= maxSec; a++)
            {
                combName = combName + section.Name;
                combIds = combIds + section.Id.ToString();
                combPages = combPages + section.Pages;

                var subConfig = new Config
                {
                    Name = combName,
                    Ids = combIds,
                    Pages = combPages
                };

                if (subConfig.Pages == _targetPage)
                {
                    _result.Add(subConfig);
                    break;
                }
                else if (subConfig.Pages < _targetPage)
                {
                    GoDeeperAndAddToResult(subConfig, b + 1);
                }
                else
                {
                    break;
                }
            }
        }
    }

    public class Config
    {
        public string Name { get; set; }
        public string Ids { get; set; }
        public int Pages { get; set; }
    }

    public class Section
    {
        public int Id { get; set; }
        public int Pages { get; set; }
        public string Name { get; set; }
    }
}

【讨论】:

    【解决方案2】:

    这是我要为您发布的最初想法,它只是返回了一个字符串列表

    public List<String> result;
    public void GetResultList(int startOffs, String CurNames, int curTotal)
    {
      for (int newOffs = startOffs; newOffs < _sections.Count; newOffs++)
      {
        int newTotal = curTotal + _sections[newOffs].Pages;
        String newNames = CurNames+ _sections[newOffs].Name;
        if (newTotal < _targetPage)
          GetResultList(newOffs, newNames, newTotal);
        else if (newTotal == _targetPage)
          result.Add(newNames);
      }
    }
    

    通过初始化结果和启动参数调用:

    result = new List<String>();
    GetResultList(0,"",0);
    

    这是一个修改为使用您的 Config 类的版本

    public void GetResultList(int startOffs, Config CurConfig)
    {
      for (int newOffs = startOffs; newOffs < _sections.Count; newOffs++)
      {
        Config newConfig = new Config{ Name = CurConfig.Name + _sections[newOffs].Name,
                                       Ids = CurConfig.Ids + _sections[newOffs].Id.ToString(),
                                       Pages = CurConfig.Pages + _sections[newOffs].Pages};
        if (newConfig.Pages < _targetPage)
          GetResultList(newOffs, newConfig);
        else if (newConfig.Pages == _targetPage)
          _result.Add(newConfig);
      }
    }
    

    调用需要初始化结果和一个开始的 Config 实例

    _result = new List<Config>();
    Config s = new Config { Ids = "", Pages=0, Name=""};
    GetResultList(0,s);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-10-31
      • 2018-11-29
      • 1970-01-01
      • 2017-07-26
      • 1970-01-01
      相关资源
      最近更新 更多