0

ユーザーに「学生ID番号」の入力を求め、それを配列に格納するプログラムの関数を書いています。学生番号は一意でなければならないため、関数を保存する前に、配列にその番号がまだないかどうかを確認する必要があります。また、これまでに格納された生徒数を表す int へのポインターも含まれます。私はいくつかのコードを書きましたが、機能していません:(誰か光を当ててください?これは私のコードです:

void update_student_id(int a[], int*pnum)
{
        int temp,h;
        for (h=0;h<=*pnum;h++){
                printf(">>>Student ID:");
                scanf("%d",&temp);
                        if (temp==a[h]){
                                printf("ERROR:%d has already been used!\n",temp);
                                h=*pnum+1;
                        }
                        else
                            h=*pnum+1;
            }
        a[*pnum]=temp;
        *pnum++;

OK、2 つの for ループを備えた新しいバージョンで、改善されていますが、まだ機能していません :(

void update_student_id(int a[], int*pnum)
{
    int temp,h,i;
    for (h=0;h<=*pnum;h++){
            printf(">>>Student ID:");
            scanf("%d",&temp);

            for(i=0;i<=*pnum;i++)
                    if (temp==a[i]){
                            printf("ERROR:%d has already been used!\n",temp);
                            i=*pnum+1;
                    }
                    else    i++;
            }
        a[*pnum]=temp;
        (*pnum)++;
}

デニスの助けを借りて解決された問題、最終的なコード:

void update_student_id(int a[], int*pnum)
{
    int temp,h,i,canary;
    for (h = 0; h <= *pnum; h++) {
            printf(">>>Student ID:");
            scanf("%d", &temp);

    canary = 0;
    for (i = 0; i < *pnum; i++) {
            if (temp == a[i]) {
            printf("ERROR:%d has already been used!\n",temp);
            canary = 1;
            break;
            }
    }
    if (canary == 0) {
            a[*pnum] = temp;
            (*pnum)++;
            break;
        }
}

return;}
4

2 に答える 2

0

したがって、主にわかるのは、数値をスキャンした後、その数値が既に配列に含まれているかどうかを実際に確認していないということです。特定のインデックスにあるかどうかを確認するだけです。

より具体的には、 for ループ内に if ステートメント以上のものが必要です。おそらく、これまでに使用されたインデックスを調べる別のループです。

編集: 最大の問題は、else 句で、インクリメントしないことiです。次に、printf を呼び出したかどうかを知らせるカナリア変数が必要です。

たとえば、これらのループに対する私のアイデアは次のとおりです。

for (h = 0; h < *pum; h++) {
    printf(">>>Student ID:");
    scanf("%d", &temp);

    canary = 0; // assuming you initialize this at beginning of function
    for (i = 0; i < *pnum; i++) {
        if (temp == a[i]) {
            printf("ERROR:%d has already been used!\n",temp);
            canary = 1;
            break;
        }
        // DON'T INCREMENT i, LOOP IS ALREADY DOING IT
    }

    // if canary is still 0, we know we haven't called that printf
    // and can add in the element. Only then do we increment the count.
    if (canary == 0) {
        a[*pnum] = temp;
        (*pnum)++;
    }
}
于 2012-08-07T17:56:08.137 に答える
0

ID をソートされた順序で維持できれば、多くの大きな最適化を得ることができます。これには、コンテナーとしての単純な配列からの移行がほぼ確実に含まれます。ヒープのようなものがぴったりです。配列を使用し続け、挿入が O(n) であることを気にしない場合は、ソート順を維持し、バイナリ検索で存在チェックを取得できます。残念ながら、標準ライブラリbsearch()関数は、どこにすべきかを教えてくれません一致が見つからない場合は要素を挿入します。独自の二分探索を正しく記述するのは驚くほど難しいことですが、正しく記述すれば再利用可能な優れたコードになります。必要なのは、要素が存在する場合は true または false を返す関数であり、一致する要素へのポインター、または存在しない場合はすぐ下の値 (または、それより小さい要素がない場合は配列ポインター自体) のいずれかです。一致するものが見つからない場合は、すべての大きな要素を 1 つの場所にシャッフルして、新しい要素を挿入します。

これは宿題なので、C に限られていると思いますが、C++ STLset<int>を使用すると、必要な作業を数行に減らすことができます。

于 2012-08-07T20:09:59.257 に答える