好吧我不知道这是否是一个有效的问题,但我在这里发帖是因为我不知道还有什么地方可以解决这个问题。我刚刚开始在大学学习半年的编程,我们刚刚参加了期末考试,但我失败了。基本上,有4个问题,而第二个看起来很容易,实际上很棘手,我只是无法弄清楚它应该如何完成。
基本上问题是:有一家银行,当人们登录做生意时,你需要编写一个程序来记录他们登录的时间(0-24h),分钟(0-59),他们选择的交易类型(1用于登录银行卡,-1用于登出同一张银行卡,2用于输入账户,2用于提取)最后是他们的银行账号(如果他们按下先前1或-1),或者他们撤回或投入的金额(如果他们选择2或-2)。
基本上我们就是这样做的:
int n; //size of the array or number of ppl who transacted that day
cin >> n;
int bank[n][4];
for (int i=0; i<n; ++i)
{
cin >> bank[n][0];
cin >> bank[n][1];
cin >> bank[n][2];
cin >> bank[n][3];
}
这会填满所有信息,然后
在白天,4个客户的输入样本基本上是这样的:
这是我无法解决的部分:
我们的测试告诉我们:有多少人从12点钟到13点钟登录?
起初我做了
int count=0;
for (int i=0; i<n; ++i)
{
if (bank[i][0]==12)
{
count=count+1;
}
}
cout << count;
问题在于,它不会考虑在12之前使用第三列中的1登录的人,但是在晚于1时使用-1注销。这意味着他们仍然在12点到1点之间登录。
然后我做了
int count=0;
for (int i=0; i<n; ++i)
{
if (bank[i][0]==12)
{
count=count+1;
}
if (bank[i][2]==-1)
{
count=count+1;
}
}
cout << count;
然后我意识到这会计算一些登录两次,因为如果他们以12登录,例如1,那么在3点钟退出时输入-1将计算一个人两次。
它还告诉我们任何人登录的最长时间,假设银行在24:00将所有人开除。老实说,我甚至不确定如何开始那个。
编辑:SORRY我编辑了一堆东西,以使代码更清晰,更正确。我不太擅长这个,但原谅我的错误
答案 0 :(得分:3)
我不知道银行系统是如何运作的。所以我为你做了一个最小的例子。 我也不知道你以前是否使用过课程,所以我没有写过。
我清理了你的代码:
//Use these enums
enum action { action_login = 1, action_logout = -1, action_input = 2, action_output = -2 };
enum information {information_time_h, information_time_m, information_action, information_bankNumber};
//Place this in the function you have
int peapelToInput = 0; //size of the array or number of ppl who transacted that day
cin >> peapelToInput;
for (int i=0; i<peapelToInput; ++i)
{
//Maby add error handeling? When some one inputs a 'a', it won't do what you want.
cin bank[i][information_time_h];
cin bank[i][information_time_m];
cin bank[i][information_action];
cin bank[i][information_bankNumber];
}
正如您所看到的,我通过添加枚举使代码更清晰。这使得开发变得更加容易。
登录代码:
int count=0;
int bankSize = bank.size(); //I guess it's a vector?
for (int i=0; i < bankSize; ++i)
{
if (bank[i][information_time_h] == 12 && bank[i][information_action] == action_login)
count++;
}
cout << "logins at 12:00 - 12:59:" << count << endl;
你可以在1中进行2次检查,如果我在12点到12点59分之间增加了计数。您是否需要排除已登出的人?
最长的时间代码:
//A function to search when he is logedout
int findLogoutIndex(int start, int accountNumber, XXX bank)
{
int bankSize = bank.size();
for (int i=start; i < bankSize; ++i)
if( bank[i][information_action] == action_logout && bank[i][information_bankNumber] == accountNumber)
return i;
return -1; //Handle this error
}
//And how it workes
int logenst = 0;
int indexLongest = 0;
int bankSize = bank.size(); //I guess it's a vector?
for (int i=0; i < bankSize; ++i)
{
if( bank[i][information_action] != action_login )
continue;
int logoutIndex = findLogoutIndex(i,bank[i][information_bankNumber],bank);
//check if logoutIndex is not -1, or handle the error on an other way.
int loginTimeHour = bank[logoutIndex][information_time_h] - bank[i][information_time_h];
int loginTimeMinute = bank[logoutIndex][information_time_m] - bank[i][information_time_m];
int loginTime = (loginTimeHour * 100) + loginTimeMinute;
if( logenst < loginTime)
{
logenst = loginTime;
indexLongest = i;
}
}
cout << "longest is: H:" << bank[indexLongest][information_time_h] << " M: " << bank[indexLongest][information_time_m] << endl;
您不需要保留时间格式,这种方式使比较容易得多。只需保存最长的登录时间及其索引号即可。这样您就可以轻松访问所需的所有数据。
我没有花时间写“好代码”。但是你问过它是如何完成的,我想这很好理解它?
我没有测试代码并在记事本中写了它。所以我不知道它是否会编译。
答案 1 :(得分:0)
您需要知道的第一件事是问题实际上是在问什么。在第一种情况下,从12点钟到1点钟登录了多少人?可能意味着多件事。这可能意味着在整个期间有多少人登录,或者在这两个小时之间的任何给定时间登录了多少人。不同之处在于,是否有人在12:15登录并在12:30退出。第二个问题是计算某人登录的最长时间,这可以同时完成。
一种可能的方法是管理从用户ID到登录时间的查找表。您可以线性地读取输入,只要有人登录,您就可以在表格中添加条目(acct, time)
。当他们注销时,您查找帐号并计算时间差。如果差值大于最大值,则存储新的最大值。
对于第一个问题,在12处,您可以创建一组从该查找表登录的人员。每当有人在该时间和1之间退出时,您会发现该人是否在该集合中,如果有,则将其删除。当您在1之后找到第一个操作时,该集合包含从12到1整个时间段内登录的所有人的帐号。
如果问题是让所有人在此期间任何时间记录,而不是从1中删除那些在1之前注销的用户,则需要包含登录的新用户在这期间。在该期间结束时,该集合包含该期间内任何时间登录的所有用户。
您只需要对输入数据执行一次传递,这意味着您甚至不需要将所有事务存储在内存中,只需要存储上面所需的映射/集。操作的总成本为O(n log n)
。 (免责声明:我没有做过数学计算,这是预感:))
答案 2 :(得分:0)
没有测试过这个。然而,所遵循的过程应该是正确的。
我确信这仍然可以在执行速度方面进行优化。
此外,我假设在12时你的意思是12:00,到时间1你的意思是13:00。
int main()
{
int answer = 0;
// For each transaction
for ( int i = 0; i < count; i++ ) {
// If logged in before 12:00
// bank[i][2] > 0 tells you user logged in.
if ( bank[i][0] < 12 && bank[i][2] > 0 ) {
// Loop through each following transaction.
for ( int j = i + 1; j < count; j++ ) {
// If logged out after 13:00
if ( bank[j][0] > 13 && bank[j][2] < 0 ) {
// Now to check if it was the same user who logged in earlier - how?:
// Only way to differentiate is by comparing the transaction amounts and types.
if ( (bank[i][3] == bank[j][3]) && (bank[i][2] == -1*bank[j][2]) ) { // log-in code = -1 * log-out code.
answer++; // Number of transactions that spanned from before 12:00 till after 13:00.
// Remember, a single person can't have multiple log-ins at the same time. ( assumption )
}
}
}
}
}
}