質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

88.91%

初心者:文字の入れ替え方法。認識の確認

受付中

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 416

tapipi

score 13

前提・実現したいこと

main関数で最初のswitch文に入り、
case1の時に入れ替えを行うことは理解できたのですが、
最初のcase1の中で
後ろのほうから比較していかないといけないのはなぜでしょうか?
例えば
70 50 100 20 とあった時、入れ替えを以下のコードだけで行うと
「50 70 20 100」となるのは理解できます。

(省略)
int num1 = data.compare(i - 1, i);
           switch (num1) {
               case 1:
                   //入れ替える
                   data.exchange(i - 1, i);
               default:
                   break;
           }
(省略)


そのため後ろのほうから
100 と 20 を 比較→ 20 100
20 と 70 を 比較→ 20 70
20 と 50 を 比較→ 20 50
となって「20 50 70 100」としなければならない理由もわかります。
ですが、case1のなかでしなければならない理由はなんでしょうか?
以下のコードでもよさそうと思ってしまうのですが…

for (int i = 1; i < 100; i++) {
           int num1 = data.compare(i - 1, i);
           switch (num1) {
               case 1:
                   //入れ替える
                   data.exchange(i - 1, i);                           
               default:
                   break;
           }
           for (int n = i; n > 0; n--) {
               int num2 = data.compare(n - 1, n);
               switch (num2) {
                   case 1:
                     data.exchange(n - 1, n);
                   default:
                     break;
               }
           }
       }


49,50あたりから何か必要そうになるのは分かるのですが
これが1000とかになるとどうしても考えられなくなります。
みなさんはどのように考えておりますか?

該当のソースコード

public class Change {
   public static void main(String[] args) {
       ListManager data = new ListManager();
       for (int i = 1; i < 100; i++) {
           /*
           signumに渡した数値によって以下の値が返ります。
           引数がゼロより大きい場合 ⇒1
           引数がゼロの場合 ⇒0
           引数がゼロより小さい場合 ⇒-1
            */
           int num1 = data.compare(i - 1, i);
           switch (num1) {
               case 1:
                   //入れ替える
                   data.exchange(i - 1, i);
                   //後ろから入れ替えていく
                   for (int n = i; n > 0; n--) {
                       int num2 = data.compare(n - 1, n);
                       switch (num2) {
                           case 1:
                               data.exchange(n - 1, n);
                           default:
                               break;
                       }
                   }
               default:
                   break;
           }
       }
       data.checkResult();
   }
}
public class ListManager {
   private int[] dataList;
   private int compareCount;
   private int exchangeCount;
   public ListManager() {
       // データをランダムに作成する
       Random random = new Random();
       dataList = new int[100];
       for (int i = 0; i < dataList.length; i++) {
           dataList[i] = random.nextInt(10000);
       }
   }
   /**
    * 2つのデータを比較
    *
    * @param index1
    * @param index2
    * @return -1:index1のデータが小さい, 1:index2のデータが小さい, 0:同じデータ
    */
   public int compare(int index1, int index2) {
       compareCount++;
       return (int) Math.signum(dataList[index1] - dataList[index2]);
   }
   /**
    * 2つのデータを入れ替え
    *
    * @param index1
    * @param index2
    */
   public void exchange(int index1, int index2) {
       exchangeCount++;
       int tmp = dataList[index1];
       dataList[index1] = dataList[index2];
       dataList[index2] = tmp;
   }
   /**
    * ソートチェック
    */
   public void checkResult() {
       int data = dataList[0];
       for (int i = 1; i < dataList.length; i++) {
           if (data > dataList[i]) {
               throw new RuntimeException("ソートされていない: [" + (i - 1) + "]=" + data + ", [" + i + "]=" + dataList[i]);
           }
           data = dataList[i];
       }
       System.out.println("ソートOK: 比較=" + compareCount + ", 入れ替え=" + exchangeCount);
   }
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • m.ts10806

    2020/07/02 20:09

    >初心者:

    「初心者アイコン」を質問につけられるのでわざわざ書く必要はありません

    キャンセル

  • 退会済みユーザー

    2020/07/30 12:17

    複数のユーザーから「意図的に内容が抹消された質問」という意見がありました
    解決後に編集機能を用いて質問内容を改変し関係のない内容にしたり、内容を削除する行為は禁止しています。
    投稿していただいた質問は、後に他の誰かが困ったときに助けになる情報資産になると考えるからです。
    「質問を編集する」ボタンから編集を行い、他のユーザにも質問内容が見えるように修正してください。

回答 1

+1

1回目のswitchで入れ替えが起こらなかった場合、その時点で見ているインデックス以前は正しく昇順に並んでいることが確定します。つまり、改めて調べる必要がありません。
あなたのコードの場合、1回目のswitchで入れ替えが起ころうが起こらなかろうが、そのインデックス以前の並びをチェックしているため、無駄です。以前の並びをチェックするのは、入れ替えが起こったときだけで十分です。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 88.91%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る