计算有限面额的变化

时间:2011-12-06 19:42:32

标签: c++ big-o

我正在编写一个计算变更的函数 - $ 1,$ 5,$ 10,$ 20,$ 50和$ 100是我可以使用的账单类型。每个面额也从当前时间抽屉中的有限数量的账单中减去。

这里也没有便宜,镍币,硬币或四分之一的处理,只需要全部金额。

这就是我提出的:

更新

当抽屉里没有任何面额的钞票时,该功能现在有一个错误处理的更正,向用户提供一条消息,以便为抽屉获得更多的钱。

// Set elsewhere in the program
int numberOnesLeft;
int numberFivesLeft;
int numberTensLeft;
int numberTwentiesLeft;
int numberFiftiesLeft;
int numberHundredsLeft;

int numberOfOnes = 0;
int numberOfFives = 0;
int numberOfTens = 0;
int numberOfTwenties = 0;
int numberOfFifties = 0;
int numberOfHundreds = 0;

void CalculateChange(float amount)
{
    char tempStr[128];

    while(amount >= 100.0)
    {
        if(numberOfHundreds >= numberHundredsLeft)
            break;
        else
            amount = amount - 100.0;
        numberOfHundreds++;
    }
    while(amount >= 50.0)
    {
        if(numberOfFifties >= numberFiftiesLeft)
            break;
        else
            amount = amount - 50.0;
        numberOfFifties++;
    }
    while(amount >= 20.0)
    {
        if(numberOfTwenties >= numberTwentiesLeft)
            break;
        else
            amount = amount - 20.0;
        numberOfTwenties++;
    }
    while(amount >= 10.0)
    {
        if(numberOfTens >= numberTensLeft)
            break;
        else
            amount = amount - 10.0;
        numberOfTens++;
    }
    while(amount >= 5.0)
    {
        if(numberOfFives >= numberFivesLeft)
            break;
        else
            amount = amount - 5.0;
        numberOfFives++;
    }
    while(amount >= 1.0)
    {
        if(numberOfOnes >= numberOnesLeft)
            break;
        else
            amount = amount - 1.0;
        numberOfOnes++;
    }
    if(amount > 0)
    {
      printf("You are still owed: $");
      sprintf(tempStr, "%.2f", amount);
      printf(tempStr);
      printf("\n\n");
      printf("Please obtain more money for the drawer\n");
    }
}

根据arasmussen的有价值修正,其中的大O是O(x * n)= x * O(n)= O(n),其中x是面额的数量有。

计算每种面额的算法更快吗?

3 个答案:

答案 0 :(得分:2)

减少循环?

凭借无限的账单,应该足够简单。

int num_100 = amount / 100; amount %= 100;
int num_50  = amount / 50;  amount %= 50;
int num_20  = amount / 20;  amount %= 20;
int num_10  = amount / 10;  amount %= 10;
int num_5   = amount / 5;   amount %= 5;
int num_1   = amount;

有限数量的账单......

void get_change(int &amount, int &left, int denom) {
  int num = amount / denom;
  if (left < num)
    num = left;
  left -= num;
  amount -= num * denom;
}

int amount = ...;
get_change(amount, num_100 , 100);
get_change(amount, num_50  , 50);
get_change(amount, num_20  , 20);
get_change(amount, num_10  , 10);
get_change(amount, num_5   , 5);
num_1 = amount;

答案 1 :(得分:1)

您应该能够使用modulo operator显着降低复杂性。

答案 2 :(得分:0)

如果我正确地理解了你的问题......有一个封闭形式的公式,给出了一些方法,你可以得到总和N,给定一组可用的硬币。它使用生成系列 - 来自本科级数学的东西。如果您有兴趣,请访问link,请参阅您可以在多少种方式中更改1美元?

此类公式的存在意味着您可以比 O(n ^ 6)

更快地计算出方式的数量

格雷厄姆,克努特和帕塔什尼克有很好的书,可以解读这类重数学的东西 - 具体数学