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

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

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

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

Q&A

3回答

4036閲覧

計算機の機能追加に関する質問

Oracle

総合スコア13

Java

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

1グッド

2クリップ

投稿2016/10/15 10:44

編集2016/10/15 13:08

javaで計算機のプログラムを作成しました。
単項マイナス演算(例、-10+5)を行う処理を追加したいのですが
修正方法がわかりません。
どのように修正したらよいでしょうか?
今後の参考の為にどなたか教えてください
よろしくお願いします。

また下記のソースコードで改正案があればご教授願います。
よろしくお願いします。

import

1import java.io.BufferedReader; 2import java.io.InputStreamReader; 3import java.util.StringTokenizer; 4 5class UsrExprException extends Exception { 6 7 public UsrExprException(String s){ 8 super(s); 9 } 10} 11//Calcクラス 12public class Calc { 13 //メインメソッド 14 public static void main(String[] args) { 15 16 try { 17 int ans = 0; 18 19 InputStreamReader isr = new InputStreamReader(System.in); 20 21 BufferedReader br = new BufferedReader(isr); 22 23 String s = br.readLine(); 24 25 while (s != null && !s.equals("")) { 26 27 Calc calc = new Calc(); 28 29 ans = calc.calc(s); 30 31 System.out.println("=" + ans); 32 33 s = br.readLine() 34 } 35 36 } catch (Exception e) { 37 38 System.out.println("例外:"+ e); 39 } 40 } 41 42 public int calc(String s) throws UsrExprException { 43 44 UsrExprException ue; 45 46 int ans = 0; 47 48 StringTokenizer st = new StringTokenizer(s, "+-*/", true); 49 50 String sign = "+"; 51 52 String tok ; 53 int tknum = 0; 54 55 while (st.hasMoreTokens()) { 56 57 tok = st.nextToken(); 58 59 tok = tok.trim(); 60 61 if (tok.length() == 0) { 62 63 continue; 64 } 65 66 if (tknum % 2 == 0) { 67 68 if (sign.equals("+")) { 69 70 ans += Integer.parseInt(tok); 71 } 72 else if (sign.equals("-")) { 73 ans -= Integer.parseInt(tok); 74 } 75 else if (sign.equals("*")) { 76 ans *= Integer.parseInt(tok); 77 } 78 else if (sign.equals("/")) { 79 ans /= Integer.parseInt(tok); 80 } 81 } else { 82 83 sign = tok; 84 } 85 86 tknum++; 87 } 88 //式の最後が整数でない場合 89 if ( tknum % 2 == 0) { 90 ue = new UsrExprException("最終整数なし"); 91 throw ue; 92 } 93 //ansを返す 94 return ans; 95 } 96} 97 98```
asadako👍を押しています

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

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

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

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

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

KSwordOfHaste

2016/10/15 11:33

質問編集時に入力エリアの上の方にある「</>」を使ってコードを見やすく整形しないとインデンテーションがつかないので閲覧者にみずらいコードになってしまいますよ。
ikedas

2016/10/16 00:14

チラ見なので間違ってるかもしれませんが、今のプログラムは「電卓」っぽい動きをしてるようです。つまり、1.記号キーで計算の種類が決まり、2.被演算数を記憶し、3.計算して結果出力。このやり方でいくのか、それとももっと複雑な式 (たとえば1+2×3で2×3を先に計算するとか、括弧が使えるとか) が計算できるものにしたいのでしょうか。どちらですか。
Oracle

2016/10/16 01:36

このやり方での修正をを希望です。
guest

回答3

0

Java

1import java.io.BufferedReader; 2import java.io.InputStreamReader; 3import java.util.ArrayDeque; 4import java.util.EmptyStackException; 5import java.util.HashMap; 6import java.util.Stack; 7import java.util.StringTokenizer; 8 9// Calcクラス 10public class Calc 11{ 12 // メインメソッド 13 public static void main(String[] args) 14 { 15 try 16 { 17 InputStreamReader isr = new InputStreamReader(System.in); 18 BufferedReader bReader = new BufferedReader(isr); 19 20 Calc calc = new Calc(); 21 22 for (; ;) 23 { 24 // プロンプトの出力 25 System.out.print(">"); 26 27 String expr = bReader.readLine(); 28 if (expr == null || expr.equals("")) 29 { 30 break; 31 } 32 33 try 34 { 35 int ans = calc.calc(expr); 36 System.out.println("=" + ans); 37 } 38 catch (UsrExprException e) 39 { 40 System.out.println("式に誤りがあります : " + e.getMessage()); 41 } 42 } 43 } 44 catch (Exception e) 45 { 46 System.out.println("例外 : " + e); 47 } 48 49 System.out.println("終了"); 50 } 51 52 53 public int calc(String expr) throws Exception 54 { 55 // 全ての空白文字を取り除く 56 expr = expr.replaceAll("\\s+", ""); 57 58 boolean printRevPolishExpr = false; 59 // p で始まっていたら、逆ポーランド記法表示モード 60 if (expr.startsWith("p")) 61 { 62 printRevPolishExpr = true; 63 expr = expr.substring(1); 64 } 65 66 // 字句解析 67 StringTokenizer tokenizer = new StringTokenizer(expr, "+-/*", true); 68 69 ArrayDeque<String> tokenQueue = new ArrayDeque<>(); 70 71 while (tokenizer.hasMoreTokens()) 72 { 73 String token = tokenizer.nextToken(); 74 75 if (! token.isEmpty()) 76 { 77 tokenQueue.add(token); 78 } 79 } 80 81 tokenQueue = replaceAsUnaryOps(tokenQueue); 82 83 ArrayDeque<String> revPolishQueue = toRevPolish(tokenQueue); 84 85 if (printRevPolishExpr) 86 { 87 ArrayDeque<String> revPolishExpr = revPolishQueue.clone(); 88 89 while (! revPolishExpr.isEmpty()) 90 { 91 System.out.print(" " + revPolishExpr.remove()); 92 } 93 System.out.println(); 94 } 95 96 return evaluate(revPolishQueue); 97 } 98 99 100 // 単項演算子を見つけて置換する 101 protected static ArrayDeque<String> replaceAsUnaryOps(ArrayDeque<String> tokenQueue) 102 { 103 ArrayDeque<String> outQueue = new ArrayDeque<>(); 104 105 // 前回の演算子を"+"に初期化 106 String lastOperator = "+"; 107 108 while (! tokenQueue.isEmpty()) 109 { 110 String token = tokenQueue.remove(); 111 if (isNumber(token)) 112 { 113 lastOperator = null; 114 outQueue.add(token); 115 continue; 116 } 117 118 // tokenは演算子 119 120 if (lastOperator == null) 121 { 122 lastOperator = token; 123 outQueue.add(token); 124 continue; 125 } 126 127 // 前回も演算子 128 129 switch (token) 130 { 131 case "+": 132 // 何もしないので詰めない 133 break; 134 135 case "-": 136 if (lastOperator.equals("u-")) 137 { 138 // 2回連続"u-"である場合 139 140 // 前回詰めた"u-"を捨てる 141 outQueue.removeLast(); 142 143 // 前々回詰めた演算子を復元する 144 lastOperator = outQueue.peekLast(); 145 if (lastOperator == null) 146 { 147 // 前回の演算子を"+"に再初期化 148 lastOperator = "+"; 149 } 150 } 151 else 152 { 153 lastOperator = "u-"; 154 outQueue.add("u-"); 155 } 156 break; 157 158 default: 159 lastOperator = token; 160 outQueue.add(token); 161 } 162 } 163 164 return outQueue; 165 } 166 167 168 // 式を逆ポーランド記法に変換する 169 protected static ArrayDeque<String> toRevPolish(ArrayDeque<String> tokenQueue) 170 throws UsrExprException 171 { 172 ArrayDeque<String> outQueue = new ArrayDeque<>(); 173 Stack<String> stack = new Stack<>(); 174 175 while (! tokenQueue.isEmpty()) 176 { 177 String token = tokenQueue.remove(); 178 179 if (isNumber(token)) 180 { 181 // 数値ならば無条件にキューに書き出す 182 outQueue.add(token); 183 continue; 184 } 185 186 // tokenは演算子 187 188 if (stack.isEmpty()) 189 { 190 // スタックが空ならば無条件にスタックに積む 191 stack.push(token); 192 continue; 193 } 194 195 // スタックは空ではない 196 197 // tokenの優先順位を得る 198 int priorityOfToken = getPriorityOf(token); 199 200 // スタックの先頭を得る(ただし取り出さない) 201 String topOfStack = stack.peek(); 202 if (priorityOfToken > getPriorityOf(topOfStack)) 203 { 204 // スタックの先頭より優先順位が高ければスタックに積む 205 stack.push(token); 206 continue; 207 } 208 209 do 210 { 211 // スタックの先頭を取り出してキューに書き出す 212 topOfStack = stack.pop(); 213 outQueue.add(topOfStack); 214 215 // スタックの先頭より優先順位が低くなるまで繰り返す 216 if (priorityOfToken > getPriorityOf(topOfStack)) 217 { 218 break; 219 } 220 } 221 while (! stack.isEmpty()); 222 223 // スタックに積む 224 stack.push(token); 225 } 226 227 // スタックに残っている全てを取り出してキューに書き出す 228 while (! stack.isEmpty()) 229 { 230 String topOfStack = stack.pop(); 231 outQueue.add(topOfStack); 232 } 233 234 return outQueue; 235 } 236 237 protected static boolean isNumber(String token) 238 { 239 try 240 { 241 Integer.parseInt(token); 242 return true; 243 } 244 catch (NumberFormatException e) 245 { 246 return false; 247 } 248 } 249 250 251 // 演算子の優先順位を定義 252 protected static final HashMap<String, Integer> priorityMap = 253 254 new HashMap<String, Integer>() { 255 { 256 // ※数値が高いほど、優先順位が高いとする 257 put("u+", 3); // 単項演算子 258 put("u-", 3); // 単項演算子 259 put("*", 2); 260 put("/", 2); 261 put("+", 1); 262 put("-", 1); 263 } 264 }; 265 266 267 // 演算子の優先順位を得る 268 protected static int getPriorityOf(String operator) 269 throws UsrExprException 270 { 271 Integer priority = priorityMap.get(operator); 272 // 見つからない場合はnullを返す 273 274 if (priority != null) 275 { 276 return priority; 277 } 278 279 throw new UsrExprException("'" + operator + "':未知の演算子"); 280 } 281 282 283 // 逆ポーランド記法に変換された式を評価する 284 protected static int evaluate(ArrayDeque<String> revPolishQueue) 285 throws UsrExprException 286 { 287 int ans; 288 ValueStack stack = new ValueStack(); 289 290 try 291 { 292 while (! revPolishQueue.isEmpty()) 293 { 294 String token = revPolishQueue.remove(); 295 296 if (isNumber(token)) 297 { 298 // 数値ならば無条件にスタックに積む 299 stack.push(token); 300 continue; 301 } 302 303 int operand1; 304 int operand2; 305 306 switch (token) 307 { 308 case "u+": // 単項 + 演算子 309 // スタックはそのまま 310 break; 311 312 case "u-": // 単項 - 演算子 313 operand1 = stack.pop(); 314 // 演算結果をスタックに積む 315 stack.push(- operand1); 316 break; 317 318 case "+": 319 operand2 = stack.pop(); 320 operand1 = stack.pop(); 321 // 演算結果をスタックに積む 322 stack.push(operand1 + operand2); 323 break; 324 325 case "-": 326 operand2 = stack.pop(); 327 operand1 = stack.pop(); 328 // 演算結果をスタックに積む 329 stack.push(operand1 - operand2); 330 break; 331 332 case "*": 333 operand2 = stack.pop(); 334 operand1 = stack.pop(); 335 // 演算結果をスタックに積む 336 stack.push(operand1 * operand2); 337 break; 338 339 case "/": 340 operand2 = stack.pop(); 341 operand1 = stack.pop(); 342 // 演算結果をスタックに積む 343 stack.push(operand1 / operand2); 344 break; 345 } 346 } 347 348 // 最終結果をスタックから取り出す 349 ans = stack.pop(); 350 } 351 catch (EmptyStackException e) 352 { 353 throw new UsrExprException("数値が足りない"); 354 } 355 356 if (! stack.empty()) 357 { 358 throw new UsrExprException("演算子が足りない"); 359 } 360 361 // ansを返す 362 return ans; 363 } 364} 365 366 367import java.util.EmptyStackException; 368import java.util.Stack; 369 370 371public class ValueStack { 372 373 private Stack<Integer> stack = new Stack<>(); 374 375 376 public ValueStack() { 377 } 378 379 380 public int push(int item) { 381 return stack.push(item); 382 } 383 384 385 public int push(String item) throws NumberFormatException { 386 387 Integer num = Integer.parseInt(item); 388 389 if (num == null) { 390 throw new NullPointerException(); 391 } 392 393 return stack.push(num); 394 } 395 396 397 public int pop() throws EmptyStackException { 398 return stack.pop(); 399 } 400 401 402 public boolean empty() { 403 return stack.empty(); 404 } 405}

キュー、スタックはデータ構造で、よく使われます。
case 文字列: … break; はJavaのバージョンによって使えない場合があります。
else if (token.equals(文字列)) { … } に変えてください。

逆ポーランド記法に変換するメソッドを少し変えるだけで( )も扱えるようになります。
優先順位を正しく設定すると、Javaのほかの演算子、%, &, |, ^, ~などにも対応できます。
字句解析を正規表現によるマッチングに変えると、浮動小数点、複数文字の演算子、>>, >>>, <<やJavaにはない演算子、例えばべき乗 ** も扱えるようになりますね。

投稿2016/10/16 00:11

編集2016/10/20 17:17
naomi3

総合スコア1105

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

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

Oracle

2016/10/16 06:10 編集

回答ありがとうございます。 一つお聞きしたいのですが、トークンが演算子の場合 何のために符号"+"をセットしているのでしょうか? また、 下記の処理の説明も併せてご説明を伺いたいのですが。 どうかよろしくお願い致します。 if (sign.equals("-")) { num = - num; }
naomi3

2016/10/16 06:27

符号を再初期化するためです。 sign = "-" のときに、次に符号"-"が来ないにもかかわらず、自動的に負数になることを避けるためです。signにセットするのはnullまたは"-"以外であれば何でもいいです。
naomi3

2016/10/16 06:31

単項演算子(-)の処理です。 整数の前に"-"があれば、負数にします。
Oracle

2016/10/16 06:33

naomi3さん。 丁寧なご回答ありがとうございます。 大変ご参考になりました。
Oracle

2016/10/16 09:47

申し訳ございませんが、再度ご質問させて下さい。 上記のコードの場合、2*--2と入力した場合、結果は答えの4ではない-4と出力されてしまいます。 おそらくマイナス単項演算の処理ができていないことが原因だと思います。 このバグ処理を修正したいのですがどうすればいいでしょうか? どうか宜しくお願いします
naomi3

2016/10/16 21:54

public int calc(String expr) throws Exception { int ans = 0; StringTokenizer tokenizer = new StringTokenizer(expr, "+-*/", true); // 符号を 正 に初期化 int sign = 1; String operator = "+"; while (tokenizer.hasMoreTokens()) { String token = tokenizer.nextToken().trim(); if (token.length() == 0) { continue; } int num; if (! token.matches("[-+*/]")) { // トークンが演算子でなければ、整数と解釈し、演算を行う try { num = Integer.parseInt(token); } catch (NumberFormatException e) { throw new UsrExprException("整数ではない"); } // num の符号を sign に合わせる num *= sign; if (operator.equals("+")) { ans += num; } else if (operator.equals("-")) { ans -= num; } else if (operator.equals("*")) { ans *= num; } else if (operator.equals("/")) { ans /= num; } operator = null; } else { // トークンが演算子の場合 if (operator == null) { // 前回が演算子でなければ、演算子を保存 operator = token; // 符号を 正 にリセット sign = 1; } else { // 前回が演算子の場合 if (token.equals("-") || token.equals("+")) { // トークンが符号であれば、演算子はそのまま // マイナスならば符号反転 sign *= (token.equals("-") ? -1 : 1); } else { throw new UsrExprException("演算子の次が符号でない"); } } } } // 式の最後に整数がない場合 if (operator != null) { throw new UsrExprException("式の最後に整数がない"); } //ansを返す return ans; } 符号反転を簡単にするためにsignをintにしました。
Oracle

2016/10/17 09:29

naomi3 さん。 度々のご回答ありがとうございます。 お詳しいですね。 ロジック周りは調べてもわからないところが あるので非常に助かっております。
Oracle

2016/10/17 13:35 編集

naomi3 さん。 さっそくまた、質問させて下さい(笑) 上記の計算機の機能はそのままで 今度は1+4+3×5のような処理を行い、適切な答えが 返ってくる計算機のプログラムを作成したいと考えております。 ソースコードはおそらく大幅な修正が必要だと思います。 これは難しいとは思いますが 可能であればその処理ができるソースコード(上記のソースコードの修正)を記入 していただきたいのですがお願いできますでしょうか? 度々すみませんが、どうかよろしくお願いします。
guest

0

よく目にする一般的な数式の場合、単項演算子(-)は2項演算子(+,-,,/)より優先度が高いというのを利用して再帰下降構文解析という手法を使うとよいと思います。単項演算子だけでなく括弧による優先順の変更や'','/'を'+','-'よりも優先度を高くしたいといったことの実現にもうまくはまります。

「再帰下降構文解析」のキーワードでいくつかヒットすると思いますのでご自分が書いているコードと照らし合わせ、手頃なコード例が載っているサイトを探してみるとよいと思います。

追記:

優先順位ありの計算機をつくりたいとのことなので(再帰を使わなくても達成できますが)簡単な再帰下降構文解析の例を書いてみます。エッセンスを示すだけなので細かな処理は端折ります。数式の計算だと構文規則が割合単純なため演算子の優先順に従い直感的に書けます。(すみませんが動かしてないのでバグあったらゴメンナサイ)

java

1// この方法ではトークンを1つ先読みできることが前提なのでこういうTokenizerがあると思ってください 2// 簡単のために最後に必ず'='などの式の終わりを示すトークンがあると仮定します。 3class Tokenizer extends StringTokenizer { 4 string currentToken; 5 6 string nextToken() { 7 string result = currentToken; 8 currentToken = nextToken(); 9 return result; 10 } 11} 12 13class Calculation { 14 // ここが計算の入り口です 15 int evalExpression(Tokenizer t) { 16 t.nextToken(); // 常に1個だけトークンを先読みしておく。以降全て同じ 17 return additiveExpression(t); 18 } 19 20 // 加減算の式の計算:'+'や'-'がある限り計算します 21 int additiveExpression(Tokenizer t) { 22 int result = multiplicativeExpression(t); 23 for (;;) { 24 switch (t.currentToken) { 25 case "+": 26 t.nextToken(); 27 result += multiplicativeExpression(t); 28 break; 29 case "-": 30 t.nextToken(); 31 result -= multiplicativeExpression(t); 32 break; 33 case "=": 34 return result; 35 default: 36 throw new RuntimeException("syntax error"); 37 } 38 } 39 40 // 乗除算の式の計算:'*'や'/'がある限り計算します 41 int multiplicativeExpression(Tokenizer t) { 42 int result = unaryExpression(t); 43 for (;;) { 44 switch (t.currentToken) { 45 case "*": 46 t.nextToken(); 47 result *= unaryExpression(t); 48 break; 49 case "/": 50 t.nextToken(); 51 result /= unaryExpression(t); 52 break; 53 default: 54 return result; 55 } 56 } 57 58 // 単項演算子、括弧、または数字の計算 59 int unaryExpression(Tokenizer t) { 60 switch (t.currentToken) { 61 case "-": 62 t.nextToken(); 63 return -unaryExpression(t); 64 case "(": { 65 t.nextToken(); 66 int result = additiveExpression(t); 67 if (!t.currentToken.equals(")") 68 throw new RuntimeException("syntax error"); 69 t.nextToken(); 70 return result; 71 } 72 default: { 73 int result = Integer.parseInt(t.currentToken); 74 t.nextToken(); 75 return result; 76 } 77 } 78 } 79}

投稿2016/10/15 11:48

編集2016/10/17 11:52
KSwordOfHaste

総合スコア18394

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

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

Oracle

2016/10/17 12:22

素晴らしいですね。 ご回答ありかとうございます。 大変参考になりました。
KSwordOfHaste

2016/10/17 13:15

単に一つの例として挙げましたが、再帰を使わないアルゴリズムやスタックを使ったものとかも含めてアルゴリズムを考える幅が広がると思うので時間がゆるすならいろいろやってみるとよいと自分は思います。
guest

0

ご質問のコードでは、toknumという変数を見て「偶数個のトークンを受け取ったらsignに記憶しておいた計算をする」となっています。しかし考えてみると、変数signには常に「次にやる計算」が記憶されているのですから、何番目のトークンかを数えなくてもいいですね。

Calc.calc()をこんなふうに変えてみます。

lang

1 public int calc(String s) throws UsrExprException { 2 UsrExprException ue; 3 4 int ans = 0; // アキュムレータ。初期値は0。 5 String sign = "ADD"; // 内部状態。初期状態は"ADD"。 6 7 StringTokenizer st = new StringTokenizer(s, "+-*/", true); 8 String tok ; 9 10 while (st.hasMoreTokens()) { 11 tok = st.nextToken(); 12 tok = tok.trim(); 13 14 if (tok.length() == 0) { 15 continue; 16 } 17 18 if (tok.equals("+")) { 19 // 処理なし。常に内部状態を"ADD"に更新 20 sign = "ADD"; 21 } 22 else if (tok.equals("-")) { 23 // 処理なし。常に内部状態を"SUB"に更新 24 sign = "SUB"; 25 } 26 else if (tok.equals("*")) { 27 // 処理なし。常に内部状態を"MUL"に更新 28 sign = "MUL"; 29 } 30 else if (tok.equals("/")) { 31 // 処理なし。常に内部状態を"DIV"に更新 32 sign = "DIV"; 33 } 34 else { // トークンが数のとき 35 // 内部状態によって決まる処理をする 36 if (sign.equals("ADD")) { 37 ans += Integer.parseInt(tok); 38 } 39 else if (sign.equals("SUB")) { 40 ans -= Integer.parseInt(tok); 41 } 42 else if (sign.equals("MUL")) { 43 ans *= Integer.parseInt(tok); 44 } 45 else if (sign.equals("DIV")) { 46 ans /= Integer.parseInt(tok); 47 } 48 else { 49 ue = new UsrExprException("最終整数なし"); 50 throw ue; 51 } 52 // 内部状態をリセット。 53 sign = ""; 54 } 55 } 56 //ansを返す 57 return ans; 58 } 59

変数signは、次に何の計算をするかを記憶しています。つまり、プログラムの「内部状態」を表していると考えられます (トークンと内部状態の区別がつくよう、signの取る値を変えてみました)。

変更後のコードでは、

  1. トークンをひとつづつ読み取って、
  2. トークンの種類と現在の内部状態の組み合わせから実行すべき処理を決め、実行し、
  3. さらに、同じ組み合わせから次の内部状態を決め、更新する。

という動作をしています。

このように、入力と内部状態に基づいて決められた動作をするものを決定性有限オートマトン (DFA) と呼び、コンピュータシステムのいろんなところで使われています (現実の電卓にも使われています)。DFAの考えかたを使うと、入力とそれに対する処理の関係がうまく整理できるので、機能拡張もやりやすくなります。

投稿2016/10/16 06:58

ikedas

総合スコア4335

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

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

Oracle

2016/10/16 08:01

丁寧な回答ありがとうございます。 大変ご参考になりました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

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

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

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問