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

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

ただいまの
回答率

88.93%

配列リストで逆順挿入のプログラム作成。

受付中

回答 6

投稿

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

engin

score 2

ja[長文失礼致します]Java入門者の者です。学校の担当講師から、「整数を要素とする配列リスト L に、キーインした複数の整数値を順に格納する。
このあと、L のすべての要素を逆順に表示し、直後にLのすべての要素を正順に
表示するプログラムを作れ。
例えば、10,15,20,..,45,50 とキーインしたとき、入力完了後に
50,45,..,20,15,10,10,15,20,..,45,50
と表示されるはずである。」

という問題が課され、全然分からずに非常に困って居ます。
一応習ったばかりのinsertメソッド?と呼ばれるメソッドで以下の様なプログラムを書いたのですが、全く実行されませんでした。

package saishuukadai01;
import java.util.Scanner;
class list {//配列リスト
static final int MAX =100;
int N ;
int[]value = {10,15,20,25,30};
list(){N=0;value=new int[MAX];
}
int  insert(int k,int val) {//insertメソッド。学校の資料に掲載されてる内容をそのままコピペしただけです。
int k1;
for(k1=N-1;k1>=k;k1--) {
value[k1+1]=value[k1];
}
value[k]=val;
return -1;}
}
public class saishuukadai01 {//アプリ

public static void main(String[] args) {
Scanner stdin =new Scanner (System.in);
list S = new list();
int val;
for(val=0;val<100
;val++) {
S.insert(0,val);
}
System.out.println(S);
}
}

各行ごとに自分なりの解釈を踏まえて説明すると、、、

1 パッケージ
2 キーボード入力
3 配列リストclassの作成
4 整数intの上限がMAX=100である事を表示
5 整数の配列 valueを作る
6 コンストラクタ?(ここもよく分からないのですが、配列リストclassにリストを作成という事でしょうか。)
9〜16 インサートメソッド。後のアプリでインサートを使用する為に予めその内部構造を記した、所謂、「関数」という解釈であってますでしょうか?
17 アプリのクラス
19いつもの定型コード。mainメソッド。
20キーボード入力?これも何を言ってるかよく分からないです。が、いつもの文章…
21配列リストSをnew list()として新しく作成
22 型名 整数変数 (変数valを宣言)
★23 valが0から100未満の間、配列リストSの0番目の前にvalを次々に挿入。つまり、10.15.20.25.30という配列があるとすれば、10から順に0番目の前に挿入されて行くので、30.25.20.15.10と逆順挿入される筈。

26 23で行われた後の配列リストSを表示する。

となり、実行されない原因は、やはり23行目のfor文が間違っているのと、上の配列リストclassと下のアプリが全く連動・連結されてない事だと思っています。

どの様なfor文を作れば、配列リストクラスで作った配列を操作する事が出来るのでしょうか?
また、配列リストclassとアプリが連動・連結されてない原因は何故でしょうか?…
どの様にすれば解決出来るのでしょうか?
また、不明な点が有ればご指摘・訂正して頂ける非常に幸いです。
以上の事について、どなたか分かる方教えて下さい。
何卒よろしくお願い致しますm(_ _)m

  • 気になる質問をクリップする

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

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

  • m.ts10806

    2020/07/24 05:12

    それに、その講師から「自分でなんとかしろ。人に教えて貰う事ではない」と言われたのでしたら、この場で質問する行為は指示に背いていることになりませんか?
    案外、こういうサイトは見られているものですよ。

    キャンセル

  • Zuishin

    2020/07/24 06:32

    これを人に聞かず自分でできなければ首と言われたんですよね?

    ということは、最終的にその単位を取るにはこれが自力で解けるだけの力が最低限必要ということですよ。力がないなら次の試験で赤点採って終わりです。

    どうせ貰えない単位のために時間を割くのはもったいなくないですか? それともテストもカンニングしますか?

    キャンセル

  • m.ts10806

    2020/07/24 08:52

    >信じられないと思いますが…

    この質問をしている時点で、信じられます。講義でなにを受けてきたのか知らないですが、安くないお金払って何をしにいってますか?
    厚意のみで成り立つ無料の質問サイトに泣きつく時点で人生舐めすぎです。

    キャンセル

回答 6

+3

ここで質問されるべきは、周りに聞ける人(個人開発やその技術を持った人)がいない方達が質問をするべき場であり、講習の課題を聞くべき場所ではありません。

というより、周りに聞ける方がいらっしゃるのでしたら、その方に聞く方が上達します。

ただ、講師に聞かずに解いたと驚かせたいなどの個人感情があっての質問だと思うので、少し勉強も兼ねて教示します。

一応習ったばかりのinsertメソッド?と呼ばれるメソッドで以下の様なプログラムを書いたのですが、全く実行されませんでした。

まず先に述べたいのは、ここで言うinsertメソッドというのは自分で作成したメソッドなので、別に名前がinsertでなくてもなんでもいいのです。メソッドについての理解がまだ足りていないように思えます。

全てを説明してもキリがないのですが、
質問者の解釈を//コメント、私の解説を/**/コメントで記述します。

// パッケージ
/* このクラスのパッケージを宣言しています。 */
package saishuukadai01;

// キーボード入力
/* キーボード入力というより、「import」という記述をすることで「java.util.Scanner」という入力を操作できるクラスを使用することができるようにしてます。 */
import java.util.Scanner;

// 配列リストclassの作成
/* 「list」という名前のクラスを宣言しています。 */
class list {

    // 整数intの上限がMAX=100である事を表示
    /* MAXという上限の判定に使用する定数を宣言と同時に100を代入しています。 */
    static final int MAX =100;
    int N ;

    // 整数の配列 valueを作る
    /* 合ってます。 */
    int[]value = {10,15,20,25,30};

    // コンストラクタ?(ここもよく分からないのですが、配列リストclassにリストを作成という事でしょうか。)
    /* コンストラクタというのは、クラスのインスタンスを生成する際に実行される処理です。ここではNに0を代入して、valueを初期化(空に)しています */
    list(){
        N=0;
        value=new int[MAX];
    }

    // インサートメソッド。後のアプリでインサートを使用する為に予めその内部構造を記した、所謂、「関数」という解釈であってますでしょうか?
    /* 大体合ってます。関数のような認識です。listというクラスが持ったinsertというメソッドはこういう処理を行う関数ですよと記述してあるのです。 */
    int insert(int k,int val) {
        int k1;
        for(k1=N-1;k1>=k;k1--) {
            value[k1+1]=value[k1];
        }
        value[k]=val;
        return -1;
    }
}

// アプリのクラス
/* 「saishuukadai01」という名前のクラスを宣言しています。 */
public class saishuukadai01 {

    // いつもの定型コード。mainメソッド。
    /* 危うい覚え方です。後々ちゃんと勉強しましょう。 */
    public static void main(String[] args) {

        // キーボード入力?これも何を言ってるかよく分からないです。が、いつもの文章…
        /* 2行目のimportでjava.util.Scannerが使用できるように宣言していたと思うのですが、そのjava.util.Scannerクラスのインスタンスを生成しています。 */
        Scanner stdin = new Scanner(System.in);

        // 配列リストSをnew list()として新しく作成
        /* これも上と同じで、自分で作成したlistというクラスのインスタンスを生成しています。importが必要ない理由としては、saishuukadai01とlistは同じパッケージの中に入っているからです。やっていることは1つ上と同じです。 */
        list S = new list();

        // 型名 整数変数 (変数valを宣言)
        /* 合ってます。 */
        int val;

        // valが0から100未満の間、配列リストSの0番目の前にvalを次々に挿入。つまり、10.15.20.25.30という配列があるとすれば、10から順に0番目の前に挿入されて行くので、30.25.20.15.10と逆順挿入される筈。
        /* 今回の問題箇所なので、割愛します。 */
        for(val = 0; val < 100; val++) {
            S.insert(0,val);
        }
        System.out.println(S);
    }
}

上を見ていただけるとわかる(と思う)のですが、Scannerクラスを全く使用していません。
教材に載っているソースを自分なりに修正したのだと思います。
不要なScanner関連を削除して、私のコメントのみ記載します。

// パッケージ宣言
package saishuukadai01;

// 「list」という名前のクラスを宣言
class list {

    /* 変数・定数宣言 */
    static final int MAX =100; // 上限値(100)
    int N ;
    int[]value = {10,15,20,25,30}; // 操作に使用するベースの配列

    /* listクラスがインスタンス化された時に実行される処理 */
    list(){
        N = 0; // Nに0を代入
        value=new int[MAX]; // valueを初期化(空に)
    }

    /* insertメソッド */
    int insert(int k,int val) {

        // for文用変数
        int k1;
        // ループ内容
        // 初期値が「N-1」で「k1がk以上の間」というのを条件にk1を-1ずつしながらループ
        for(k1 = N-1; k1 >= k; k1--) {
            value[k1+1]=value[k1];
        }
        value[k]=val;
        return -1;
    }
}

/* 「saishuukadai01」という名前のクラスを宣言 */
public class saishuukadai01 {

    /* mainメソッド */
    public static void main(String[] args) {

        // listクラスのインスタンス生成
        list S = new list();

        // for文用変数
        int val;

        // ループ内容
        // 初期値が「0」で「valが100未満の間」というのを条件にvalを+1ずつしながらループ
        for(val = 0; val < 100; val++) {
            S.insert(0,val);
        }
        System.out.println(S);
    }
}

少し問題が見えてきませんか?
ヒントはここまでです。後は自力で頑張ってください。

まとめとして思ったこととしては、今のままでは到底理解していると言えません。
ここで質問してくるということはプログラミングへの意欲はあると思うので、その時の課題をただこなすのではなく、内容を隅から隅まで理解して欲しいです。

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2020/07/23 17:16

    すばらしい。

    キャンセル

  • 2020/07/24 02:40 編集

    LOVE -KANON様
    非常に詳しく的確で丁寧なご回答・解説、誠にありがとうございます。

    1行ずつ全てのプログラムの内容を解説してくださったお陰で非常に理解が深まり、また自身の書いたプログラムの欠陥を見つける事が出来た他、改めて勉強不足である現状を把握する事が出来ました。

    本題についてですが、momon-ga様がご指摘下さった通り、System.out.println(java.util.Arrays.toString(S.value));
    に変更した所、[99,0,0,0,…0]と配列の要素らしきコードを抽出させる事が出来ました。
    この出力結果により、やはりclass saishuu kadai01{ のfor文の中身が異常である事が発覚しました。
    課題の本来の目的は、整数配列value内に格納されている{10,15,20,25,30}の要素を逆順に表示させる事であり、それを実行する為に為に関数「insertメソッド」を導入しました。
    しかし、結果的には配列リスト、insertメソッドの役割を全く果たさず、ただsaishuukadai01 クラス内のfor文を適用させているだけという現状であります。
    何故でしょうか…
    このメソッドとアプリ(class saishuu kadai01)を連動させる根本的な所がレベルの低い私の頭脳では理解出来ないので、どうかアドバイス頂けないでしょうか?…
    良ければ、お願い致します。
    また、メソッドの概念については講義内外でほぼ触れて来なかったのですが、やはりそのメソッドの理解の不十分が最大の欠陥である事が分かったので、早急に学習し直しております。

    キャンセル

  • 2020/07/24 02:55

    承知いたしました。
    コメントありがとうございます。

    今から追記しますので、またお時間ある時に確認しておいてください。

    キャンセル

  • 2020/07/24 03:36

    今気づきましたが、「キーイン」というのはjava.util.Scannerを使用したキーボード入力値ということですね。

    質問者様はそれ以前の問題なので、今私が定時している課題がクリア出来たらやっていきましょうか。

    キャンセル

+2

まず、「配列リスト」とは何かです。Javaで「配列」と言えば配列型(int[]等)を意味します。逆に「リスト」と言えばjava.util.Listインターフェース型(List<int>等)を意味します。しかし、課題文は「配列リスト」です。一体何を使えば良いのかわかりません。

そこで、「教授は英語の課題文を直訳してしまったのかもしれない」と推測します。配列はarray、リストはlist、つまり、array listと言うことになります。ここから、java.util.ArrayListの事ではないかと推測できます。ArrayListをそのまま分解して訳せば配列リストです。これに間違いありません。

次に「整数」について考えます。Javaには複数の整数の型があります。よく使われるのはintですが、longが必要な場合もあります。しかし、intlongは使用できる範囲があるため、その範囲内に収まるかどうかを十分検討の上で使う必要があります。今回の課題において、整数がどれぐらいの大きさまで想定するのかが明記されていません。1垓(100,000,000,000,000,000,000)とかもあり得ると言うことです。おっとlongの範囲を超えてしまいました。これ以上大きいプリミティブ型の整数はありません。でも、安心してください。Javaにはメモリが許す限り際限が無い整数のクラスが用意されています。そうjava.math.BigIntegerです。これを使えば、多いときも安心です。

あとは逆順と正順での表示になるのですが、java.util.Collections#reverse(List<?> list)を使うとリストそのものが逆順になってしまいます。後から正順に直すというのも二度でまですし、逆順の状態があるのもよろしくないです。そこで、ループ一回で文字列を作ることにしました。"数,前の文字列,数"とすればうまく行くはずです。しかし、この方法では、中央が",,"とカンマ二個連続になってしますので、最後にこのカンマを消します。前後に追加していく文字列は同じなので、文字列の長さから消すべきカンマの位置がわかります。

最終的にはこうなりました。

/**
 * https://teratail.com/questions/279642
 *
 * > 整数を要素とする配列リスト L に、キーインした複数の整数値を順に格納する。
 * > このあと、L のすべての要素を逆順に表示し、直後にLのすべての要素を正順に
 * > 表示するプログラムを作れ。
 * > 例えば、10,15,20,..,45,50 とキーインしたとき、入力完了後に
 * > 50,45,..,20,15,10,10,15,20,..,45,50
 * > と表示されるはずである。
 */
import java.util.Scanner;
import java.util.ArrayList;
import java.math.BigInteger;

public class Q279642 {
    public static void main(String[] args) {
        var scanner = new Scanner(System.in);
        scanner.useDelimiter("\\r?\\n|,");
        var list = new ArrayList<BigInteger>();
        while (scanner.hasNextBigInteger()) list.add(scanner.nextBigInteger());
        if (list.size() == 0) return;

        var str = list.stream().map(i -> i.toString())
            .reduce("", (r, s) -> s + "," + r + "," + s);
        var builder = new StringBuilder(str);
        builder.deleteCharAt(str.length() / 2);
        System.out.println(builder);
    }
}

なお、入力を簡素化しています。入力終わりは改行二回や","や数値以外を入れてください。


課題文のみから回答しています。質問者が今まで授業で何を習ってきたのか、また、どのような教科書や参考書を使っているのかを私は一切知りません。そのため、質問者が習っていないクラスや構文を使用している可能性があります。予めご了承ください。また、コードはLibericaJDK 14.0.2で動作確認しています。Oracle Javaでの動作は保証しません。

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2020/07/24 10:54

    raccy様、ご回答ありがとうございます。
    まず配列リストへの認識が不十分でした。
    せっかく書いて頂いたプログラムですが、自身の不勉強故に見慣れない羅列が多く、プログラムを正確に理解する事が出来ませんでした…
    しかし、この問題を解決する為の材料を提供して頂き、誠に有難く思います。
    書かれた内容を踏まえて、もっと深く学習し直す様努めます。

    キャンセル

+1

一応習ったばかりのinsertメソッド?と呼ばれるメソッドで以下の様なプログラムを書いたのですが、全く実行されませんでした。

”実行は”されているはずです。
私の環境では、いかの出力がされました

list@51016012

期待通りではないと思いますが、実行はされています。
で、まずは配列の表示方法についてです。
たぶん、toStringを実装する課題があると思いますが、いったんここは置いておいて
※課題として、それがないと配列の表示が常にMAX個になる

System.out.println(S);

System.out.println(java.util.Arrays.toString(S.value));

にしてみると、Sの内部配列を表示できます。

insertメソッド。学校の資料に掲載されてる内容をそのままコピペしただけです。

と、ありますが内容が間違っているか、そもそも資料に誤りがあるかだと思います。
※もしかしたらinsertを直すっていう課題が直前にあったりします?


どこから指摘すればいいのか・・・と、思ったが
LOVE-KANONさんが、丁寧に解説?している。
まずは、自分が理解していないソースは使えないので、教本読みながら1つづつ理解していくしかないかなぁ。

コンストラクタの意味
listのコンストラタでやってること
insertメソッドで、やろうとしていること
insertメソッドで、やっていること(不具合があると私は思っている)
listの要素の表示方法(たぶん、toStringの実装)

このあたりを理解してからでないと、saishuukadai01は作れないと思います。

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2020/07/24 03:12 編集

    > for文を書かない場合、0が100個表示されると思いますが、それは想定通りですか?

    全く想定しておりませんでした。実際for文無しで出力した所、仰る通り[0,…0]と0が100個挿入されました。
    何故そうなったかも分かりません…


    >直接数字をinsertする場合
    S.insert(0,1);
    S.insert(1,2);
    S.insert(2,3);
    S.insert(0,4);
    この場合に表示される内容は、期待通りですか?
    いえ、全く想定出来ませんでした。
    勉強不足ですみません…
    上記の内容で出力した結果、益々謎が深まりました…

    int insert(int k,int val){(インサートメソッド)に関して、講義資料には「位置kの直前にvalを挿入」と書かれております。
    私はこのメソッドを活用して、value内に格納されている配列の要素 {10,15,20,25,30};を逆順に呼び起こしたいのですが、一体どうすれば良いのでしょうか…
    まず無駄なfor文を消し、S.insert(0.val)の前に、変数valを上に作成した配列リストに結びつける為の何かを挿入するのでは無いかと方針を立てているのですが、この要領であってますでしょうか?…
    良ければ何かアドバイス頂けると幸いです。

    キャンセル

  • 2020/07/24 06:31

    アドバイスとしては、大きく3つ

    1.今あるコードはいったん破棄して自分の理解できるコードを書いた方が良い。
    LOVE-KANON さんがチカラのいれた回答してるので、そちらを元に書き直してみた方がよいかと思います。

    2.そもそも、日本語(自然言語)で、プログラムの流れをいったん整理した方がよいです。
    よくわからないが頻出するコードの動作は、正しく動かないんじゃないでしょうか。
    コンストラクタで、何をやってるか理解すれば
    > value内に格納されている配列の要素 {10,15,20,25,30};を逆順に呼び起こしたいのですが、一体どうすれば良いのでしょうか…
    という疑問自体でてこないです。

    3.insertメソッドをまずは正しく動作させるように直しましょう。
    ---
    > まず無駄なfor文を消し、S.insert(0.val)の前に、変数valを上に作成した配列リストに結びつける為の何かを挿入するのでは無いかと方針を立てているのですが、この要領であってますでしょうか?

    結びつけるという表現が、いまいちピンとこないのですが・・・
    配列リスト(list)に対して、「整数値を順に格納」するのであれば、insertメソッドを修正するか
    for文の中身の
    > S.insert(0,val)

    S.insert(val,val)
    にすると、格納はできます。
    とうぜん、 {10,15,20,25,30} には、なりませんが。

    キャンセル

  • 2020/07/24 10:38

    アドバイスありがとうございます。
    やはり、私はここで皆様に教えて頂く土俵には達しない程自身のプログラムの理解が欠落している事が分かりました。
    momon-ga様やLOVE-KANON様の仰る内容がもっと理解出来るよう努めます。

    キャンセル

+1

問題解決のためのヒントです。

import java.util.Scanner;

class Test1 {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        String line = sc.nextLine();  // 10,20,30,40 という 1行を入力
        System.out.println(line);
    }
}

class Test2 {
    public static void main(String[] args) {
        String str = "10,20,30,40,50";
        String[] word = str.split(",");
        for (int i = 0; i < word.length; i++)
            System.out.println(word[i]);
    }
}

class Test3 {
    public static void main(String[] args) {
        String str = "123";
        int num = Integer.parseInt(str);
        System.out.println(str + 45);
        System.out.println(num + 45);
    }
}


これらのコードは全部理解できますか?

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

0

コメント読ませていただきました。
長くなりそうなので、回答とは別のこちらで回答致します。

まず、Javaで最初に呼び出されるmainメソッドを実装します。
実際プログラムとしては、このmainメソッド内に全てを記述しても実行できるので、まずはこの中に色々記述していきます。

/* 最初に実行されるmainメソッドを実装したクラス */
public class saishuukadai01 {

    /* mainメソッド(最初に呼ばれるメソッド) */
    public static void main(String[] args) {
    }
}

何も処理を行わないプログラムの完成です。
次に課題となっている配列を作りましょう。

/* 最初に実行されるmainメソッドを実装したクラス */
public class saishuukadai01 {

    /* mainメソッド(最初に呼ばれるメソッド) */
    public static void main(String[] args) {
    int value[] = {10, 15, 20, 25, 30}; // 課題の配列
    }
}

整数配列のvalueを宣言しました。今valueには「10, 15, 20, 25, 30」が入っている状態です。
この配列の要素を順番に表示する処理をループを使って記述していきます。

/* 最初に実行されるmainメソッドを実装したクラス */
public class saishuukadai01 {

    /* mainメソッド(最初に呼ばれるメソッド) */
    public static void main(String[] args) {
    int value[] = {10, 15, 20, 25, 30}; // 課題の配列

        // valueの中身をループを使って表示していきます。
        // iの初期値が0で、iがvalue.length(この場合5)未満になる間、iを+1しながらループします。
        // iはループのたびに+1されていくので「0, 1, 2, 3, 4(5未満)」となっていきます。

        for (int i = 0; i < value.length; i++) {
            // 整数配列valueのi番目を表示
            // System.out.println()は、文字列を渡してあげないと出力してくれません。
            // valueは整数配列のため、String.valueOf()を使って文字列に変換してます。
            System.out.println(String.valueOf(value[i]));
        }
    }
}

上記のループ内では、整数配列valueのi番目を表示する処理を記述しています。
処理の内容を全て記載すると、
valueの0番目(10)
valueの1番目(15)
valueの2番目(20)
valueの3番目(25)
valueの4番目(30)

と表示されていきます。

ここまでわかりますでしょうか?

では逆に、「30, 25, 20, 15, 10」と表示するためにはどうしたら良いのでしょうか?
ヒントは、iの順番を逆(4→3→2→1→0となるよう)にしてあげることです。

コメントにて回答ソースを記入いただけたら追記します。


回答をいただいたので追記します。

上記処理で配列を順番に出力することができたので、今度は逆に出力してみます。

/* 最初に実行されるmainメソッドを実装したクラス */
public class saishuukadai01 {

    /* mainメソッド(最初に呼ばれるメソッド) */
    public static void main(String[] args) {
        int value[] = {10, 15, 20, 25, 30}; // 課題の配列

        // valueの中身をループを使って表示していきます。
        // iの初期値が0で、iがvalue.count(この場合5)未満になる間、iを+1しながらループします。
        // iはループのたびに+1されていくので「0, 1, 2, 3, 4(5未満)」となっていきます。

        for (int i = 0; i < value.length; i++) {
            // 整数配列valueのi番目を表示
            // System.out.println()は、文字列を渡してあげないと出力してくれません。
            // valueは整数配列のため、String.valueOf()を使って文字列に変換してます。
            System.out.println(String.valueOf(value[i]));
        }

        // 上記と同じようにvalueの中身をループを使って逆から表示していきます。
        // iの初期値がvalue.length - 1(ここが結構落とし穴です。配列の長さは5ですが配列のインデックス値は0始まりなので-1してあげなければなりません。)
        // で、iが0以上の間、iを-1しながらループします。
        // iはループのたびに-1されていくので「4, 3, 2, 1, 0(0以上)」となっていきます。

        for (int i = value.length - 1; i >= 0; i--) {
            // 整数配列valueのi番目を表示
            System.out.println(String.valueOf(value[i]));
        }

        // これも上と同じで逆から表示していきます。
        // iの初期値を-1しないバージョンです。
        // iの初期値がvalue.length(ここでは5)で、iが0より大きい間、iを-1しながらループします。
        // iはループのたびに-1されていくので「5, 4, 3, 2, 1(0より大きい)」となっていきます。

        for (int i = value.length; i > 0; i--) {
            // 整数配列valueのi-1番目を表示
            // こうしてあげないと、上で説明したような落とし穴に引っ掛かります。
            System.out.println(String.valueOf(value[i - 1]));
        }
    }
}

これで逆順処理ができました。
ただ、saishuukadai01のメインメソッド内が少し大きくなってきたので、ループして出力する処理を別のクラスを作成して移行していきましょう。

/**
 * 新たに作成したlistクラス
 */
class list {

    /**
     * 整数配列を昇順に出力するメソッド
     */
    public void outIntArrayAcs(int[] value) {

        // valueの中身をループを使って表示していきます。
        // iの初期値が0で、iがvalue.count(この場合5)未満になる間、iを+1しながらループします。
        // iはループのたびに+1されていくので「0, 1, 2, 3, 4(5未満)」となっていきます。

        for (int i = 0; i < intArray.value; i++) {
            // 整数配列valueのi番目を表示
            // System.out.println()は、文字列を渡してあげないと出力してくれません。
            // valueは整数配列のため、String.valueOf()を使って文字列に変換してます。
            System.out.println(String.valueOf(value[i]));
        }

    }
}

上記は、「引数でもらった整数配列を昇順インデックスで出力するoutIntArrayAcsというメソッドをもったlistというクラス」です。outIntArrayAcs内の処理自体は全く変更していません。
では今度はこのクラス内に「引数でもらった整数配列を降順インデックスで出力するoutIntArrayDesc」というメソッドを追加してください。

コメントに回答をいただければ、また追記します。


追記します。

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2020/07/24 13:15 編集

    焦ってしまい、また間違えました。
    public void out IntArray Descs(int [] value) {
    for (int i = 4; i >=0 ; i--)
    {
    System.out.print In(String.valueof(value[i])); }}
    この様な感じですか?
    質問攻めですみません。

    キャンセル

  • 2020/07/24 13:15 編集

    回答にすべて記入します。

    キャンセル

  • 2020/07/24 13:21

    検索し、現在アカウント作ってフォローしています。
    お手数掛けて本当に申し訳ありません。

    キャンセル

0

学校の資料

回答者として未熟者ですが、ごく控えめに言って、教材が間違っているのではないかと思います。listのinsert()はNを加算しなくて良いのだろうか。N==MAXのとき困らないだろうか。kの範囲チェックがなされるのは当然だとしても。

int insert(int k, int val) {// insertメソッド。学校の資料に掲載されてる内容をそのままコピペしただけです。
  if (N == MAX) { // <-- この下でArrayIndexOutOfBoundsExceptionが起きるけど?
    throw new RuntimeException();
  }
  for (int k1 = N - 1; k1 >= k; k1--) {
    value[k1 + 1] = value[k1];
  }
  value[k] = val;
  ++N; // <-- Nを加算しなくて良いのだろか?
  return -1;
}

質問のタイトルは逆順挿入なので、insert(0,…)を使えば逆順に格納できますが、問題文は順に格納のようです。順に格納したければ以下のメソッドを書けばよいのではないでしょうか。

void append(int val) { // 正順に格納する
  if (N == MAX) {
    throw new RuntimeException();
  }
  value[N++] = val;
}

Lの表示

正順に格納したのであれば、配列を先頭から読み、出力リストの両端に配列の要素を追加すれば良いでしょう。

/**
 * 正順に格納されたリストの表示
 */
private List<Integer> symmetricFromAsc() {
  return IntStream.of(value).limit(N)
                  .mapToObj(Integer::valueOf)
                  .collect(ArrayList<Integer>::new,(acc,x)->{acc.add(x);acc.add(0,x);},Collection::addAll);  
}

逆順に格納したのであれば、配列を先頭から読み、出力リストの中間に配列の要素を追加すれば良いでしょう。

/**
 * 逆順に格納されたリストの表示
 */
private List<Integer> symmetricFromDesc() {
  return IntStream.of(value).limit(N)
                  .mapToObj(Integer::valueOf)
                  .collect(ArrayList<Integer>::new,(acc,x)->{acc.add(acc.size()/2,x);acc.add(acc.size()/2,x);},Collection::addAll);  
}

配列の添字を動かす

ArrayListを使わず配列だけを使用するなら、連続した整数を与えて、添字をN-1〜0、0〜N-1へと動かせば良いことに気づいたので、メソッドを作成。sizeが配列のサイズ、iが連続した整数です。

static int genIndex(int size, int i) {
  return i%(2*size) - ((i/size)%2) * (2*(i%size)+1);
}

以下のように添字が動きます。Nは配列のサイズ。

  • 0 <= i < 2*N
    0, 1, … N-1, N-1, … 1, 0
  • N <= i < 3*N
    N-1, … 1, 0, 0, 1, … N-1

テストケース。

  @Test
  void testGenIndex() {

    BiFunction<Integer,Integer,Integer> genIdx = list::genIndex;
    Function<Integer,UnaryOperator<Integer>> supplyGen = size -> i -> genIdx.apply(size,i);
    int size = 5;
    UnaryOperator<Integer> gen = supplyGen.apply(size);

    String result = IntStream.range(0,6*size).map(i -> gen.apply(i)).mapToObj(String::valueOf).collect(Collectors.joining(","));
    assertEquals("0,1,2,3,4,4,3,2,1,0,0,1,2,3,4,4,3,2,1,0,0,1,2,3,4,4,3,2,1,0",result);

    result = IntStream.range(size,7*size).map(i -> gen.apply(i)).mapToObj(String::valueOf).collect(Collectors.joining(","));
    assertEquals("4,3,2,1,0,0,1,2,3,4,4,3,2,1,0,0,1,2,3,4,4,3,2,1,0,0,1,2,3,4",result);
  }

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2020/07/24 14:04

    教材の間違いは多いです。ひどいのは、実績があると言われている教材で練習問題の回答が1割も間違っていたり。まともに査読されていない。
    人を信じちゃいけません。自分自身を拠り所として誠実に生きるのです。

    キャンセル

  • 2020/07/24 14:33

    私は、insertを直す課題が事前にあったのではと考えてます。
    > for (int k1 = N - 1;
    ここ見て、Nに変更かけないとループの挙動が、ずっと変わらないは気付いて欲しいところですよね。。。

    apendは、
    L.insert(L.N,val)
    で、対応できるので、なくてもいいかもしれないですね。(Nがきちんと更新されれば)

    キャンセル

  • 2020/07/24 15:49

    思い至りませんでした。オブジェクト指向の課題ならNはカプセル化して、L.Nは使えない、と思ってappend()を提案しました。しかし、教材の構成や質問者の理解度もわからないので勝手な意見です。

    キャンセル

  • 2020/07/24 19:34

    > Nに変更かけないとループの挙動が、ずっと変わらないは気付いて欲しいところですよね。。
    Scannerより逆順表示より先に、これ片付けないとどうにもならない。

    キャンセル

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

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

関連した質問

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