- 投稿日:2019-04-15T20:16:20+09:00
JAVA_HOMEとPath
JAVA_HOMEとPath
windowsでJavaのインストールをしないといけない時にネックになってくるのが環境変数。
環境変数とは
Javaとかにはバージョンごとにフォルダにその情報とかが入っている。
そこまでの階層/Library/Java/JavaVirtualachine/jdk{バージョン}/
をさすのはめんどくさいから、JAVA_HOMEとかPathという環境変数に入れて楽に扱おうというもの。よく「Pathが通らない〜」というのは環境変数の中身が間違っていて目的の階層にいけない事
JAVA_HOMEとPathの違い
どちらも環境変数である。
ただ、アプリケーションによってJAVA_HOME
でJavaの情報を取得したりPath
でJavaの情報を取得したりするので両方設定しておくといい。以下設定情報。
なおJDK(Java)はC:¥Program Files¥Java¥jdk1.8.0_101
にインストールされてるとします。
詳しい設定方法はこちら。JAVA_HOME
JAVA_HOME = C:¥Program Files¥Java¥jdk1.8.0_101JDKがインストールされているディレクトリを指定する
Path
Path = C:¥Program Files¥Java¥jdk1.8.0_101¥binJavaのソースコードをコンパイルしたり実行したりするファイルが
¥bin
以下に入っているのでそこを指定。参考にさせていただいた記事
ありがとうございました。
ちゃんとできてる?Javaの環境変数の設定方法
PATHの設定及び環境変数JAVA_HOMEの設定
JAVA_HOMEについて
- 投稿日:2019-04-15T17:51:37+09:00
java kotlin IntとIntの除算(割り算)にご注意
なんでこんな簡単なことにハマったのでしょう?
私と同じようにハマって時間を無駄にする方がいないように備忘録下記は当然の如く0.25と出ると思っていましたが...
var rate: Double = 0.0 rate = 1 / 4 Log.v("TEST:", "rate:${rate}")下記のようなコンパイルエラーがでる。
Type mismatch: inferred type is Int but Double was expectedgoogle翻訳様:「型が一致しません:推定型はIntですがDoubleが必要です」
そんなことわかっておるワイ!!!
ん? あっ Σ(゚д゚;) ,,,, そういう事か。
IntとIntの計算なので計算結果の型の判定がIntになっていたんですね...
俺よ、なぜ気づかなかった。。。ということで解決策。どっちか、もしくは両方をDoubleに合わせてやればよい。
val num1 = 1.toDouble() val num2 = 4.toDouble() val aaa = num1 / num2 Log.v("TEST:", "rate = ${aaa}")V/TEST:: rate = 0.25はい。想定どおりの結果が返ってきました。
自分の頭の悪さに涙が止まらんです。補足
ちなみに...
val aaa = (1/4).toDouble() Log.v("TEST:", "rate = ${aaa}")V/TEST:: rate = 0.0こうすると 計算結果がIntで来てそれをDoubleに変換しているみたいになるから
想定する結果が返ってきません。
10 / 4
とかだと2.0
になるから注意。では、よい kotlin 生活を!
- 投稿日:2019-04-15T02:07:48+09:00
AtCoder に登録したら解くべき精選過去問 10 問を Java,StreamAPIで解いてみた
はじめに
AtCoder に登録したら次にやること ~ これだけ解けば十分闘える!過去問精選 10 問 ~ で紹介されていた10問をJava8, StreamAPIを使って解いた。
AtCoder Beginners Selectionはこちら
StreamAPIの勉強のためにやったのでマサカリを糧にしたい。前提
- パフォーマンスはとりあえず無視するが、入力は
BufferedReader
で受け取る- できるだけ手続き的な書き方を避ける
ABC086A Product
import java.io.BufferedReader; import java.io.InputStreamReader; import java.util.Arrays; class Main { public static void main(String[] args) throws java.lang.Exception { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); String input = br.readLine(); System.out.println( Arrays.stream(input.split(" ")) .mapToInt(Integer::parseInt) .reduce(1,(x, y) -> x * y % 2) != 0 ? "Odd":"Even" ); } }ABC081A Placing Marbles
import java.io.BufferedReader; import java.io.InputStreamReader; import java.util.Arrays; class Main { public static void main(String[] args) throws java.lang.Exception { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); String input = br.readLine(); System.out.println( Arrays.stream(input.split("")) .filter(i -> i.equals("1")) .count() ); } }ABC081B Shift only
import java.io.BufferedReader; import java.io.InputStreamReader; import java.util.Arrays; class Main { public static void main(String[] args) throws java.lang.Exception { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); String input = br.readLine(); int[] intArray = Arrays.stream(br.readLine().split(" ")).mapToInt(Integer::parseInt).toArray(); for(int count = 0; ; count++) { if(Arrays.stream(intArray).allMatch(i -> i % 2 == 0)) { intArray = Arrays.stream(intArray).map(i -> i / 2).toArray(); } else { System.out.println(count); break; } } } }
BufferedReader
を使う都合で、行で受け取って配列に分割してStreamに変換するのがやりやすかったからinput
を受け取っても使わないABC087B Coins
import java.io.BufferedReader; import java.io.InputStreamReader; import java.util.stream.IntStream; class Main { public static void main(String[] args) throws java.lang.Exception { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); int A = Integer.parseInt(br.readLine()); int B = Integer.parseInt(br.readLine()); int C = Integer.parseInt(br.readLine()); int X = Integer.parseInt(br.readLine()); final long count = IntStream.rangeClosed(0, A).map(i -> i * 500) .flatMap(i -> IntStream.rangeClosed(0, B).map(j -> i + 100 * j)) .flatMap(i -> IntStream.rangeClosed(0, C).map(j -> i + 50 * j)) .filter(i -> i == X) .count(); System.out.println(count); } }ABC083B Some Sums
import java.io.BufferedReader; import java.io.InputStreamReader; import java.util.Arrays; import java.util.stream.IntStream; import java.util.stream.Stream; class Main { public static void main(String args[]) throws java.lang.Exception { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); int[] nab = Arrays.stream(br.readLine().split(" ")).mapToInt(Integer::parseInt).toArray(); final long count = IntStream.rangeClosed(1, nab[0]).filter(num -> { int sum = Arrays.stream(String.valueOf(num).split("")).mapToInt(Integer::parseInt).sum(); return sum >= nab[1] && sum <= nab[2]; }) .sum(); System.out.println(count); } }ABC088B Card Game for Two
import java.io.BufferedReader; import java.io.InputStreamReader; import java.util.Comparator; import java.util.List; import java.util.stream.Collectors; import java.util.stream.IntStream; import java.util.stream.Stream; class Main { public static void main(String[] args) throws java.lang.Exception { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); br.readLine(); List<Integer> list = Stream.of(br.readLine().split(" ")) .map(Integer::parseInt) .sorted(Comparator.reverseOrder()) .collect(Collectors.toList()); int alice = IntStream.range(0, list.size()) .filter(i -> i % 2 == 0) .mapToObj(i -> list.get(i)) .mapToInt(Integer::intValue) .sum(); int bob = IntStream.range(0, list.size()) .filter(i -> i % 2 == 1) .mapToObj(i -> list.get(i)) .mapToInt(Integer::intValue) .sum(); System.out.println(alice - bob); } }ShiftOnlyと同じ理由で、
input
を使わないABC085B Kagami Mochi
import java.io.BufferedReader; import java.io.InputStreamReader; import java.util.stream.Collectors; class Main { public static void main(String[] args) throws java.lang.Exception { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); int N = Integer.parseInt(br.readLine()); long count = br.lines().limit(N).collect(Collectors.toList()).stream().distinct().count(); System.out.println(count); } }ABC085C Otoshidama
import java.io.BufferedReader; import java.io.InputStreamReader; import java.util.Arrays; import java.util.stream.IntStream; class Main { public static void main(String[] args) throws java.lang.Exception { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); int[] intArray = Arrays.stream(br.readLine().split(" ")).mapToInt(Integer::parseInt).toArray(); int n = intArray[0]; int y = intArray[1]; IntStream.rangeClosed(0, n).forEach(ichiman -> { IntStream.rangeClosed(0, n -ichiman).forEach(gosen -> { int senen = n -ichiman -gosen; if(10000 *ichiman + 5000 *gosen + 1000 *senen == y) { System.out.println(ichiman +" " +gosen +" " +senen); System.exit(0); } }); }); System.out.println("-1 -1 -1"); } }ABC049C 白昼夢 / Daydream
import java.io.BufferedReader; import java.io.InputStreamReader; import java.util.stream.Stream; class Main { public static void main(String[] args) throws java.lang.Exception { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); String S = br.readLine(); long count = Stream.of(S).map(i -> i.replaceAll("eraser", "x")) .map(i -> i.replaceAll("erase", "x")) .map(i -> i.replaceAll("dreamer", "x")) .map(i -> i.replaceAll("dream", "x")) .map(i -> i.replaceAll("x", "")) .filter(i -> i.equals("")) .count(); System.out.println(count > 0 ? "YES" : "NO"); } }ABC086C Traveling
これ、使い所あるんですかね..
import java.io.BufferedReader; import java.io.InputStreamReader; import java.util.ArrayList; import java.util.List; import java.util.stream.Collectors; import java.util.stream.Stream; public class Main { public static void main(String[] args) throws java.lang.Exception { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); int n = Integer.parseInt(br.readLine()); List<List<Integer>> plans = new ArrayList<>(); for (int i = 0; i < n; i++) { List<Integer> plan = Stream.of(br.readLine().split(" ")).map(Integer::parseInt).collect(Collectors.toList()); plans.add(plan); } int diff = 0; int nextX = 0; int nextY = 0; for (List<Integer> plan: plans) { diff = plan.get(0) - diff; nextX = plan.get(1) - nextX; nextY = plan.get(2) - nextY; int dist = Math.abs(nextX) + Math.abs(nextY); if (diff < dist) { System.out.println("No"); return; } else { if ((diff - dist) % 2 != 0) { System.out.println("No"); return; } } } System.out.println("Yes"); } }
- 投稿日:2019-04-15T00:21:40+09:00
ビット演算の高速化メモ
はじめに
元ネタはハッカーのたのしみ(原題:Hacker's Delight)です。
ビットマップのループ
01011000 ↓ f(00001000) f(00010000) f(01000000)右から走査して1のときだけ処理を行いたいとき、
ビットの長さ分ループしなくても1の数のループで済ませられる。for (int x = 0b01011000; x > 0; x &= x - 1) { f(x & -x); }このように
x & -x
とx &= x - 1
を繰り返せば、1の部分だけ渡り歩くことができる。x & -x
01011000
= x
10100111
= not(x)
10101000
= not(x)+1 = -x
つまり
00001000
= x & -x
となって、右端の1だけが残る。x & x-1
01011000
= x
01010111
= x-1
つまり
01010000
= x & x-1
となって、右端の1が消える。ビットカウント
00101110 10100000 11100101 11001011 ↓ 161の数を数えたいとき、
ビットの数だけループしなくてもlog(ビット数)回のビット演算で求められる。x = 0b00101110101000001110010111001011; x = (x & 0x55555555) + ((x >>> 1) & 0x55555555) x = (x & 0x33333333) + ((x >>> 2) & 0x33333333) x = (x & 0x0F0F0F0F) + ((x >>> 4) & 0x0F0F0F0F) x = (x & 0x00FF00FF) + ((x >>> 8) & 0x00FF00FF) x = (x & 0x0000FFFF) + ((x >>> 16) & 0x0000FFFF)やっていることは、部分和をx自身に書き込んでいく分割統治。
手順
代入1回目
データを2ビットずつに区切り、2ビットごとの1の数を求めてxを上書きする。
00 10 11 10 10 10 00 00 11 10 01 01 11 00 10 11
= x
↓
_0 _1 _2 _1 _1 _1 _0 _0 _2 _1 _1 _1 _2 _0 _1 _2
(10進表現)
↓
00 01 10 01 01 01 00 00 10 01 01 01 10 00 01 10
= 新しいx
00 10 11 10 10 10 00 00 11 10 01 01 11 00 10 11
= x
_0 _0 _1 _0 _0 _0 _0 _0 _1 _0 _1 _1 _1 _0 _0 _1
= x & 0x55555555
_0 _1 _1 _1 _1 _1 _0 _0 _1 _1 _0 _0 _1 _0 _1 _1
= ((x >>> 1) & 0x55555555)
2ビットで分けたときの上の桁、下の桁を同時に足し合わせる
00 01 10 01 01 01 00 00 10 01 01 01 10 00 01 10
= (x & 0x55555555) + ((x >>> 1) & 0x55555555)
やっていることは、2ビットのベクトル演算。代入2回目
データを4ビットずつに区切り、4ビットごとの1の数を求めてxを上書きする。
0001 1001 0101 0000 1001 0101 1000 0110
= x
↓
_0_1 _2_1 _1_1 _0_0 _2_1 _1_1 _2_0 _1_2
(10進表現)
↓
___1 ___3 ___2 ___0 ___3 ___2 ___2 ___3
(10進表現)
↓
0001 0011 0010 0000 0011 0010 0010 0011
= 新しいx
0001 1001 0101 0000 1001 0101 1000 0110
= x
__01 __01 __01 __00 __01 __01 __00 __10
= x & 0x33333333
__00 __10 __01 __00 __10 __01 __10 __01
= (x >>> 1) & 0x33333333
4ビットで分けたときの上の2ビット、下の2ビットを同時に足し合わせる
0001 0011 0010 0000 0011 0010 0010 0011
= (x & 0x33333333) + ((x >>> 2) & 0x33333333)
やっていることは、4ビットのベクトル演算。代入3回目
データを8ビットずつに区切り、8ビットごとの1の数を求めてxを上書きする。
00010011 00100000 00110010 00100011
= x
↓
___1___3 ___2___0 ___3___2 ___2___3
(10進表現)
↓
_______4 _______2 _______5 _______5
(10進表現)
↓
00000100 00000010 00000101 00000101
= 新しいx代入4回目
データを16ビットずつに区切り、16ビットごとの1の数を求めてxを上書きする。
0000010000000010 0000010100000101
= x
↓
_______4_______2 _______5_______5
(10進表現)
↓
_______________6 ______________10
(10進表現)
↓
0000000000000110 0000000000001010
= 新しいx代入5回目
データ全体の1の数を求めて、xに上書きする。
0000000000000110 0000000000001010
= 新しいx
↓
_______________6 ______________10
(10進表現)
↓
_______________________________16
(10進表現)
↓
0000000000000000 0000000000010000
= 新しいx
↓
16ちなみに
標準ライブラリで実装されていたりします。JavaとGoの例しか知りませんが、
Java : Integer.bitCount()、Long.bitCount()
Go : bitsパッケージのOnesCountXX()
(上記のコードよりも最適化されている)。さらに言うと、10年前ぐらいからCPUの拡張命令(IntelであればSSE4.2のPOPCNT)としても実装されているので、
そもそも本気で高速化するなら直接POPCNTを呼べる言語を利用すべきです。Javaに関してはJITがbitCount()をPOPCNTに置き換えてくれるらしいですが、
Goはどうなんでしょうか?参考
wikipedia : SSE4、ハミング重み
https://en.wikipedia.org/wiki/SSE4
https://en.wikipedia.org/wiki/Hamming_weightopenjdk8のLongクラス(ソースコード)
https://hg.openjdk.java.net/jdk8/jdk8/jdk/file/687fd7c7986d/src/share/classes/java/lang/Long.javaGoのbitsパッケージ(ソースコード)
https://golang.org/src/math/bits/bits.go?s=3946:3972#L103ビットリバース
00101110 10100000 11100101 11001011 ↓ 11010011 10100111 00000101 01110100ビットを逆順にしたいときも分割統治が使える。
x = 0b00101110101000001110010111001011; x = (x & 0x0000FFFF) << 16 | (x & 0xFFFF0000) >>> 16; x = (x & 0x00FF00FF) << 8 | (x & 0xFF00FF00) >>> 8; x = (x & 0x0F0F0F0F) << 4 | (x & 0xF0F0F0F0) >>> 4; x = (x & 0x33333333) << 2 | (x & 0xCCCCCCCC) >>> 2; x = (x & 0x55555555) << 1 | (x & 0xAAAAAAAA) >>> 1;手順
代入1回目
データを16ビットずつに区切り、入れ替える。
0010111010100000 1110010111001011
= x
↓
1110010111001011 0010111010100000
= 新しいx
0010111010100000 1110010111001011
= x
1110010111001011 ________________
= (x & 0x0000FFFF) << 16
________________ 0010111010100000
= (x & 0xFFFF0000) >>> 16
1110010111001011 0010111010100000
= (x & 0x0000FFFF) << 16 | (x & 0xFFFF0000) >>> 16代入2回目
データを8ビットずつに区切り、隣り合う同士で入れ替える。
11100101 11001011 00101110 10100000
= x
↓
11001011 11100101 10100000 00101110
= 新しいx
11100101 11001011 00101110 10100000
= x
11001011 ________ 10100000 ________
= (x & 0x00FF00FF) << 8
________ 11100101 ________ 00101110
= (x & 0xFF00FF00) >>> 8
11001011 11100101 10100000 00101110
= (x & 0x00FF00FF) << 8 | (x & 0xFF00FF00) >>> 8代入3回目
データを4ビットずつに区切り、隣り合う同士で入れ替える。
1100 1011 1110 0101 1010 0000 0010 1110
= x
↓
1011 1100 0101 1110 0000 1010 1110 0010
= 新しいx代入4回目
データを2ビットずつに区切り、隣り合う同士で入れ替える。
10 11 11 00 01 01 11 10 00 00 10 10 11 10 00 10
= x
↓
11 10 00 11 01 01 10 11 00 00 10 10 10 11 10 00
= 新しいx代入5回目
データを1ビットずつに区切り、隣り合う同士で入れ替える。
1 1 1 0 0 0 1 1 0 1 0 1 1 0 1 1 0 0 0 0 1 0 1 0 1 0 1 1 1 0 0 0
= x
↓
1 1 0 1 0 0 1 1 1 0 1 0 0 1 1 1 0 0 0 0 0 1 0 1 0 1 1 1 0 1 0 0
= 新しいx
11010011101001110000010101110100
= もとのx
00101110101000001110010111001011
= 新しいx
となって、正しく逆順になっている。ちなみに
こちらも標準ライブラリで実装されていることがあります。
Java -> Integer.reverseBytes()、Long.reverseBytes()
Go -> bitsパッケージのReverseXX()
- 投稿日:2019-04-15T00:20:58+09:00
[Android]ShareCompatを使ってシェア(共有)する場合の画像の渡し方、コールバックの受け取り方
↓これの事
わりとたくさん情報がありそうな気がしたが、意外と出てこなかったので、メモ書き。
ライブラリ
- com.android.support:support-compat:28.0.0
実装
SomeActivity.java// アクティビティ内から実行する前提のコード private void showShareChooser() { File tempFile = new File(getApplicationContext().getExternalCacheDir(), tempImgFilePath); // ファイルをシェアするためにURIを取得する場合は、FileProviderを通じて、後述するオーソリティの名前を指定して取得する必要がある Uri uri = FileProvider.getUriForFile(getApplicationContext() , getApplicationContext().getPackageName() + ".provider" , tempFile); ShareCompat.IntentBuilder builder = ShareCompat.IntentBuilder.from(this); builder.setChooserTitle(chooserTitle) // シェアする時のタイトル .setSubject(subject) // 件名。使われ方はシェアされた側のアプリによる .setText(text) // 本文。使われ方はシェアされた側のアプリによる .setStream(uri) // ファイルをシェアする時は、そのURIを指定 .setType("image/jpeg"); // ストリームで指定したファイルのMIMEタイプ // URIに対する読み取り権限を付与する Intent intent = builder.createChooserIntent().addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); // コールバックを受け取りたい場合は、そのインテントを使ってアクティビティを開始する if (intent.resolveActivity(getPackageManager()) != null) { startActivityForResult(intent, SNS_SHARE); } // 結果を受け取らなくても良い場合は、ビルダーからそのまま開始できる // builder.startChooser(); }戻りを受け取る場合は、 通常どおり
onActivityResult
で受け取れる。@Override public void onActivityResult(int requestCode, int resultCode, Intent data) { switch (requestCode) { case SNS_SHARE: // 戻りを受け取って何らか処理する // resultCode は必ずゼロになるので、 RESULT_OK で判定しない doSomething(); break; default: super.onActivityResult(requestCode, resultCode, data); break; } }ファイルを共有する場合
画像などを共有する場合は、Bitmapをそのまま共有したりできないため、一旦ファイルに保存する必要がある。
また、以下のように保存先からの読み出しを許可する必要がある。まず、パスをXMLで指定する。
src/main/res/xml/provider_paths.xml<?xml version="1.0" encoding="utf-8"?> <paths xmlns:android="http://schemas.android.com/apk/res/android"> <external-cache-path name="cache" path="." /> </paths>
external-cache-path
などは保存先に応じて変わる。
英語だけどFileProviderの公式リファレンスを参照。
次に、そのプロバイダをAndroidManifest.xml
で指定する。AndroidManifest.xml<manifest package="com.example" xmlns:android="http://schemas.android.com/apk/res/android"> : <provider android:name="android.support.v4.content.FileProvider" android:authorities="${applicationId}.provider" android:exported="false" android:grantUriPermissions="true"> <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/provider_paths"/> </provider> : </application> : </manifest>参考