C # валютные перестановки - PullRequest
2 голосов
/ 07 декабря 2011

Просто чтобы все знали, я впервые обращаюсь за помощью по переполнению стека.Я обычно ищу сайт и нахожу удовлетворительный ответ или копаю дальше на MSDN или других сайтах.Но на этот раз я серьезно застрял.

Я получил программную проблему от вербовщика, которую я должен заполнить, чтобы отправить клиенту запрос, чтобы узнать, хотят ли они мне позвонить. Вот проблема: для любого заданного значения определите количество способов, которым это значение можетбыть представленными номиналами $ 100, $ 50, $ 20, $ 10, $ 5, $ 1, .25, .10, .05, .01

Я никогда не принимал тригонометрию или исчисление, и я никогда не сталкивался с чем-то таким математически сложным вмои 14 лет программирования.Они хотят получить ответ на C #, так как это магазин Microsoft .NET.

Рекрутер дал мне код другого кандидата, который он представил.Этот человек должен быть блестящим математиком, поскольку она действительно написала весь алгоритм для достижения желаемого результата.Я подключил его к веб-странице, и он на самом деле удовлетворяет требованиям.Проблема в том, что я даже не могу понять это и понять это так, чтобы я мог написать свою собственную реализацию.

Я действительно очень хочу эту работу, как это звучит при запуске в Нью-Йорке, что звучитотличный.Я смог ответить на вторую проблему, так как это был вопрос об архитектуре / дизайне, но этот вопрос меня смущает.

Кстати, я посмотрел в Википедии проблему смены монет и типа ранца, и она выходит далеко за рамки моей математическойнавыки.Я даже не могу прочитать ответы, потому что я не понимаю исчисления.Поэтому мне нужна серьезная помощь в этом.

Вот ее код, который работает, кстати:

protected void Page_Load(object sender, EventArgs e)
{
    var numberToSplit = new List<int>() {123};  
    foreach (int a in numberToSplit)
    {
        Response.Write(a + "  can be split in ");
        foreach (List<double> splits in GetDenominations(a).Values)
        {
            foreach (double b in splits)
            {
                Response.Write(b + ",");
            }
            //next split
            Response.Write("<br/>");
        }      
        Response.Write("<br/>");
    }
}

public Dictionary<double, List<double>> GetDenominations(int value)
{
    var denominations = new List<double> {100, 50, 20,10,5,1,0.25,0.10,0.05,0.01};
    var AllPossibleSplits = new Dictionary<double, List<double>>();
    var hightestdenomination = 100.0;

    while (hightestdenomination != 0)
    {
        var remainingDenominations =
                denominations.Where(a => (a <= value && !AllPossibleSplits.Keys.Contains(a)));

        if (remainingDenominations.Count() > 0)
            hightestdenomination = remainingDenominations.Max();
        else
            hightestdenomination = 0;

        var splits = new List<double>(); 

        if (hightestdenomination != 0)
        {
            int valueToSplit = value;
            while (valueToSplit > 0)
            {
                foreach (double denomination in remainingDenominations.Where(a => a <= valueToSplit))
                {
                    int absoluteValue = (int) (valueToSplit/denomination);
                    valueToSplit = valueToSplit - (int) (absoluteValue*denomination);
                    int absoluteValueSplit = 0;

                    while (absoluteValueSplit < absoluteValue)
                    {
                        splits.Add(denomination);
                        absoluteValueSplit++;
                    }
                }
           }   
        }

        AllPossibleSplits[hightestdenomination] = splits;
    }

    return AllPossibleSplits;
}

Ответы [ 5 ]

2 голосов
/ 07 декабря 2011

Вы можете рассматривать это как проблему обхода дерева:

Здесь вы проходите через дерево и проверяете следующее:

Is the cost of the path currently lower then what I want 
 -> Go deeper in the tree

Is the cost of the path currently higher then what I want 
 -> Stop

Is the cost of the path currently the same as what I want 
 -> Permutation found

Вот пример: вы хотитеполучить все возможные перестановки в 25 долларов, с 5, 10 и 20 долларовых купюр.Синий означает, что cost < 25, красный означает cost > 25, а зеленый означает cost = 25 enter image description here ОТКАЗ ОТ ИЗОБРАЖЕНИЯ: Возможно, в нем есть некоторые ошибки, но хорошо вы поняли

Такжеесли вы сделаете это так, то получится перестановка, например, 5,5,5,10 <> 10,5,5,10, поэтому сохраните список решений, которые у вас уже есть, чтобы вы не получили эти кратные числа.Также у этого дерева есть несколько большой (спорный) коэффициент ветвления (10), поэтому, если вы получаете большие числа, есть МНОГО возможных вариантов.Не создавайте сначала целое дерево и не проходите через него.Это может сложить (я не могу себе представить, сколько существует возможностей заработать, как $ 1.000.000).

2 голосов
/ 07 декабря 2011

Хорошо, опубликованный алгоритм только дает вам взгляд на все возможные перестановки, пробовал его со значением 1, он дает ответы вроде:

  • 1
  • 0,25, 0,25, 0,25, 0,25
  • 0,1, 0,1, 0,1, 0,1, 0,1, 0,1, 0,1, 0,1, 0,10,1.,.

Но это только взгляд на весь ответ, пропущенные ответы, такие как 0,25, 0,25, 0,1, 0,1, 0,1, 0,1, 0,1 просто упомянуть один.Реализация собственного алгоритма - хороший способ сделать это.Я стажер в вычислительных науках, и я могу придумать алгоритм для этого на вершине моей головы, не такой сложный, но работающий.Парень, который писал прямо передо мной, дал хороший совет: переходите от наибольшего к наименьшему возможному сплиту, рассчитывайте максимальное количество вхождений и продолжайте с меньшими суммами до тех пор, пока не закончите с 0 отдыхом.Чтобы получить все возможные решения, это немного больше работы, но решение, которое вы предоставили, дает решение на другую максимальную сумму.

0 голосов
/ 07 декабря 2011

Хотя я чувствую, что это интервью для работы, вы должны быть в состоянии написать этот код, но я больше готов дать вам толчок в правильном направлении.Это классическая задача программирования, требующая простой математики, и я объясню ниже.Подумайте о том, чтобы иметь по 1 из каждой конфессии, как бы вы разделили их в реальной жизни.Ну, во-первых, вы должны составить кучу каждого наименования, которая в данном случае соответствует переменной, т.е. var сотойDollarNotes, var fiftyDollarNotes или, альтернативно, объекту со свойствами на этот счет.

, тогда как ваша сумма не равна нулю.возьмите сумму в 100 долларов и добавьте одну к переменной стоDollarNotes, повторяйте, пока не сможете снять 100 долларов.Продолжайте с меньшими суммами до тех пор, пока у вас не останется ни одной суммы.

И у вас есть алгоритм жадности в скорлупе.

0 голосов
/ 07 декабря 2011

Не усложняйте проблему.

Допустим, у вас есть 51 монета. Используйте самый большой счет, который у вас есть (50) 51-50 = 1 Затем используйте самую большую монету, которая у вас есть (1) 1-1 = 1

И вот, пожалуйста.

Код просто просматривает весь список значений и использует максимально возможный счет / деноминацию и делает то же самое для всего, что осталось, пока ничего не осталось.

0 голосов
/ 07 декабря 2011

Возможно, вы захотите взглянуть на алгоритм жадности .

...