はじめに
こんにちは、野村です。
今回は、Javaを使っていくつかの数列を表示させてみます。
普通に書くのは面白くないので、ループ(forやwhile)を禁止してみました。
しかし、ソースがやたらと長くなるのは何とかならないものだろうか?
インストールと実行
インストール
環境はdebian9.2です。
とりあえず、現在のJavaのバージョンを表示してみたら
$ java -version openjdk version "1.8.0_151" OpenJDK Runtime Environment (build 1.8.0_151-8u151-b12-1~deb9u1-b12) OpenJDK 64-Bit Server VM (build 25.151-b12, mixed mode) $ javac -version bash: javac: コマンドが見つかりません
javacがなかった。
なので、default-jreとdefault-jdkをインストールしてみる。
$ sudo apt install default-jre $ sudo apt install default-jdk $ java -version openjdk version "1.8.0_151" OpenJDK Runtime Environment (build 1.8.0_151-8u151-b12-1~deb9u1-b12) OpenJDK 64-Bit Server VM (build 25.151-b12, mixed mode) $ javac -version javac 1.8.0_151
入りました。
実行
例えば、「sosu00.java」というファイルの場合、
ファイルをVimで開いて、コマンドモードに入って以下のコードを実行する。
:!javac %; java sosu00
素数
・1より大きい自然数で、正の約数が1と自分自身のみである数。
import java.util.stream.Stream; import java.util.stream.IntStream; import java.util.stream.Collectors; import java.util.List; public class sosu01{ private static List<Integer> sosu(List<Integer> b, int i){ int m = b.get(i); if (m > Math.sqrt(b.get(b.size()-1))) return b; return sosu(b.stream().filter(v -> (v%m!=0) || (v==m) ) .collect(Collectors.toList()), ++i); } private static void disp(List<Integer> a){ a.forEach(b->System.out.print(b+" ")); System.out.println(); } public static void main(String[] args){ List<Integer> a = IntStream.range(2,100) // 100未満の素数を表示 .boxed().collect(Collectors.toList()); disp(sosu(a, 0)); } }
2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97
双子素数
・双子素数:差が2である2つの素数の組
・いとこ素数:差が4である2つの素数の組
・セクシー素数:差が6である2つの素数の組
import java.util.stream.Stream; import java.util.stream.IntStream; import java.util.ArrayList; import java.util.List; public class twin02{ private static Boolean chk(int a){ return IntStream.range(2,a).filter(v -> a%v==0).count() == 0; } private static List<int[]> loop(List<int[]> a, int f, int c, int i){ if (c<1) return a; if (chk(i) && chk(i+f)){ int[] b = {i, i+f}; a.add(b); --c; } return loop(a, f, c, i+1); } private static List<int[]> twin(int f, int c){ List<int[]> p = new ArrayList<int[]>(); return loop(p, f, c, 2); } private static void disp(List<int[]> a){ a.forEach(b->System.out.print("("+b[0]+","+b[1]+") ")); System.out.println(); } public static void main(String[] args){ disp(twin(2,10)); // 双子素数を10組表示 disp(twin(4,10)); // いとこ素数を10組表示 disp(twin(6,10)); // セクシー素数を10組表示 } }
(3,5) (5,7) (11,13) (17,19) (29,31) (41,43) (59,61) (71,73) (101,103) (107,109) (3,7) (7,11) (13,17) (19,23) (37,41) (43,47) (67,71) (79,83) (97,101) (103,107) (5,11) (7,13) (11,17) (13,19) (17,23) (23,29) (31,37) (37,43) (41,47) (47,53)
幸運数
・ポーランドの数学者スタニスワフ・ウラムによって提案された数列。
・素数の性質を研究するために、素数に似たルールで導き出せる数列を考案したとのこと。
import java.util.stream.IntStream; import java.util.stream.Collectors; import java.util.List; public class lucky00{ private static List<Integer> luc(List<Integer> a, int i){ a.add(0,0); int s = a.get(i); int l = a.size(); if (s<=l) { List<Integer> m = IntStream.range(0,l).filter(v->v%s!=0) .map(v->a.get(v)).boxed().collect(Collectors.toList()); return luc(m,i+1); } a.remove(0); return a; } private static void disp(List<Integer> a){ a.forEach(b->System.out.print(b+" ")); System.out.println(); } public static void main(String[] args){ List<Integer> a = IntStream.range(0,100).filter(v->v%2!=0) .boxed().collect(Collectors.toList()); disp(luc(a,2)); } }
1 3 7 9 13 15 21 25 31 33 37 43 49 51 63 67 69 73 75 79 87 93 99
階乗
・1 から n までのすべての整数の積。
import java.util.stream.IntStream; public class fact00{ private static void disp(IntStream a){ a.forEach(b->System.out.print(b+" ")); System.out.println(); } public static void main(String[] args){ IntStream a = IntStream.range(0,10).map(v->{ // 階乗を10個表示 return IntStream.range(1,v+1).reduce(1,(i,j)->i*j); }); disp(a); } }
1 1 2 6 24 120 720 5040 40320 362880
フィボナッチ数
・フィボナッチ数:イタリアの数学者レオナルド・フィボナッチにちなんで名付けられた数
・リュカ数:フランスの数学者エドゥアール・リュカにちなんで名付けられた数
import java.util.stream.IntStream; public class fibo00{ private static int loop(int a, int b, int c){ if (c==0) return a; if (c==1) return b; return loop(a,b,c-2)+loop(a,b,c-1); } private static IntStream fibo(int a, int b, int c){ return IntStream.range(0,c).map(v->loop(a,b,v)); } private static void disp(IntStream a){ a.forEach(b->System.out.print(b+" ")); System.out.println(); } public static void main(String[] args){ disp(fibo(0,1,10)); // フィボナッチ数を10個表示 disp(fibo(2,1,10)); // リュカ数を10個表示 } }
0 1 1 2 3 5 8 13 21 34 2 1 3 4 7 11 18 29 47 76
パスカルの三角形
・二項展開における係数を三角形状に並べたもの。
import java.util.stream.IntStream; import java.util.stream.Collectors; import java.util.List; import java.util.ArrayList; import java.util.Arrays; public class pas00{ private static List<Integer> pas(int a){ if (a==0) return new ArrayList<Integer>(Arrays.asList(1)); List<Integer> b = pas(a-1); b.add(0,0); b.add(b.size(),0); return IntStream.range(1,b.size()).map(v->b.get(v-1)+b.get(v)) .boxed().collect(Collectors.toList()); } private static void disp(List<Integer> a){ a.forEach(b->System.out.print(b+" ")); System.out.println(); } public static void main(String[] args){ IntStream.range(0,10).forEach(v->disp(pas(v))); // パスカルの三角形を10段表示 } }
1 1 1 1 2 1 1 3 3 1 1 4 6 4 1 1 5 10 10 5 1 1 6 15 20 15 6 1 1 7 21 35 35 21 7 1 1 8 28 56 70 56 28 8 1 1 9 36 84 126 126 84 36 9 1
最後に
以上、Javaを使っていくつかの数列を表示させてみました。
もっとソースを短く、わかりやすくできるはず。
Stream APIを勉強して書き直すかも。
というわけで、今回はこれにて。