2019/05/04 21:30の内容
さて,次に引き算です.今回のプログラムは正の整数しか入力がない前提で書いていますが,残念ながら引き算は正の整数同士の計算でも負の数が答えになる場合があります.これに対する対処法は2つです.1つはa-bという計算において,a>bでしか計算を行わないようにするという方法.もう1つはa-bでa<bのとき,b-aをしてから先頭に-をつけて出力するという方法です.
後者のマイナスを先頭につけて出力する方法で今回は書いていきたいと思います.
1.入力された数字のどちらが大きいかを見分ける作業
大きい数字から小さい数字を引く作業をする以上,どちらの数字が大きいのかを確認する必要があります.
まず,桁数の違う2値の場合は,足し算同様に少ない桁数側の先頭を0埋めしたListを作成します.
次に,2つのListの先頭から順に数値をみていきます.どちらかの数字が大きい場合,そこで処理を中止し,大きい値が取得できた方のListを大,もう片方を小として保管します.具体例は以下の通りです.
113-123をさせたい.それぞれをlist1とlist2に入れる.
list1 = [1,1,3]
list2 = [1,2,3]
を先頭から見ていく
list1の0番目要素は1,list2の0番目要素は1,値は同じなので処理は続く
list1の1番目要素は1,list2の1番目要素は2,値はlist2の方が大きいので処理を終了
ここで,プログラムを書く都合上,list1を大,list2を小として扱いたいと思います.しかし,上のままではlist2が大になっているので入れ替えておきましょう.
List<String> tmp = list1;
list1 = list2;
list2 = tmp;
また,入れ替えたことはboolean型などで覚えておきましょう.最後に-をつけるかどうかで使います.
引き算の実装
list1-list2をする前提で書いていきます.また,先の説明から,list1>list2は成り立っている前提になります.
引き算において必要な情報は以下の通りです
- 各Listの計算する桁の数字
- 1つ上の位から繰り下がりしてくるか
- 1つ下の位から繰り下がりされたか
ほぼ,足し算と同じですね.
よって以下のようになります.
list1=[1,0,0]
からlist2=[0,9,5]
を引く計算をします.
- 各リストの後ろから数字を取ってきて(
int a = 0, int b =5
)
- 下の位から繰り下がりされてないので,それに関する処理はせず
int c = a - b
(c = -5)
a < b
なので,上の位から繰り下げてくる(c += 10
)->(c = 5
)
- 繰り下げてきたことをboolean型などで覚えておく(boolean borrow = true)
- 下から2桁目を取ってくる(
int a = 0, int b = 9
)
- 下の位から繰り下がりされているので,aの値から-1しておく(
a--
)->(a = -1
)
int c = a - b
(c = -10
)
a < b
なので,上の位から繰り下げてくる(c += 10
)->(c = 0
)
- 繰り下げてきたことをboolean型で記憶
- 下から3桁目を取ってくる(
int a = 1, int b = 0
)
- 下の位から繰り下がりされているので,aから-1(
a--
)->(a = 0
)
int c = a - b
(c = 0
)
- a < bではないので繰り下げてくる処理なし
- 終了
答えが[0,0,5]で5になりましたね.
お気づきかと思いますが,答えも先頭0埋めで返ってきます.
答えを表示するときなどは,先頭0梅を取ってから表示してあげてくださいね.
もし,95-100をしていたなら,最初にlist1とlist2の値を入れ替えたことを記録しているはずなので,答えの先頭に-をつけてから返してあげてください.
以下 2019/05/03 17:00以前の内容
やりたいことが理解でき,何をプログラムで実装したいのかわかりました.私も同じこと考えたことあります,実用性は二の次で自力で組み上げてみたいみたいな気持ちで書いていたことがあります,挫折しましたが(笑)
当時の気持ちを思い出しながら,私の方でも書いてみました.無事動くものが出来上がったので,ポイントさえ抑えれば実現はもちろんできます.いきなり答えを載せるのは何か違うなと感じたので,ヒントのようなものを書きたいと思います.
1.とりあえず足し算を実装
引き算の方がやはり難しいです.Listを使った足し算を実装してから,その要領で引き算を実装しましょう.
2.String->List<String>をするときに
String a = "123456";
List<String> list1 = Arrays.asList(a.split(""));
としてしまうと, list1.add("0");
で要素の追加をするとエラーが発生します.これは,Arrays.asList()
を使うと,Listの長さを固定長にしてしまうからです.上のコードの場合,list1は[1,2,3,4,5,6]となりますが,list1の長さは6で固定となるため,7個目の要素を入れることができません.これを回避する方法として,先にListだけ作成するという方法があります.具体的には以下の通りです
String a = "123456";
List<String> list1 = new ArrayList<String>();
list1.addAll(Arrays.asList(a.split("")));
このように,先にListをnew ArrayList<String>()
で宣言しておくことによって,可変長,つまり長さ制限のないものが出来上がります.
足し算を実装するには
-
桁数の違う足し算などをするとき,少ない桁数の数字は先頭を0で埋めると扱いやすくなります.与えられる数字がそれぞれ,12345と6789のとき,Listの中身では[1,2,3,4,5]と[0,6,7,8,9]とする方が扱いやすいのです.これによって,forで各要素(数字)を見るときに,桁数の違いによるループ回数の差などを気にしなくてよくなります.
-
足し算に置いて必要なものは次の通りです.
- 計算する桁の数字2つ
- 1つ下の桁からの繰り上がりがあるか
- 1つ上に繰り上げるか
先ほど例に出したList[1,2,3,4,5]と[0,6,7,8,9]をそれぞれlist1とlist2という名前とし,これらの足し算を例に挙げると,
- list1と1ist2の後ろから要素を取り出してきて(
int a = 5, int b = 9
)
- それぞれを足して(
int c= a + b
)
- 1つ下からの繰り上がりはないので,
c = c + 1
の処理は飛ばして
- 次の桁に繰り上がりするので,繰り上がりすることをboolean型などで覚えておく
といったことを繰り返して(for文)いけば足し算の完成です.
まだ注意するべきこともありますが,とりあえず足し算を作ってみましょう!
質問等あればまたどうぞ,最初から私が書いたやつ載せて!という場合も載せますので...
以下 2019/05/03 05:20以前の内容
私なりの回答を置いておきます.質問の意図と違う回答でしたら,またおっしゃってください.
import java.util.List;
import java.util.ArrayList;
import java.util.Arrays;
// ファイル名をlistcharAt2.javaにしたため
class java_listcharAt2 {
public static void main(String[] args) {
// String型配列を使い,かつArrays.asListを使う前提とすると,こういう書き方をしたかったのではないかという予想
String[] a = { "1", "2", "3", "4", "5", "6", "7", "8", "9", "4", "5", "8", "5", "5", "8", "4", "8", "5", "8" };
// String型19の要素を含むListを作成したかったのではないかという予想
List<String> list1 = Arrays.asList(a);
int i;
// for文の中でA[i]としていたので,Aは配列だと予想
int[] A = new int[list1.size()];
for (i = list1.size() - 1; i >= 0; i--) {
// Listから要素を取ってくる時は,charAtは使えないので,とりあえずget.型をintにするために,Integer.parseInt(String)
A[i] = Integer.parseInt(list1.get(i));
}
// 正しく格納されているかを確認するために追加.
for (i = 0; i < A.length; i++) {
System.out.println(A[i]);
}
}
}