根据C

时间:2017-06-12 16:02:58

标签: c loops if-statement stdio

我正在阅读以前的纸质问题,并发现了一个问题,要求我根据每个客户消耗的单位(电量)来生成账单。有一张表格,指示如何进行计算。我已经使用if else语句以非常基本的方式创建了程序。我想知道是否有比使用if else更好的方法。也许循环?我尝试使用循环,但它对我来说不切实际,因为范围不是恒定的。 这是该问题的一部分的屏幕截图。Question Screenshot

我创建的计算函数如下。

void findBill(int table[],float ar[],int size)
{
int i; 
float bill;
for(i=0; i<7 ; i++)
{
    if((table[i]>=0)&&(table[i]<=5))
    {   bill=table[i]*3.0;
    }
    else if((table[i]>=6)&&(table[i]<=10))
    {   bill=5*3.0+(table[i]-5)*7.0;
    }
    else if((table[i]>=11)&&(table[i]<=15))
    {   bill=5*3.0+5*7.0+(table[i]-10)*15.0;
    }
    else if((table[i]>=16)&&(table[i]<=20))
    {   bill=5*3.0+5*7.0+5*15.0+(table[i]-15)*30.0;
    }
    else if((table[i]>=21)&&(table[i]<=25))
    {   bill=5*3.0+5*7.0+5*15.0+5*30.0+(table[i]-20)*50.0;
    }
    else if((table[i]>=26)&&(table[i]<=30))
    {   bill=5*3.0+5*7.0+5*15.0+5*30.0+5*50.0+(table[i]-25)*75.0;
    }
    else if((table[i]>=31)&&(table[i]<=40))
    {   bill=5*3.0+5*7.0+5*15.0+5*30.0+5*50.0+5*75.0+(table[i]-30)*90.0;
    }
    else if((table[i]>=41)&&(table[i]<=50))
    {   bill=5*3.0+5*7.0+5*15.0+5*30.0+5*50.0+5*75.0+10*90.0+(table[i]-40)*105.0;
    }
    else if((table[i]>=51)&&(table[i]<=75))
    {   bill=5*3.0+5*7.0+5*15.0+5*30.0+5*50.0+5*75.0+10*90.0+10*105.0+(table[i]-50)*110.0;
    }
    else if(table[i]>75)
    {   bill=5*3.0+5*7.0+5*15.0+5*30.0+5*50.0+5*75.0+10*90.0+10*105.0+25*110.0+(table[i]-75)*120.0;
    }

    ar[i]=bill; 
}

}

即使这有效,我觉得这是不好的编码,如果有100个范围怎么办?请建议我另一种更简单的方法,而不是编写简单的if else语句。

P.S:我是初学者,所以请在C中使用stdio.h建议答案。

提前致谢。

3 个答案:

答案 0 :(得分:2)

我写了一个比你当前的例子更具扩展性的小程序。它使用循环,因此它具有O(n)时间和空间复杂度,因为您的程序对于两者都具有恒定的复杂性。尽管如此,我的代码将计算任何填充任何值的大小范围的值。此代码确实要求您在范围内实际硬编码,但这相对容易摆脱。

int calcBill(int input){
        int total = 0;
        int billCost[] = {3,7,15,30,50,75,90,105,110,120};
        int billRange[] = {5,10,15,20,25,30,40,50,75,200};
        int rangeAdd[10];
        int sizeOfRange = sizeof(billCost)/sizeof(int);
        //add up the first section
        int i = 0;
        for(; i<sizeOfRange; i++){
                if(i == 0)
                        rangeAdd[i] = billCost[i] * billRange[i];
                else {
                        rangeAdd[i] = billCost[i] * (billRange[i] - billRange[i-1]);
                        rangeAdd[i] += rangeAdd[i-1];
                }
        }
        i = 0;
        for(; i<sizeOfRange; i++){
                if(billRange[i] > input)
                        break;
        }
        if(i == 0){
                total = input * billCost[0];
        }
        else {
                total += (input - billRange[i-1]) * billCost[i];
                if(i > 0)
                        total += rangeAdd[i-1];
        }
        printf("%d %d\n", input, total);
        return total;
}

此代码使用两个数组(billCost和billRange)来计算在使用给定范围内的所有单位时每个帐单的成本。例如,25个单位的账单存储在rangeAdd数组的索引4处,30个单位的账单存储在索引5处。这很容易计算,只是在两个数组上循环。然后代码找到两个数组的单位下降的最大范围的索引(对于36的输入,即31-40的范围,或索引7)。该代码计算该范围内的单位数,并将该范围的总帐单(单位*价格)添加到其正下方索引的rangeAdd值中保存的预先计算的值。

显然,如果你运行这个程序数百次,每次都会重新计算这个函数中的rangeAdd数组。您可以预先计算此值并将其作为变量传递给函数。这只是一个概念证明,可以提高效率。

答案 1 :(得分:1)

由于根据单位数量计算成本没有固定模式,因此难以避免硬编码数组。

但我认为你所做的实施可以更清洁。

我认为更好的方法是以下

void findBill(int table[], float arr[], int size) {

    int levels[]={75,50,40,30,25,20,15,10,5,0};
    float costs[]={120,110,105,90,75,50,30,15,7,3};
    int level_cnt=sizeof(levels) / sizeof(int);

    for(int i=0;i<size;i++) {
        arr[i]=0;
        for(int c=0;c<level_cnt;c++) {
            if(table[i]>levels[c]) {
                arr[i]+=(table[i]-levels[c])*costs[c];
                table[i]=levels[c];
            }
        }
    }
}

答案 2 :(得分:-1)

你正在考虑这样的事吗?代码很容易理解。如果需要,请随时提问。

#include <limits.h> // MAX_INT
#define MIN(a, b) {((a) < (b)) ?  (a) : (b);

typedef struct RATE_DEF
{
    float slice;    // ceiling for this rate - ceiling fro previous rate
    float ppu;      // price per unit
};


const struct RATE_DEF RATE_TABLE[] = 
{
    { 5,   3.f },
    { 5,   7.f },
        /* ... */
    { MAX_INT, 120.f },  // much better
};

#define NUM_RATES (sizeof(RATE_TABLE) / sizeof(RATE_TABLE[0]))

void findBill(int table[],float ar[],int size)
{
int i, j, amt, slice; 
float bill;
for(i=0; i<7 ; i++)
{
    amt = table[i];
    bill = 0.f;

    for (j = 0; amt > 0 && j < NUM_RATES; ++j)
    {
        slice = MIN(amnt, RATE_TABLE[j].slice);
        bill += (slice * RATE_TABLE[j].ppu);
        amt -= slice;
    }

    ar[i] = bill; 
}

[编辑]有一些错别字,但今天我觉得很懒:)