2

私は C に不慣れで、正直なところ、構造体の配列から特定の要素を削除することをどこから始めればよいかわかりません。

必要に応じて、ここで私のコード全体を表示およびコピーできます: http://pastebin.com/Zbrm2xyL

ほとんどの場合、関数「rmv_student」に関心があります。これは、ユーザーに確認を求めた後、その配列の他の要素をいじることなく、配列「st_array」から一致する ID 番号を持つ構造体を削除することになっています。関数「rmv_student」は次のとおりです。

void rmv_student(long id) // BROKEN
{
int i; // iterator
char response; // used to confirm deletion

for( i = 0; i < MAX; i++){
    if ( st_array[i].id == id){
        printf("Are you sure you want to delete %s %s, %d?\n", st_array[i].first_name, st_array[i].last_name, st_array[i].id);
        puts("You will not be able to undo the deletion.");
        puts("Enter 'y' to delete or 'n' to return to the main menu.");
        response = getchar();

        switch (response){

            case 'y':
                // delete

            case 'Y':
                // delete

            case 'n':
                main();

            case 'N':
                main();

            default:
                puts("Please enter 'y' or 'n'.");
                rmv_student(id);
        }
    }
}
if ( i == MAX ){
    printf("\nThere are no students with ID %d.\n\n", id);
    main();
}
}

2 つの質問があります。

  1. 私のスイッチケースは正しいですか?これはユーザーの入力文字を正しくテストしますか?

  2. 構造体を削除するにはどうすればよいですか?

あなたが尋ねる前に。はい、これは宿題です。そのため、私は配布資料を探しているのではなく、正しい方向へのポイントを探しているだけです。他の提案は大歓迎です。

注: 「menu_test_input」関数が本当に必要ないことは承知していますが、今のところはそのままにしておきます。

4

3 に答える 3

1

問題には 2 つの解決策が考えられます。どちらを使用するかは、配列要素の順序が重要かどうかによって異なります。

  1. 迅速な解決策: 配列内の最後の要素を削除する要素の位置にコピーし、配列内の要素の数を減らすだけです。

    int* array = ...;
    int elementCount = ...;
    ...
    int deletionIndex = ...;
    array[deletionIndex] = array[--elementCount];    //the deletion is actually a one liner :-)
    

    このソリューションは、ソートされていない配列を操作している場合はいつでも推奨されるソリューションであり、削除を行う場所に関係なく、一定の時間しかかかりません。

  2. 長い解決策: 削除された要素の後ろにあるすべての要素を 1 つ前に移動します。

    //setup is the same as for the fast solution
    elementCount--;
    for(int i = deletionIndex; i < elementCount; i++) array[i] = array[i+1];
    

    それほど難しいわけではありませんが、高速なソリューションよりもかなり複雑です。

    配列要素の相対的な順序を維持する必要があるときはいつでも、これを使用する必要があります。注文の価格は、ランタイムが移動する必要がある要素の量に依存することです。

于 2013-11-04T19:51:31.817 に答える
1

再帰呼び出しの代わりに、ループと return ステートメントを使用してください! 呼び出された関数が返されると、呼び出し後にコードが続行されることに注意してください。

代わりに、次の擬似コードのようなことを行います

do
{
    print_prompt()
    get_response()

} while (response is not legal)

if (response is yes)
    do_the_actual_deletion

配列 A の要素 X を削除する場合は、要素 X + 1 を X に移動し、要素 X + 2 を X + 1 に移動します。完了したら、サイズを 1 減らします。実際の「削除」は必要ありません。

于 2013-11-04T07:03:58.573 に答える