Какой-то цикл с условиями. Конкретная проблема - PullRequest
1 голос
/ 17 апреля 2019

У меня небольшая проблема с математикой или комбинаторикой в ​​моем коде на 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 как сумма страниц.он может быть возвращен в виде строки на основе имени или идентификатора, например, 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 OK CFFFF = 10 + 5 +5 +5 +5 = 30 Ok и т. Д.

У меня нет идеи для лучшего способа создания циклов для этого, и я помещаю записи в список. Большое спасибо за каждую попытку помочь мне.

Ответы [ 2 ]

1 голос
/ 17 апреля 2019

Это была моя оригинальная идея, которую я собирался опубликовать для вас, она просто вернула список строк

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);

Это версия, измененная для использования вашего класса конфигурации

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);
0 голосов
/ 17 апреля 2019

Только для информации и поисковиков.Я знаю, этот код не так чист, но я поставил его здесь как тест 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; }
    }
}
...