0

これが有効な質問であるかどうかはわかりませんが、他にどこに向けるべきかわからないため、ここに投稿しています。この半年間、大学でプログラミングの勉強を始めたばかりで、最終試験がありましたが、失敗しました。基本的に4つの問題があり、2番目の問題は簡単に見えましたが、実際にはトリッキーで、どうすればいいのかわかりません.

基本的に問題は次のとおりです。銀行があり、人々がビジネスを行うためにログインするとき、ログインした時間 (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];
}

これですべての情報が埋まり、

基本的に、1 日の 4 人の顧客のサンプル入力は次のようになります。

  1. 11 40 1 458965
  2. 12 20 2 6000
  3. 15 40 -1 458965
  4. 16 25 -2 18000

ここに私が解決できなかった部分があります:

私たちのテストでは、12 時から 13 時までに何人がログインしたかを尋ねました。

最初はやった

int count=0;
for (int i=0; i<n; ++i)
{
  if (bank[i][0]==12)
{
  count=count+1;
}
}

cout << count;

これの問題は、12 時より前に 3 列目に 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 でログアウトすると、その 1 人が 2 回カウントされるためです。

また、銀行が 24:00 に全員を追い出すと仮定して、ユーザーがログインしていた最長期間を尋ねました。正直なところ、それをどのように開始するかさえわかりません。

編集:申し訳ありませんが、コードをより明確で正しいものにするために、たくさんのものを編集しました。私はこれがあまり得意ではありませんが、私の過ちを許してください

4

3 に答える 3

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];
}

ご覧のとおり、enum を追加してコードをすっきりさせました。これにより、開発が非常に簡単になります。

ログインコード:

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;

12:00 から 12:59 にログインしたときにカウントをインクリメントする場合、1 つで 2 つのチェックを実行できます。ログアウトした人を除外する必要がありますか?

最長タイムコード:

//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;

時間形式を保持する必要はありません。この方法により、比較がはるかに簡単になります。最長のログイン時間とそのインデックス番号を保存するだけです。そうすれば、必要なすべてのデータに簡単にアクセスできます。

「良いコード」を書くのに時間をかけませんでした。しかし、あなたはそれをどのように行うことができるかを尋ねました.これはそれを理解するのに十分だと思いますか?

私はコードをテストせず、メモ帳に書きました。したがって、コンパイルされるかどうかはわかりません。

于 2013-01-10T12:53:22.130 に答える
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 )
                    }
                }
            }
        }
    }
}
于 2013-01-10T13:04:07.440 に答える
0

最初に知っておく必要があるのは、質問が実際に何を求めているかということです。最初のケースでは、12 時から 1 時までに何人がログインしていましたか? 複数のことを意味します。全期間中に何人がログインしたか、またはその 2 時間の間に何人がログインしたかを意味する場合があります。違いは、12:15にログインして12:30にログアウトした人をカウントするかしないかです。2 番目の質問は、誰かがログインしていた最長期間を計算することであり、これは同時に行うことができます。

考えられるアプローチの 1 つは、ユーザー ID からログイン時間までのルックアップ テーブルを管理することです。誰かがログインし(acct, time)てテーブルにエントリを追加するたびに、入力を直線的に読み取ります。彼らがログアウトしたら、アカウント番号を検索して時間の差を計算します。差が最大値より大きい場合は、新しい最大値を保存します。

最初の質問では、12 で、そのルックアップ テーブルからログインした一連のユーザーを作成できます。その時点から 1 の間に誰かがログアウトするたびに、その人がセットに含まれていたかどうかを確認し、含まれていた場合は削除します。1 の後の最初の操作を見つけると、セットには 12 から 1 までの全期間にログインしたすべての人のアカウント番号が含まれます。

質問が期間内の任意の時点でログに記録されたすべての人を取得することであった場合、1 より前にログアウトしたユーザーをセットから削除するのではなく、期間内にログインした新しいユーザーを含める必要があります。期間の終わりに、セットには、期間内の任意の時点でログインしたすべてのユーザーが含まれます。

入力データに対して単一のパスを実行するだけで済みます。つまり、すべてのトランザクションをメモリに保存する必要さえなく、上記で必要なマップ/セットのみを保存する必要があります。操作の全体的なコストは、操作O(n log n)の数にあります。(免責事項:私は計算をしていません。これは推測です:))

于 2013-01-10T12:56:58.950 に答える