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

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

新規登録して質問してみよう
ただいま回答率
85.35%
Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Q&A

解決済

4回答

856閲覧

【Java】文字列を"abc"を"cba"に変換するプログラムを作りたい

t.z

総合スコア21

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

0グッド

0クリップ

投稿2020/03/10 06:08

Javaで、"abc"と入力したら"cba"、"asdfghjkl"なら"lkjhgfdsa"と変換するプログラムを作りたいです。右のものから順に文字を記述する感じです。

私の考えで間違っているところを教えていただき、具体的なコードの例を挙げていただきたいです。
よろしくお願いします。

#考えたパターン

ケース1
文字列を"abc"だとする。"abc"という文字列を固定するとして一番最後の文字、最後から2番目の文字、最後から3番目の文字というふうに抽出していく方法。つまり、n回目のターンであることを記述し、s.substring(s.length()-(1+n), s.length()-(1+n))で1文字抽出する。これは、n回目のターンであることを組み込むことができなかった。
ケース2
文字列を"abc"だとして、"c"を出力したら"c"を削除し、"ab"にする。"b"を出力したら削除し、"a"にする。"a"を出力したら"a"を削除し空の文字列にする。つまり、s.substring(s.length()-1)で文字を抽出し、文字の最後を削除するコードと、文字列を更新し保存するコードが必要になるが、削除するコードがマニュアルにないことと、"c"を出力したら文字列が"c"になってしまい"ab"が消えてしまうので削除するコードの位置をどうすればいいのかわからなかった。

どの構文を使うか

  • ifは試したがケース1のようにn番目である記述を組み込むことができなかったり、ケース2のように削除するコードを調べても見つけられない&どの位置に削除するコードを組み込めばいいのかわからなかった。↓に挙げるどれよりもifが一番よさそう。

Java

1Scanner scn = new Scanner(System.in); 2String s = scn.next(); 3 4int i = s.length(); 5if(i>0){ 6 s = s.substring(i-1); 7 System.out.print(s); 8 i--; 9}else{ 10 throw new IndexOutOfBoundsException("err"); 11} 12 13//出力は最後の1文字のみ 14//s = s.substring(i-1)は、s = s.substring(s.length()-1)と同様の出力だった
  • forifと同様の問題点。とくにケース1では条件式のところに何回目であるかの記述を書けないと厳しいと思ったので、わからなくなった。例外処理の書き方も不明。

Java

1Scanner scn = new Scanner(System.in); 2String s = scn.next(); 3 4for(int i = s.length(); i > 0; i--){ 5 s = s.substring(i-1); 6 System.out.print(s); 7} 8//出力は最後の1文字のみ 9//s = s.substring(i-1)は、s = s.substring(s.length()-1)と同様の出力だった
  • switch-caseは文字列の文字数がわからずcaseを書きようがなかった。繰り返し処理でcaseの数を増やせるとしても複雑になってしまいそうなのでやめた。caseをすべて実行してくれるという特性(があったきがした)をうまく使うこともできなさそう。
  • try-catchは例外処理を記述しなければならなくとも、繰り返し処理がメインの今回は違うと思った。
  • whileは、forifほど触れたことはないが、それらで処理できないのなら無理な気がした。

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

m.ts10806

2020/03/10 06:19

現在のコードにおける問題点はなにでしょうか。質問ではなく作業依頼になってませんか
t.z

2020/03/10 06:38 編集

出力が最後の一文字のみになってしまうのが示したコードでの問題点です。様々なパターンを試しすぎたので問題点が1つではないので冒頭には書きませんでした。 どこらへんが作業依頼と思われた理由かはわかりませんが、完全に自習でやっているので作業依頼ではないと思います。
m.ts10806

2020/03/10 06:43

>具体的なコードの例を挙げていただきたいです。 「コードください」
t.z

2020/03/10 06:58

ニュアンスでそうではないことを読み取っていただければと思います。
m.ts10806

2020/03/10 07:16

表現の問題ということであれば文章調整してください。 あくまで見るのは赤の他人なので、人となりや細かいニュアンスまで汲み取るのは基本不可能です
guest

回答4

0

java

1String hoge ="abcdefg"; 2String reversed = new StringBuffer(hoge).reverse().toString(); 3System.out.println(reversed); // gfedcba

もしもアルゴリズムを考える訓練であったなら、
入力文字列を前から1文字ずつ見ていって
結果の文字列の先頭に入れてけばいいだけなので

java

1String hoge = "0123456789"; 2String result = ""; 3for(int i=0; i<hoge.length(); i++){ 4 result = hoge.charAt(i) + result; 5} 6System.out.println(result);

他にも最後から見ていって結果の末尾に連結していくとかいろいろあるんじゃないですかね

投稿2020/03/10 06:16

編集2020/03/10 06:39
ozwk

総合スコア13553

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

t.z

2020/03/10 06:59

こんなに簡潔に記述できるのですね。"charAt"は今回は使えないと思っていましたが、こんなふうに使えるのですね。ご回答ありがとうございます!
guest

0

Java

1class Rev { 2 public static void main(String[] args) { 3 String s = "abcdefg"; 4 char[] a = s.toCharArray(); 5 for (int i = s.length(), j = 0; i > 0; ) a[j++] = s.charAt(--i); 6 s = new String(a); 7 System.out.println(s); 8 } 9}

いろいろな回答が寄せられていますが、全部理解できましたか?
・StringBuffer の reverse
・StringBuilder の reverse (StringBuffer との違い分かりますか?)
・String の subString と +=
・String の charAt と +
・String の toCharArray と charAt
どれが気に入りましたか?

追記
同じことをするのに、いくつものやり方があります。
上のコードの s = new String(a); は
s = String.valueOf(a); と書くこともできます。

追記2

"String の toCharArray と charAt"は、Stringをcharに型変換するために出てきたもので、最初のほうが出力前にさらに型変換されたもので、追記のほうがcharのまま出力したのでしょうか。

toCharArray は、String から char配列を作り出してそれを返すメソッド。
charAt(i) は、String の中の i番目の char を返すものメソッド
new String(a) は、コンストラクタにより char配列 a から、Stringオブジェクトを作りだしています。
String.valueOf(a) は、内部で new String(a) を実行してそれを返しているはずです。

for文のところはString型とchar型の両方を同時にあつかっているから複雑になっているのだ予想しますが、"a[j++] = s.charAt(--i)"という部分がなぜその位置にあるのか、なぜ波括弧とその中の実行文がないのか、なぜ()の中の変化式がないのかは、現時点での知識ではわかりません。

文が一つの場合は { } は省略できる、というか、本当は、for文の (;;) のあとには
文が一つしか書けないので、{ } によって複数の文をまとめて一つの文にしていると
いうことです。
この for文は次のように書いても同じです。

Java

1 for (int i = s.length(), j = 0; i > 0; ) { 2 i--; 3 a[j] = s.charAt(i); 4 j++ 5 } 6あるいは 7 for (int i = s.length(), j = 0; i-- > 0; j++) { 8 a[j] = s.charAt(i); 9 } 10さらに 11 for (int i = s.length(), j = 0; --i >= 0; j++) 12 a[j] = s.charAt(i);

投稿2020/03/10 08:05

編集2020/03/11 06:59
kazuma-s

総合スコア8224

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

t.z

2020/03/10 11:49

洗い出し、ご回答、ありがとうございます。 reverseは両方とも自分で書けました。StringBufferとStringBuilderの違いは調べたらStringBuilderのほうが処理が速いといった内容はいくつかでてきました。"String の subString と +="や"String の charAt と +"は、最初にnullや0を宣言するというのが思い浮かばなかったので学びです。 "String の toCharArray と charAt"は、Stringをcharに型変換するために出てきたもので、最初のほうが出力前にさらに型変換されたもので、追記のほうがcharのまま出力したのでしょうか。 for文のところはString型とchar型の両方を同時にあつかっているから複雑になっているのだ予想しますが、"a[j++] = s.charAt(--i)"という部分がなぜその位置にあるのか、なぜ波括弧とその中の実行文がないのか、なぜ()の中の変化式がないのかは、現時点での知識ではわかりません。 気に入ったのは今のところ、簡単に書けて処理の速い(らしい)StringBuilderでしょうか...。
t.z

2020/03/12 05:59

追記ありがとうございます。どちらの件も納得しました。 デクリメントと不等号を同時に使っているコードは初めて見ました。前置と後置で変わってくるのですね。
guest

0

ベストアンサー

ケース1にしてもケース2にしても、少し難しく考え過ぎな気がします。Javaについて初学で、恐らくまだJavaの文法とライブラリの使い方の理解が消化不良かもしれなく、それらに振り回されてしまっているのではないでしょうか。

既に存在するライブラリについて同じような機能を自分でわざわざ作らずに使いこなすのは実務や実際のプログラミングにおいて大変重要なのは確かですが、もしそれが無かった場合に「では、自分でそれを作れるか」と言うのもそれなりに大事です。特に、今回のご質問のような文字列の反転のような簡単な目的であれば、尚更だと思います。

文字列関係のクラスのreverseメソッドを使う例は既に回答をいただいているので、あえてそれを使わないで自力で出力する例です。whileは使っていませんがforwhileに変えることはできるし、try-catchは使うまでも無いでしょう。

Java

1public class t3 { 2 public static void main(String[] args) { 3 4 String src = "abcdefg"; 5 6 String dst1 = ""; 7 char[] dst2 = new char[src.length()]; 8 int dst2_index = 0; 9 for (int i = src.length() - 1; 0 <= i; i--) { 10 // String.substring()で1文字ずつ切り出し、dst1へ足し込んでいく 11 dst1 += src.substring(i, i + 1); 12 13 // 末端から先頭に向けてchar単位でセットしていく。 14 dst2[dst2_index] = src.charAt(i); 15 dst2_index++; 16 } 17 18 System.out.println(dst1); 19 System.out.println(dst2); 20 } 21}

OpenJDK Java8での実行例です。

CMD

1C:>javac t3.java 2 3C:>java t3 4gfedcba 5gfedcba

投稿2020/03/10 06:53

dodox86

総合スコア9256

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

t.z

2020/03/10 07:11

まさに初学で、今年始めたばかりの者です...。プログラミングがどういうものなのか、どこであがけばいいのか、独学ゆえ感覚でつかめていませんでした。とてもありがたいご回答です。 substringを使用するとこんなふうになるのですね。これは、今の私ではいくら考えても答えにたどり着けませんでした。とても参考になりました。ありがとうございます。
dodox86

2020/03/10 07:20 編集

様々な取り組み方があると思いますが、まず自分の頭と筆記具と紙を使って手書きでプログラムをを表現できるか、と言うのが基本だと思います。自分の頭の中で動きをイメージできない限り、絶対に思った通りには動きません。よく言われることですが、まさに「書いた通り」に動きます。プログラミング言語は筆記具と紙に相当する表現手段に過ぎません。〈とはいえ、表現力によっては思った以上の大変なモノになりますが)
t.z

2020/03/10 07:55

ご教示いただきありがとうございます。プログラミング動画を見ていると簡単なコードを書いてそれをふくらませていくような印象で、それを真似ればいいと思っていました。もう少し複雑なコードを書くようになったら紙の上で表現してみようと思います。
dodox86

2020/03/10 08:04 編集

> 簡単なコードを書いてそれをふくらませていくような印象で 自分で何をしているか分かっていて、ふくらんでいくのならそれで良いのではないでしょうか。(分かっていずに、写経に終わっていたら問題です) 紙の上は極端な例で、紙に書いて説明してみて、と言われたら書ければよい、程度の意味ととらえてください。頭の中で設計はできているはずだから、書けないのはおかしいのでは?と言うことです。要はプログラミング言語に依存せずにやることを正確に(良し悪しは置いておいて、例えばフローチャートを書けるとか)イメージできているかの確認です。
t.z

2020/03/10 12:04

そんな感じなのですね。Androidアプリの作り方を見ることが多いので、視覚的に理解していますが、数式などを使うようになったらあぶないかもしれません。画面上で息詰まったり、理解を深めたいときなどに、いろいろ手段を考えて変えてみようと思います。
guest

0

Javaで、"abc"と入力したら"cba"、"asdfghjkl"なら"lkjhgfdsa"と変換するプログラムを作りたいです。

StringBuilder.reverse()というメソッドがありますので(Oracle)、これを使えば自分で書く必要自体がありません。

ライブラリを使いこなすのも、プログラミングで必要なことの1つです。

投稿2020/03/10 06:19

maisumakun

総合スコア146018

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

t.z

2020/03/10 06:59

存在したのですね。考えるより調べる技術を磨きたいと思います。ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問