2017-07-10 16 views
0

私はこの間、私の頭をしばらく掻いてきました。私は非常にプログラミングに新しいので、私のコードは効率的ではないかもしれませんが、私は何がうまくいかないのか分かりません。挿入のソートを使用して配列にハイスコアを追加すると重複が発生する

目標は、records [i] .getName()を使用して、オブジェクトのレコードの配列に格納されているハイスコアのソート済みリストと 'uScore'(今再生したゲームのスコア、 )その位置でスコアを取得する。次に、「uScore」が挿入される位置を 'insertScoreHere'を使用してマークし、配列の下のすべてを1つ下にシフトします。次に、「insertScoreHere」のスコアの値をuScoreに設定し、名前を「uName」(プレイしたゲームのプレイヤー名)に設定します。これは、「以下の配列である(何が起こっているかで、

public void sortWinners() { 

    for (int i = 0; i < 10; i++) { 
     if (uScore < records[i].getScore()) { 
      insertScoreHere = i; 
      i = 10; //this is terrible i know 
     } 
    } 

    for (int i = 9; i > insertScoreHere; i--) { 
     records[i] = records[i-1]; 
    } 

    records[insertScoreHere].setName(uName); 
    records[insertScoreHere].setScore(uScore); 
} 

は今最も最近のゲームからプレイヤー名は「SAM」であれば、彼のスコアは「8」で、配列はで開始する空であります記録):

NAME: sam, SCORE: 8 

NAME: sam, SCORE: 8 

NAME: , SCORE: 0 

NAME: , SCORE: 0 

NAME: , SCORE: 0 

NAME: , SCORE: 0 

NAME: , SCORE: 0 

NAME: , SCORE: 0 

NAME: , SCORE: 0 

NAME: , SCORE: 0 

私は私のコードにこれを追加し、私はできる限りのすべてを記録しました:

public void sortWinners() { 

    for (int i = 0; i < 10; i++) { 
     if (uScore < records[i].getScore()) { 
      insertScoreHere = i; 
      i = 10; 
     } 
    } 

    Log.v("ARRAY", "PLACE TO INSERT SCORE: " + insertScoreHere); 

    for (int i = 9; i > insertScoreHere; i--) { 

     Log.v("ARRAY", "BEFORE ITERATION I = " + i + ": " + 
       " | " + records[0].getScore() + 
       " | " + records[1].getScore() + 
       " | " + records[2].getScore() + 
       " | " + records[3].getScore() + 
       " | " + records[4].getScore() + 
       " | " + records[5].getScore() + 
       " | " + records[6].getScore() + 
       " | " + records[7].getScore() + 
       " | " + records[8].getScore() + 
       " | " + records[9].getScore()); 
     records[i] = records[i-1]; 

     Log.v("ARRAY", " AFTER ITERATION I = " + i + ": " + 
         " | " + records[0].getScore() + 
         " | " + records[1].getScore() + 
         " | " + records[2].getScore() + 
         " | " + records[3].getScore() + 
         " | " + records[4].getScore() + 
         " | " + records[5].getScore() + 
         " | " + records[6].getScore() + 
         " | " + records[7].getScore() + 
         " | " + records[8].getScore() + 
         " | " + records[9].getScore()); 
    } 
    records[insertScoreHere].setName(uName); 
    records[insertScoreHere].setScore(uScore); 

    Log.v("ARRAY", "AFTER SORTING"); 
    for (int i = 0; i < 10; i++) { 
     Log.v("ARRAY", "NAME: " + records[i].getName() + ", SCORE: " + records[i].getScore()); 
    } 
} 

はここで伐採した結果の一例です。例えば、我々は(重複がすでに発生している)人口の配列を持っていると言う:

NAME: milfred, SCORE: 1 

NAME: milfred, SCORE: 1 

NAME: timmy, SCORE: 3 

NAME: john, SCORE: 5 

NAME: sam, SCORE: 7 

NAME: dhshs, SCORE: 8 

NAME: , SCORE: 0 

NAME: , SCORE: 0 

NAME: , SCORE: 0 

NAME: , SCORE: 0 

今度は、再生され、次のゲームは「6」のスコアとプレイヤー名「stringray」を持っているとしましょう。

PLACE TO INSERT SCORE: 4 

BEFORE ITERATION I = 9: | 1 | 1 | 3 | 5 | 7 | 8 | 0 | 0 | 0 | 0 

AFTER ITERATION I = 9: | 1 | 1 | 3 | 5 | 7 | 8 | 0 | 0 | 0 | 0 

BEFORE ITERATION I = 8: | 1 | 1 | 3 | 5 | 7 | 8 | 0 | 0 | 0 | 0 

AFTER ITERATION I = 8: | 1 | 1 | 3 | 5 | 7 | 8 | 0 | 0 | 0 | 0 

BEFORE ITERATION I = 7: | 1 | 1 | 3 | 5 | 7 | 8 | 0 | 0 | 0 | 0 

AFTER ITERATION I = 7: | 1 | 1 | 3 | 5 | 7 | 8 | 0 | 0 | 0 | 0 

BEFORE ITERATION I = 6: | 1 | 1 | 3 | 5 | 7 | 8 | 0 | 0 | 0 | 0 

AFTER ITERATION I = 6: | 1 | 1 | 3 | 5 | 7 | 8 | 8 | 0 | 0 | 0 

BEFORE ITERATION I = 5: | 1 | 1 | 3 | 5 | 7 | 8 | 8 | 0 | 0 | 0 

AFTER ITERATION I = 5: | 1 | 1 | 3 | 5 | 7 | 7 | 8 | 0 | 0 | 0 



AFTER SORTING 

NAME: milfred, SCORE: 1 

NAME: milfred, SCORE: 1 

NAME: timmy, SCORE: 3 

NAME: john, SCORE: 5 

NAME: stingray, SCORE: 6 

NAME: stingray, SCORE: 6 

NAME: dhshs, SCORE: 8 

NAME: , SCORE: 0 

NAME: , SCORE: 0 

NAME: , SCORE: 0 

そして最後に、ここに私のデータ型で:これは何を私のログ戻っある

String uName; 
int uScore; 
playerRecord records[] = new playerRecord[10]; 

playerRecord:

public class playerRecord { 
    private String name; 
    private int score; 

    public playerRecord(String input_name, int input_score) { 
     name = input_name; 
     score = input_score; 
    } 

    public String getName() { 
     return name; 
    } 

    public int getScore() { 
     return score; 
    } 

    public void setName(String set_name) { 
     name = set_name; 
    } 

    public void setScore(int set_score) { 
     score = set_score; 
    } 
} 

移入playerRecord:

for (int i = 0; i < 10; i++) { 
      records[i] = new playerRecord("", (0)); 
     } 

私は私はillustraできるようになったことを願って問題を適切にしてください。その他の詳細が必要な場合は、私に知らせてください。あなたは

records[insertScoreHere].setName(uName); 
records[insertScoreHere].setScore(uScore); 

あなたの新しいスコアを挿入したいとき

+2

[ 'Arrays.toString() '](https://docs.oracle.com/javase/7/docs/api/java/util/Arrays.html#toString(int []))はあなたの友人です。また、//これはひどいです私はあなたが探しているキーワードが['break']だと思います(https://docs.oracle.com/javase/tutorial/java/nutsandbolts/branch.html) –

+0

ああ、ヒントのために喝采。ありがとう。 – sam

答えて

0

あなたが抱えている問題を確認したい場合があります。 10点の配列は、実際にはplayerRecordオブジェクトへのポインタの配列です。私はそれがそれのように見えないことを知っていますが、これはあなたがオブジェクトの配列を持っているときに舞台裏で起こっていることです。

並べ替え操作を実行した後の、配列内の2つの重複要素は、実際には同じメモリをアドレス指定しています。

i = 4としましょう。そしてinsertScoreHere = 3

records[i] = records[i-1]; 

# records[4] = records[3]; 
# BUT what actually happens here is records[4] is now pointing to the 
# same piece of memory as records[3]. So then: 
# records[4] => memory_address_x 
# records[3] => memory_address_x 

records[insertScoreHere].setName(uName); 
records[insertScoreHere].setScore(uScore); 

#so now this code: records[3].setName(uName); is actually modifying 
#the same piece of memory as records[4]. 

溶液#1:

スワップあなたの周りに並べ替えを行うとポインタ。とにかくそれを拭くので、私はオブジェクトをi == 9で使うつもりです。

public void sortWinners() { 
    for (int i = 0; i < 10; i++) { 
     if (uScore < records[i].getScore()) { 
      insertScoreHere = i; 
      i = 10; //this is terrible i know 
     } 
    } 

    # EDIT 1: lets save this record for reuse 
    playerRecord temp = records[9]; 
    for (int i = 9; i > insertScoreHere; i--) { 
     records[i] = records[i-1]; 
    } 

    # EDIT 2: change the record to point to a separate record 
    records[insertScoreHere] = temp; 
    #^this index now points to a separate record from records[i] 
    records[insertScoreHere].setName(uName); 
    records[insertScoreHere].setScore(uScore); 
} 

溶液#2:

メモリポインタをいじって回避するための別の方法は、別のレコードからデータをコピーするようになります。

public void sortWinners() { 
    for (int i = 0; i < 10; i++) { 
     if (uScore < records[i].getScore()) { 
      insertScoreHere = i; 
      i = 10; //this is terrible i know 
     } 
    } 

    for (int i = 9; i > insertScoreHere; i--) { 
     records[i].setName(records[i-1].getName()); # EDIT 1 ** 
     records[i].setScore(records[i-1].getScore());# EDIT 2 ** 
    } 

    records[insertScoreHere].setName(uName); 
    records[insertScoreHere].setScore(uScore); 
} 
+0

私はそれを更新し、コード付きの2番目のソリューションを追加しました。第2の解決策は、コード「records [i] = records [i-1];」によって引き起こされる重複メモリポインタの割り当てを回避する。 – Bastion

+0

これは大変感謝しており、本当に分かりやすいです。私は第二の解決策に行きました! – sam

0

問題は、これらの線とについて何が来るのか、これは実際にやっていると、そのインデックスにあるplayerRecordの名前とスコアを置き換えています。どちらも、あなたが今、あなたにこれを表示するには、次のインデックス(insertScoreHere + 1)

にシャッフルされている同じオブジェクトを持っているあなたがする必要があるすべては、印刷は、あなたの配列のプレーヤーレコードのアドレスです:

[email protected], [email protected], [email protected], [email protected], ... 

これです私はかつてあなたsortWinnersメソッドを呼び出した後に - あなたは配列の最初の2つの要素は、あなたがちょうどこの

01呼び出すことによって、そのインデックスの新しいスコアを挿入する必要があり、この問題を解決するには、同じオブジェクト [email protected]

を参照することがわかります

records[insertScoreHere] = new PlayerRecord(uName, uScore) 

はまた、メモリポインタとnaming conventions for Java

関連する問題