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

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

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

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

Q&A

解決済

4回答

895閲覧

「はじめに出た文字だけを残し、その後の重複した文字を消す」プログラムをつくりたいです。

License

総合スコア2

Java

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

0グッド

0クリップ

投稿2021/12/18 22:36

前提・実現したいこと

ここに質問の内容を詳しく書いてください。
ご覧いただきありがとうございます。Java初心者です。
Javaで、「文字列の中で、重複した文字を消す。ただし、はじめに出た文字だけは残す。」
というものを解いています。

この問題について、
・「はじめに出た文字だけを残し、その後の重複した文字を消す」という方法は、どうすればできるかアドバイスください。
・return文の指定について、どうすれば解決できるか、お答えいただきたいです。

これを解きたいです。ご回答よろしくお願いいたします。

発生している問題・エラーメッセージ

java: return文が指定されていません

該当のソースコード

Java

1 2import java.util.Scanner; 3public class Main { 4 public String removeDuplicates(String str) { 5 6 String strBefore = "abbc"; 7 //→表示させる必要あり 8 System.out.println(strBefore); 9 10 char ch0 = strBefore.charAt(0); 11 int code0 = ch0; 12 int value0 = code0; 13 System.out.println(code0); 14 //→表示させる必要はないが、過程を知るために表示 15 16 char ch1 = strBefore.charAt(1); 17 int code1 = ch1; 18 int value1 = code1; 19 System.out.println(code1); 20 //→表示させる必要はないが、過程を知るために表示 21 22 char ch2 = strBefore.charAt(2); 23 int code2 = ch2; 24 int value2 = code2; 25 System.out.println(code2); 26 //→表示させる必要はないが、過程を知るために表示 27 28 char ch3 = strBefore.charAt(3); 29 int code3 = ch3; 30 int value3 = code3; 31 System.out.println(code3); 32 //→表示させる必要はないが、過程を知るために表示 33 34 if (code0 == code1) { 35 String strAfter = strBefore.replace("a", ""); 36 System.out.println(strAfter); 37 //→このstrAfterと以下のstrAfterは、条件を満たしたものを表示させる必要あり 38 39 } else if (code1 == code2) { 40 String strAfter = strBefore.replace("b", ""); 41 System.out.println(strAfter); 42 43 } else if (code0 == code2) { 44 String strAfter = strBefore.replace("a", ""); 45 System.out.println(strAfter); 46 47 } else if (code2 == code3) { 48 String strAfter = strBefore.replace("c", ""); 49 System.out.println(strAfter); 50 51 } else if (code1 == code3) { 52 String strAfter = strBefore.replace("b", ""); 53 System.out.println(strAfter); 54 55 } else if (code0 == code3) { 56 String strAfter = strBefore.replace("a", ""); 57 System.out.println(strAfter); 58 59 } 60 } 61 62} 63 64

試したこと

・「はじめに出た文字だけを残し、その後の重複した文字を消す」ということについて、str.replaceを使ってみたのですが、すべて消えてしまうので、そこに困っています。

・if文で59行目に
if (str) {
return;
}
を挿入してみましたが、引き続きエラーとなりました。

補足情報(FW/ツールのバージョンなど)

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

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

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

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

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

jimbe

2021/12/19 03:37

何故 removeDuplicates メソッドは public String removeDuplicates(String str) という定義になっているのでしょうか。 どこかの課題で「このメソッドの中身を書きなさい」ということなのでしょうか。 また、ご提示のコードだけでは実行出来ません。省略された部分がありましたら、ご質問を編集して追加して頂けますでしょうか。
License

2021/12/19 22:49

ご質問、ご指摘いただきありがとうございます。 確認したところ、”public String removeDuplicates(String str)”の、"public"は必要ありませんでした。 また、メソッドの中身を書きなさい、ということであっております。 省略はしておりません。 ご協力いただいて大変申し訳ありませんが、わかりにくい提示方法で大変失礼いたしました。
guest

回答4

0

java: return文が指定されていません

java

1 public String removeDuplicates(String str) { 2 (省略) 3 }

メソッドの宣言が「戻り値として String を返す」となっている以上、どのような場合("例外"を発する場合以外)でも String オブジェクトもしくは null を返すような return 文を実行するようにコードが書かれている必要があります。

ご提示のコードには return 文自体が見当たりませんし、試されたという
if (str) {
return;
}
では if 条件が成立しなかった場合には return を通らず、また成立した場合も return に String オブジェクトも null も指定されていませんので、メソッドの宣言を満たしておりません。(条件式の書き方のほうでもコンパイルエラーでしょうけれど。)

単純には、メソッドの最後に

java

1 public String removeDuplicates(String str) { 2 (省略) 3 return メソッドの戻り値; 4 }

と加えればよいはずです。
メソッドの戻り値として何を指定するかは、このメソッドの目的によって決まっているはずですので、ご自身で書き換えてください。


「はじめに出た文字だけを残し、その後の重複した文字を消す」ということについて、str.replaceを使ってみたのですが、すべて消えてしまう

消えてしまうので、消える前に他に保存することを考えます。つまり「はじめに出た文字を他に保存し、元の文字列からその文字を全部消す」です。

以下のように、[元文字列の先頭1文字を取り出し]て[戻り値用変数に追加]し、[その文字を元文字列から全部消す]のを[元文字列が空になるまで繰り返す]と、終わった時点で戻り値用変数には重複の無い文字が集められているはずです。

java

1 public String removeDuplicates(String strBefore) { 2 String result = ""; //返り値用変数 3 while(!strBefore.isEmpty()) { //空になるまで 4 String c = "" + strBefore.charAt(0); //先頭1文字を(文字列として)取り出す 5 result += c; //追加 6 strBefore = strBefore.replaceAll(c, ""); //該当文字を全部消す 7 } 8 return result; 9 }

投稿2021/12/19 04:56

編集2021/12/19 07:57
jimbe

総合スコア13209

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

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

License

2021/12/19 22:52

returnに関して、そして、replaceの代替方法についてのアドバイスをありがとうございます。 returnに関しては、おかげさまで解決できました!理解できました。 replaceに関しては、まだ理解が追いついていません。未熟であることを恥じるばかりです・・・。 ご回答いただき、ありがとうございました!またの機会ありましたら、よろしくお願いいたします!
guest

0

ベストアンサー

java

1import java.util.Scanner; 2 3class Main { 4 public static String removeDuplicates(String str) { 5 for (int i = 0; i < str.length(); i++) { 6 String a = str.substring(0, i+1); 7 String b = str.substring(i+1); 8 String c = str.substring(i, i+1); 9 str = a + b.replace(c, ""); 10 } 11 return str; 12 } 13 14 public static void main(String[] args) { 15 Scanner sc = new Scanner(System.in); 16 String s = sc.next(); 17 System.out.println(removeDuplicates(s)); 18 } 19}

replace を使うなら、このようになると思うんですが、
replace を使わないなら、もっと簡単になります。

java

1 public static String removeDuplicates(String str) { 2 String s = ""; 3 for (char c : str.toCharArray()) 4 if (s.indexOf(c) < 0) s += c; 5 return s; 6 }

toCharArray を使いたくなければ、

java

1 public static String removeDuplicates(String str) { 2 String s = ""; 3 for (int i = 0; i < str.length(); i++) { 4 char c = str.charAt(i); 5 if (s.indexOf(c) < 0) s += c; 6 } 7 return s; 8 }

投稿2021/12/19 01:16

kazuma-s

総合スコア8224

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

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

License

2021/12/19 12:00

アドバイスおよび、ご指摘ありがとうございます。まさに作成したかったのはこのプログラムです!私のそもそもの考え方が違っていたため、まだまだ実践が足りないことを恥ずかしく思うばかりです・・・。本当にありがとうございました!
guest

0

return文の指定について、どうすれば解決できるか

今回のケースでは、空文字列に1文字ずつ加えていき、return する方法が良いと思います。

Java

1public String removeDuplicates(String str) { 2 3 String strAfter = ""; 4 5 char ch0 = 'a'; 6 strAfter = strAfter + ch0; 7 8 char ch1 = 'b'; 9 strAfter = strAfter + ch1; 10 11 char ch2 = 'b'; 12 strAfter = strAfter + ch2; 13 14 char ch3 = 'c'; 15 strAfter = strAfter + ch3; 16 17 return strAfter; 18} 19

→ 結果: "abbc"

はじめに出た文字だけを残し、その後の重複した文字を消す

「はじめに出た文字だけ結果に加え、その後の重複した文字は加えない」と読み替えます。
重複した文字かどうかのチェックには、java.util.HashSet のご利用が便利です。

Java

1 HashSet<Character> set = new HashSet<>(); 2 3 char ch0 = strBefore.charAt(0); 4 if (!set.contains(ch0)) { 5 // ch0 は重複していない 6 } 7 set.add(ch0); 8 9 char ch1 = strBefore.charAt(1); 10 if (!set.contains(ch1)) { 11 // ch1 は重複していない 12 } 13 set.add(ch1);

なお、「HashSetなんて習ってないし、そんなのつかったらおこられちゃうよ///」という特殊なケースに備え、今回は弊社が、送料無料の特別価格(\0)でもう1本サンプルプログラムをお付けいたします!

Java

1 int i0 = 0; 2 char ch0 = strBefore.charAt(i0); 3 if (strBefore.substring(0, i0).indexOf(ch0) == -1) { 4 // ch0 は重複していない 5 } 6 7 int i1 = 1; 8 char ch1 = strBefore.charAt(i1); 9 if (strBefore.substring(0, i1).indexOf(ch1) == -1) { 10 // ch1 は重複していない 11 }

ところで、世の中には for 文という便利なものもありますから、折を見て換装してみてくださいね。

投稿2021/12/19 01:02

momodx

総合スコア185

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

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

swordone

2021/12/19 02:06

あるかないかだけ判定できればいいので、HashSetで十分なのでは? 順番に文字を付け足すのは「空文字に文字を付け足していく」で事足りてますし。
TN8001

2021/12/19 02:13

swordoneさん あぁたしかにチェック用として使う分には十分ですね^^; > streamで1行で書けるんだと思い これをやっていたせいで思い込みがありました。
swordone

2021/12/19 03:06

Stream使うなら、直列ストリームでdistinct使えば一発では?
TN8001

2021/12/19 03:45

swordoneさん はいその通りです^^; はじめ質問を読んだときにSetが思い浮かび素朴に書いてみました。 その後1行になるだろうなと思ってstreamと格闘してました。 C#なら(きっと)楽なのになぁと思い書いてみようとしたところ、C#にはLinkedHashSet相当がありませんでしたw あぁDistinctすりゃいいのかと思って実装できましたが、C#のDistinctは(建前上)安定でないことがわかりましたorz return new string(str.ToCharArray().Distinct().ToArray()); じゃあJavaはどうなんだろうと調べると、distinctは安定でした^^ return str.chars().distinct().mapToObj(c -> String.valueOf((char) c)).collect(Collectors.joining()); というのを今まさにやっておりましたw
License

2021/12/19 22:54

momodx様、みなさま、アドバイスありがとうございます。 HashSetに関してのなですが、完全に初見でした。 ただ、自分の考えからも解決可能だということを知ることができました。 本当にありがとうございました。 またの機会ありましたら、よろしくお願いいたします!
guest

0

・return文の指定について、どうすれば解決できるか、お答えいただきたいです。

やりたいことが「表示」だけでいいのであれば、逆に返り値の型をvoidとすることで、返す必要性自体をなくす、という手段もありえます。

投稿2021/12/18 22:55

maisumakun

総合スコア146018

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

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

License

2021/12/19 22:55

maisumakun様 アドバイスありがとうございます。 そのとおりでした。 まだまだ未熟であるため、身についていないことが多いことを痛感するばかりです。 アドバイスいただき、ありがとうございました! またの機会ありましたら、よろしくお願いいたします!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問