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

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

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

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

Q&A

4回答

4455閲覧

javaでの入力された文字を置き換えた数値化と計算について

uonitarou

総合スコア20

Java

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

0グッド

0クリップ

投稿2018/04/05 06:09

編集2018/04/05 06:24

前提・実現したいこと

入力された文字列を数値に置き換えて整数にし、計算をしたいです。

実現したい処理

を1として

<を5とします

入力値①

+>>>>>

結果①
9

入力値②
<>>>->>>>>

結果②
3

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

動くものができていないのでエラーメッセージがございません。

該当のソースコード

java

1Scanner sc = new Scanner(System.in); 2String line = sc.nextLine(); 3line = line.replaceAll("*", "1");

java

1String[] str = line.split("", -1)

などは試しましたがこれらを駆使して作れないのかなと思いました。
順番を変えたりしましたが、動くものは作れませんでした。
お知恵をお貸しいただければと思います。宜しくお願い致します。

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

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

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

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

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

guest

回答4

0

">>>>"のような文字列を4に変換するためにString#split("",-1)などまで調べたとのことで方向性はよいと思うのですが・・・

プログラムを考えるとき、複雑なことを一挙にやろうとせずに「小さな問題に分割する」という考え方を学ぶとよいと思います。本件でいえば

(1) ">>+<"という文字列を">>""+""<"に分割する
(2) ">>""<"といった文字列を2とか5に変換する
(3) "+""-"といった演算子に応じて(2)で得た数値に対して計算する

こんな方針でそれぞれどうやればよいかを一つずつ攻略していくわけです。各々について「やり方は色々考えられる」ので自分が知っている機能を使ってどうすればできるかを考えたり、それが思いつかなかったら(本件でいえば)Stringクラスの機能を調べて「どんなことができるか」を研究することが大切だと思います。

ヒント:
(1)はプログラムの前提を単純にしてみてください。例えば入力行は必ず次のようなパターンであると前提を置くと取り組みやすくなります。非常に単純な電卓っぽい仕様です。

「>や<で表現された数」「一文字の演算子」「>や<で表現された数」

「一文字の演算子」を最初は+-のみに限定してみましょう。

java

1static void main(String[] args) { 2 ... 3 String line = scanner.nextLine(); 4 String[] operands; 5 String operator; 6 7 operator = "+"; 8 if (line.contains("+")) { 9 operator = "+"; 10 operands = line.split(operator); 11 } else if (line.contains("-")) { 12 operator = "-"; 13 operands = line.split(operator); 14 } else { 15 System.err.println("演算子がありません"); 16 return; 17 } 18 if (operands.length != 2) { 19 System.err.println("ごめんなさい!演算子は1個しか指定できません!"); 20 return; 21 } 22 // この時点でoperatorには"+"か"-"が入り 23 // operands[0]には演算子の左側、operands[1]には演算子の右側の文字列が入ってる 24 ...省略 25}

上の例はエレガントではありませんが、本件に取り組むにあたって最小限の知識で読めるように配慮してみました。これは(1)の部分のみのサンプルです。

このように「機能を単純なものの集まりに分割する」「まがりなりにもなんらかの実装ができる」ところまでできるようになれば、演算子を+,-以外も増やしたり、もっと複雑な式が書けるような仕様に拡張したり、数字を表すのに<や>以外の表記を使えるようにしたり・・・といった次の段階へ進むことができます。

しかし一挙に複雑な仕様を作ろうとはしないことをお奨めします。論理を作る練習が充分できていない段階でそれをしようとしても混乱するだけですし、プログラムを自分の力で完成させられないと達成感も得られません。一歩一歩簡単なプログラムを着実に書く力を付けていって初めて複雑なプログラムが書けるようになるものです。

投稿2018/04/05 07:07

編集2018/04/05 07:09
KSwordOfHaste

総合スコア18394

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

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

uonitarou

2018/04/05 08:40

ご回答ありがとうございます。私なりに細かく分割したつもりでしたがまだ足りなかったようで こればっかりは数をこなすしかないと思うので今後も続けて行こうと思います。今回の設問に3時間もかかってしまったがためにこちらに質問させていただきました。
KSwordOfHaste

2018/04/05 10:32

> こればっかりは数をこなすしかない 機能を分割したり、個々の機能の論理を考えたりするには色々な問題を解いて訓練するのが重要と思います。大切なのは(人からのヒントにせよ自分で考えるにせよ)自分自身の知識・経験を増やし、同様の問題に取り組んだとき「だんだん早く解けるように成長すること」と思います。成長にはやはりある程度の時間はかかると思います。同じ時間をかけるなら動くコードを写経するより自分で論理を考えた方がいいように思います。(人によりけりかも知れません)
guest

0

まず簡単に動くプログラムを作ってから質問してはいかがでしょうか。

入力値結果
>+>2
<->4

またはもっと簡単に

入力値結果
1+12
5-14

ご参考までに
コピペで動いても何の意味もありませんが。。。

また仕様が曖昧過ぎます。
「>>>>+>>>>>」→「1111+11111」で結果が「12222」になると思います。②も同じく。
期待値が正しいのであれば「>+>+>+>+>+>+>+>+>」とする必要があります。
もしくは任意の前提条件を置く必要があります。

投稿2018/04/05 06:55

szk.

総合スコア1400

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

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

uonitarou

2018/04/05 07:10

ご回答いただきありがとうございます。 入力値は固定なのですみませんが>+>+>+>+>+>+>+>+>というのは不可能です。 こちらは >>>>+>>>>> をまず 配列に このように入れ {>,>,>>,+,>,>>,>,>} その後文字の置き換えを行い数値化し {1,1,1,1,+,1,1,1,1,1} これを 演算子はifなどで別で処理して 1つずつ計算していくことを考えていました。
szk.

2018/04/05 07:46

入力値なのに固定というのが分かりません。。。 演算子が1つということでしょうか? ざっと見た感じの仕様としては、  直前の演算子を使って算出する、ただし最初の演算子がない場合は+として算出する という感じでしょうか。 考え方はよいと思いますが、 プログラミングはルールを明確化しないと動きません。 最初に「>>」が続くからといって勝手に足し算してくれません、 足し算するというルール(プログラム)が必要です。
uonitarou

2018/04/05 08:32

こちら最初は演算子が1つかと思っていたので 全ての演算子ではないところに+をつけるのも方法としてできそうですね。 ご回答いただきありがとうございました。
szk.

2018/04/05 08:45

>全ての演算子ではないところに+をつけるのも方法としてできそうですね。 いや、そうすると②のほうがうまくいきませんので、 直前の演算子を使う必要があるのかと思いますが、、、、 間に演算子を入れるイメージとしては ①が{1,+,1,+,1,+,1,+,1,+,1,+,1,+,1,+,1} ②が{5,+,1,+,1,+,1,-,1,-,1,-,1,-,1,-,1} ですよね。
uonitarou

2018/04/05 08:52

なるほど、こちらは (5,+,1,+,1,+,1),-,(1,+,1,+,1,+,1,+,1) を想定しておりました。
szk.

2018/04/05 09:10

お、確かにそれも正しいですね。 しかもそちらのほうが仕様が簡単な気がします;  連続する数字は足し算で先に計算する。 だけ。 なんか変なことをいくつか言ってしまってすいません;;
guest

0

こんにちは

Java

1line = line.replaceAll(">", "1");

おそらくこれだと"1"というのは変数の1ではなく文字列の1になっているので
一度 変数に変換する必要があると思います。(Integer.parseIntなど)

入力値が>>>>+>>>>> や >>>>->>>>> など符号が1つのものだけであることを前提に
話を進めたいと思います。(違ったらすみません)

1.符号が+か-か判断します。+ -> 戻り値1 - -> 戻り値 -1 メソッドjudge_signにて
2.二つの変数の計算ができるように配列を用意します。
3.>の時は1加え >の時は10加えます。
4.文字列の中の符号が訪れたとき配列の番号を0から1に増やします。
5.二つの変数の計算をします。1で戻り値を±1にしたのはこのためです。

以下、ソースコードとなります。

Java

1import java.util.*; 2 3public class Main { 4 public static void main(String[] args) { 5 // Your code here! 6 Scanner sc = new Scanner(System.in); 7 String line = sc.nextLine(); 8 int []number = {0,0};//説明の2番目 9 int position = 0; 10 for(int i = 0; i < line.length(); i++){ 11 char c = line.charAt(i); 12 if(c == '>'){ 13 number[position]++; 14 } 15 else if(c == '<'){ 16 number[position] += 5; //説明の3番目 17 } 18 else{ 19 position++; //説明の4番目 20 } 21 } 22 int sign = judge_sign(line); 23 int answer = number[0] + sign * number[1]; //説明の5番目 24 25 System.out.println(answer); 26 27 } 28 29 public static int judge_sign(String line){ //説明の1番目 30 int sign = 0; 31 for(int i = 0; i < line.length(); i++){ 32 char c = line.charAt(i); 33 if(c == '+'){ 34 sign = 1; 35 } 36 else if(c == '-'){ 37 sign = -1; 38 } 39 } 40 return sign; 41 } 42} 43

<追記> 符号が複数の場合のソースコード

Java

1import java.util.*; 2 3public class Main { 4 public static void main(String[] args) { 5 6 Scanner sc = new Scanner(System.in); 7 String line = sc.nextLine(); 8 int count = count_sign(line) + 1; 9 int []number = new int[count]; 10 for(int i = 0; i < count; i++){ 11 number[i] = 0; /*初期化*/ 12 } 13 int position = 0; 14 int sign = 1; 15 for(int i = 0; i < line.length(); i++){ 16 char c = line.charAt(i); 17 if(c == '>'){ 18 number[position] += sign; 19 } 20 else if(c == '<'){ 21 number[position] += 5 * sign; 22 } 23 else if(c == '+'){ 24 sign = 1; 25 position++; 26 } 27 else if(c == '-'){ 28 sign = -1; 29 position++; 30 31 } 32 } 33 int sum = 0; 34 35 for(int i = 0; i < count; i++){ 36 sum += number[i]; 37 } 38 39 System.out.println(sum); 40 41 } 42 43 public static int count_sign(String line){ 44 int count = 0; 45 for(int i = 0; i < line.length(); i++){ 46 char c = line.charAt(i); 47 if(c == '+' || c == '-'){ 48 count++; 49 } 50 } 51 return count; 52 } 53} 54

投稿2018/04/05 06:52

編集2018/04/05 08:09
退会済みユーザー

退会済みユーザー

総合スコア0

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

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

uonitarou

2018/04/05 07:04

ご回答いただきありがとうございます。 上記コードを 入力値①で実行したところ 見たことのないエラーが出てしまいました。 Main.java:7: error: unreported exception IOException; must be caught or declared to be thrown String line = br.readLine(); ^ 1 error
退会済みユーザー

退会済みユーザー

2018/04/05 07:09

すみません。訂正しておきます。
uonitarou

2018/04/05 07:10

お手数おかけします。ありがとうございます。
退会済みユーザー

退会済みユーザー

2018/04/05 07:12

オンライン上でやっていてそこではエラーは出てなかったのですが try ~ catchが必要だと思います。 入力の方法を変更しました。
uonitarou

2018/04/05 07:45

すみません 因みに複数の演算子があった場合の処理をいただいたコードを軸に自分なりに書いて見たのですが、以下のエラーが出てしまいました。もしよろしければどこが悪いのか原因を教えていただけないでしょうか?宜しくお願い致します。 エラー Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 2 at Main.main(Main.java:17) (Exit status: 1) 該当コード ```java BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); String E = br.readLine(); int []number = {0,0}; int youso = 0; // 配列[0] 左辺から for(int i = 0; i < E.length(); i++){ char c = E.charAt(i); // /の時は+1 if(c == '/'){ number[youso]++; } // <の時は + 10 else if(c == '<'){ number[youso] += 10; } // 演算子の時 配列を[1]に(右辺へ) else{ youso++; } } //計算 int answer = 0; for (int j = 0; j < number.length; j++) { answer = answer + number[j]; } System.out.println(answer); ```
退会済みユーザー

退会済みユーザー

2018/04/05 07:50

java.lang.ArrayIndexOutOfBoundsExceptionは配列の要素数以上の数字が代入されたとき 起こるエラーです。符号が2つの時は int []number = {0,0}; でよかったのですが 符号が複数になるとnumberの要素数は変わります。 (具体出的に言うと符号の数 + 1) ですのでまず最初に符号の個数を数え そのあとに配列numberを宣言するといいと思います。
退会済みユーザー

退会済みユーザー

2018/04/05 08:07

符号が複数の場合のソースコードを載せておきます。
uonitarou

2018/04/05 08:13

あらかじめ初期値に0を入れておけばうまく動作はするんですがこれでは原始的すぎますよね int []number = {0,0,0}; 符号の数を数えることを文字列の段階で試みたのですが int kazu = 0; Boolean tf = line.indexOf("+"); if ( true == tf) { kazu = kazu + 1; } 型は会ってると思うのですが1このようなエラーが返されてしまいました。 Main.java:11: error: incompatible types: int cannot be converted to Boolean Boolean tf= E.indexOf("+"); もしよろしければご回答いた亜dければとおもいます。
uonitarou

2018/04/05 08:13

すみません わざわざ 一度照らし合わせて見ます。
退会済みユーザー

退会済みユーザー

2018/04/05 08:24

booleanを使いたければ Boolean tf = (評価式) というような形にする必要があります。
uonitarou

2018/04/05 08:31

booleanについてはサイトを見て理解しました。詳しくありがとうございます。
退会済みユーザー

退会済みユーザー

2018/04/05 09:21

あと、[]number = {0,0,0}とすると符号が2つの場合に限るので一般化したいのであれば 私のコードのようにint []number = new int[count]にすべきです。
guest

0

まあ類推できるようなもの計算記号は自分で分離してくださいとなりますが

ローマ数字を引数に持たせてコンピューターが理解できる数値に変換するのはこちらになります。

ローマ数字をアラビア数字に置き換える場合

java

1map.put("I", 1D); 2map.put("V", 5D); 3map.put("X", 10D); 4map.put("L", 50D); 5map.put("C", 100D); 6map.put("D", 500D); 7map.put("M", 1000D);

となります。
まあほかの条件は ローマ数字 - Wikipedia を見てください。

その条件をもとに計算する場合

java

1public RomaNumber(String strValue) { 2 this.strValue = strValue; 3 new StringBuilder(strValue).reverse().chars().forEach(n -> { 4 String x = new String(new char[] { (char) n }); 5 double current = valueMap.get(x); 6 BigDecimal currentBd = new BigDecimal(current); 7 if (current < lastValue) 8 value = value.subtract(currentBd); 9 else 10 value = value.add(currentBd); 11 lastValue = current; 12 }); 13}

のような実装になります。

この実装が正しいかをチェックしてみましょう。

java

1import static org.junit.jupiter.api.Assertions.*; 2 3import java.util.HashMap; 4import java.util.Map; 5import java.util.Map.Entry; 6import java.util.stream.Stream; 7 8import org.junit.jupiter.params.ParameterizedTest; 9import org.junit.jupiter.params.provider.MethodSource; 10 11class RomaNumberTest { 12 13 static Stream<Entry<String, Integer>> values() { 14 15 Map<String, Integer> map = new HashMap<>(); 16 17 map.put("I", 1); 18 map.put("II", 2); 19 map.put("III", 3); 20 map.put("IV", 4); 21 map.put("V", 5); 22 map.put("VI", 6); 23 map.put("VII", 7); 24 map.put("VIII", 8); 25 map.put("IX", 9); 26 map.put("X", 10); 27 map.put("XX", 20); 28 map.put("XXX", 30); 29 map.put("XL", 40); 30 map.put("L", 50); 31 map.put("LX", 60); 32 map.put("LXX", 70); 33 map.put("LXXX", 80); 34 map.put("XC", 90); 35 map.put("C", 100); 36 map.put("CC", 200); 37 map.put("CCC", 300); 38 map.put("CD", 400); 39 map.put("D", 500); 40 map.put("DC", 600); 41 map.put("DCC", 700); 42 map.put("DCCC", 800); 43 map.put("CM", 900); 44 map.put("M", 1000); 45 map.put("MM", 2000); 46 map.put("MMM", 3000); 47 48 map.put("LXXXIX", 89); 49 map.put("CCXCIX", 299); 50 51 return map.entrySet().stream(); 52 } 53 54 @ParameterizedTest 55 @MethodSource("values") 56 void testIntValue(Entry<String, Integer> entry) { 57 RomaNumber rn = new RomaNumber(entry.getKey()); 58 int value = entry.getValue(); 59 int test = rn.intValue(); 60 assertEquals(test, value); 61 } 62 63}

を実施し想定した数値になるかを確認してみましょう。
こんな感じで独自数値形式を作ってみましょう

投稿2018/04/05 12:24

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問