一个算法

panda_w 2003-07-10 04:38:25
在做一个小东西,遇到了一个问题
关于收费的算法:(类似停车场收费)

假设一天分为连续的n个时段,每个时段的费率不一致,车辆进停车场的时间为tmIN,出停车场的时间为tmOUT;
假设tmOUT - tmIN <24小时

怎么算出此时间内停车的费用

时段费率可以如此来表示

typedef struct MM
{
double fM; //费率
CTime tmFrom;//时段起始时间
CTime tmTo; //时段中止时间
}DMONEY;
...全文
58 点赞 收藏 31
写回复
31 条回复
wlpwlp1977 2003年07月11日
up
回复 点赞
zteliubin 2003年07月11日
我就不写算法了,提醒大家不只是单独计算3:00-9:00这样简单的计算问题。
回复 点赞
ftp123 2003年07月11日
如果是这样的话,可以再开一帖,把具体的规则全都说出来,我们来个具体的算法,这样好不
好?虽然会很费力,但是我现在很想实现这个算法。有问题吗?如果没的话,把它帖出来吧。呵呵。
可以加我的qq 30981344
回复 点赞
arfi 2003年07月11日
在工资计算中有一项速算扣除数,仿照这个来写一下。

假设存车一天缴费100元,各时段费率设置如下:

时段 费率(%) 速算数
0 - 4 10 0
4 - 8 15 10
8 -12 20 25
12-16 5 45
16-20 30 50
20-24 20 80

速算数是假设每辆车都是从0时开始,存储到该时段的起始时间需缴纳的费用。

则有:如果从0时存车到18时,需缴纳的费用为100*30%*(18-16)/(20-16) + 50 = 65(元)。

这样从m时存车到n时的费用计算为
money = 从0时存车到n时需缴纳的费用 - 从0时存车到m时需缴纳的费用
= (100*(n所在时段费率)*((n-n下限时)/(n上限时-n下限时))+n速算数) - (100*(m所在时段费率)*((m-m下限时)/(m上限时-m下限时))+m速算数)
其中0 <= m <= n <= 24
回复 点赞
zteliubin 2003年07月11日
还有可能不同车型的费率不等,VIP的收费等等。

真正要做的话,需求方面还有很多工作要做!
回复 点赞
zteliubin 2003年07月11日
呵呵,一个真正适用的计费系统考虑的情况还很多,我上面说的除外,还有比如:
1。工作日/节假日的优惠问题
2。超过多少时间的一个折扣问题
3。针对特殊人群的优惠问题(比如教师,军人,内部人员)
等等,还有一些暂时没有想到。
以上规则可能暂时不用,但是我认为应该考虑到这些规则的制定及处理,
可能超出讨论范围,但计费所考虑的东西的确应该是很多!

欢迎大家讨论!
回复 点赞
cdocument 2003年07月11日
如果要求在计算的时候实时性高的话,是否可以考虑这样:当然是在n不是太大的时候。
在程序启动的时候制作出这样一张表,计算出任意两个时段发生费用。存储起来,以后计算每一辆车的费用的时候根据车timein和timeout在这个表中查处相关费用。

这样这样做可以稍稍保证实时计算效率,但是在程序启动时可能要慢些。这个表的建立我就想不出什么好办法了,分时计算好像少不了。

这样做的好处是如果有大量的车>n*(n-1)需要计算的话,效率高些,就好像一个调色板。不知是否合楼主之意?^_^
回复 点赞
ftp123 2003年07月11日
好吧,我写个详细的方法
计费的问题在于时间段不同,如果一开始就记下某一辆车的车牌号码,因为这个是唯一的,
下面可以有两个方法,一是从车子一开始停下就开始计费,这样可以在时间段变化的时候改变
计率,就是我说的x,因为x不同,所以a不同,这里的a就是计率;二 可以在车子开走的时候计费,这是因为车子停留的时间不超过24小时,而在这个时间内不会造成重复,所以每个时间段的计率都不同,所以可以这样做,这样计费就为每个时间段的钱的总和,这样计费就出来了。是不是和我说的是一样的啊。
比如上面说的跨天计费,这个根本不存在问题,只要你把时间设成24小时制的就行了,轻松解决跨天计费问题,为什么呢?因为在24小时内,它们根本就不相同,没有重复的。
至于位置问题,应该是很好解决。因为一个位置只可以停一辆车子。
呵呵,这个问题应该是大一生就可以解决的事情啊。
是不是还有优惠规则啊,有的话,应该写出来啊,这样我们就好写算法,呵呵。
你看看我写的对不对啊。
回复 点赞
zteliubin 2003年07月11日
1.首先你的题目计费单位没有明确,假设一个用户停车20分钟,是按1个小时还是20分钟收费
2.跨计费时段的规则没有确定,假设一个用户在8:30-9:30停车,8:00-9:00为2元每小时,9:00
-10.00为3:00每小时,此时是按哪种费率收费,因为可能有3种收费结果(2,2.5,3),假设最小计 费单位为 1小时,一般都收费方会按费率高的时段靠(3元/小时),

具体计费可处理如下:
1。计算总的停车时间。
2。得出总的计费时长(比如:停车2小时45分,那么如果最小计费时长1小时,则总得计费时长 为3小时,如果最小计费时长为2小时,则总的计费时长为4小时,或者2小时,根据设定规则处理)
3。把停车开始时间修改为整点(往前往后都可,可有利于车主,也可有利于停车场,可设定)
4。按整的计费时段分段计费,求总和(因为第3步的处理,这时很容易找出开始的计费时段)。

以上是简单算法:
如果有费率交迭情况,比如:一天只收20,或者0:00-6:00只收10元,则要考虑取最优惠的费率
进行计费(根据开始时间比较费率),还有可能有其他的优惠或折扣情况,具体情况具体处理。

以上是简单的处理过程,不知是否满意,可联系: liubin9408@sina.com
回复 点赞
panda_w 2003年07月11日
to ftp123(应付工作) :
不知道你现在的工作的薪水怎么样,不如来我这里工作算了
不过,我还真的没有看明白你的答案
to zteliubin(bill) ( ) ,这里存在大量计算,效率当然是需要考虑的,是否有好的方法?
回复 点赞
ftp123 2003年07月11日
呵呵,结帖子吧!
我到,怎么按分钟计费啊,不过想想也是啊,现在的人多精明啊,不可能给人白停车子的。
我想就是这样的话,也好算啊,我想了下,计算并不复杂啊,就是想简化也简化不到那里去,
除非是这样,有几辆车子从停的时候到走的时候相差不了多少时间,或者是这样,就是有几
辆车子走的时候时间是相同,不同的是停车子的时候,他们的时间差为整小时,这样就可以
节约计算了,其他的我想还是要重复计算的。
我现在大概知道你的意图了,和我以前写程序的时候一样,总是想尽量的节省cpu时间,但是
现在的机器多好啊,不在乎这几个cpu时间的,呵呵!
不过我有个想法可能可以节约你的时间,我想可以把设一张表,就是上面他们说的那样,但是
具体的细节不一样,我想可以先计算出时间为1,2,5,10,30。60分钟的计费,把她们放在表里面,比如说某一辆车子从停车子到走的时间为1小时58分钟,你看看用上面我划分的那几个时间段是不是很容易算出来啊,呵呵。是的吧?我有没有说错。
我想式子应该是这样的:60+30+10+10+5+2+1。是不是很方便?
看来你真的应该请我去为你做事情了,呵呵。
记得在结帖的时候给我加分啊,呵呵!
回复 点赞
zteliubin 2003年07月11日
RE:回复人: LeeAn(李安) ( ) 信誉:100
难道停车收费不是一个时段一个时段的算么?????然后将各时段的值相加。
我没车,没停过,;-(
------------------------------------------

有一个最小计费单位的问题,比如:
8:50 - 9: 15分停车,假设计费单位是分钟,你说的办法没有问题,
假设计费单位为半个小时,则有两种选择:按8:30-9:00还是9:00-9:30计费,需要定一个规则,
因为费率是半个小时的,不是分钟的,你不能:f1*10/30+f2*15/30.
如果计费单位为1个小时,则同上,只能取小时费率,不能取分钟费率。

计费处理的复杂主要是规则的复杂,你不能只是简单的用数学方法把它表示出来!
或许是我考虑得太多?!
回复 点赞
panda_w 2003年07月11日
其实,我是在做一个计费的程序,是按照分钟计费的(不够一分钟就舍去),所以最多的时段也是有限的。

大家的方法有许多我是没有考虑到,非常感谢。

回复 点赞
LeeAn 2003年07月11日
回复人: zteliubin(bill) ( )
跨计费时段的规则没有确定,假设一个用户在8:30-9:30停车,8:00-9:00为2元每小时,9:00
-10.00为3:00每小时,此时是按哪种费率收费,因为可能有3种收费结果(2,2.5,3),假设最小计 费单位为 1小时,一般都收费方会按费率高的时段靠(3元/小时),



---------------------------------------------------------------------------------
难道停车收费不是一个时段一个时段的算么?????然后将各时段的值相加。
我没车,没停过,;-(
回复 点赞
snipersu 2003年07月11日
typedef struct MM
{
double fM; //费率
CTime tmFrom;//时段起始时间
CTime tmTo; //时段中止时间
}DMONEY;

///////////////////////////////////////////////////////////////////////////////
提供点建议:
我看楼主的结构体中有double型fM这个成员,我觉的不好,因为在某时段的费率一般是固定定的,一天最多大概也就24个不同的收费时段吧(多了也无所谓^v^),我建议把“费率表”做成单独的(比如用map表示,且单独出来)用的时候查一下就行了,不用每个结构体都存一个自己的费率,关键是记下车辆存放的时间段,在计算的时候要用哪段只要去查那段的费率就行了。
拙见!
回复 点赞
zteliubin 2003年07月11日
我觉得,目前出现的答案中我觉得没有一个满意的。
连很简单的最小计费时长,跨时段计费等问题都未考虑,
这些问题,应该不是简单相加或四舍五入就可以得到。
事实上,这个程序也不是大家花几分钟就可以完成的。

当然,我也不清楚楼主主要想得到什么?
回复 点赞
hpho 2003年07月11日
我觉得 arfi() 的算法好.
struct time_vector{
double percentage[]; // 基本数据(时段,费率(%),速算数等)
....
....
virtual double money()=0;
};

class time_point:public time_vector{ // 从0时存车到t时需缴纳的费用
double m_;
public:
time_point(int t);
const time_point& operator -(const time_point& other);
double money();
};

class time_line:public time_vector{
time_vector& p1_;
time_vector& p2_;
public:
time_line(time_vector& p1, time_vector& p2):p1_(p1), p2_(p2){}
double money(){return p1_-p2_;}
};
回复 点赞
lubin59 2003年07月11日
高手
回复 点赞
fixopen 2003年07月11日
struct DurationFee
{
time_t startTime;
time_t stopTime;
double unitFee;
};

vector<Duration> durationTable; //it's the fee rule at time; 升序排列

time_t beginTime = x;
time_t endTime = y;

double calc(time_t beginTime, time_t endTime)
{
double result = 0;
//找到开始时段
int startDuration = 0;
for (vector<Duration>::iterator i = durationTable.begin(); i != durationTable.end(); ++i)
{
if (i->stopTime > beginTime)
break;
++startDuration;
}

//找到结束时段
int stopDuration = 0;
for (vector<Duration>::iterator i = durationTable.begin(); i != durationTable.end(); ++i)
{
if (i->stopTime >= endTime)
break;
++stopDuration;
}

assert (startDuration <= stopDuration) //if assert failure, the durationTable maybe error

result = (durationTable[startDuration].stopTime - beginTime) * durationTable[startDuration].unitFee;
for (int i = startDuration + 1; i < stopDuration; ++i)
result += (durationTable[i].stopTime - durartionTable[i].Time) * durationTable[startDuration].unitFee;
result += (endTime - durationTable[stopDuration]) * durationTable[stopDuration].unitFee;
return result;
}

匆匆写成,未及细考,不周之处见谅
回复 点赞
ftp123 2003年07月10日
我晕,你怎么找到工作的啊?
哎,我大一的时候就会算了,但是我现在还是没找到工作,郁闷ing。
这个就好比是算一个数学问题一样,看下面的,很简单:
y=3x+a;
1. a=100 0<x<100
1. a=200 100=<x<=200
哎,不会这个也不会算吧。
回复 点赞
发动态
发帖子
C语言
创建于2007-09-28

3.2w+

社区成员

24.0w+

社区内容

C语言相关问题讨论
社区公告
暂无公告