Senの競技プログラミング備忘録

こけた問題を自分用の解説で載せる。けんちょんさんのブログを目指したい。質的にも量的にも。こけた問題だけに限定するけど

(競プロメイン)C++erから見たKotlin勉強記録-1 型、基本制御文

テスト環境

Try Kotlin
try.kotlinlang.org
paizaのKotlin環境
paiza.io

Main本体の構造

C++

#include<iostream>

int main(){
	std::cout << "HW" << std::endl;
	式;
	式, 式;
	return 0;
}

Kotlin

fun main(args: Array<String>){
	println("HW")
	式
	式; 式
}

文の終わりの;は不要で、C++でいう','で文と文をつなげるものが';'に相当。

コメント

C++と同じ。次のように書く宗派もある。

/*
	*something
	*hogehoge
	*コメントの先頭に'*'をつけることで明示する
*/

標準入出力

加筆中

変数、定数、値

C++では、

int a = 3;
int b = 4;
a = b;
b = a + b;

Kotlinでは

var message : String = "Hello, Wolrd!"
//var 変数名 : 型名 = 代入する式 で宣言
var num1 = 114514
var num2 : Int = 114514
//代入する式が明確ならば、型明示せずとも、型推論してくれる

num2 = num1 //代入もC++と同じ
num1 = num2 + num1 //式演算も同じ

型指定しないとき、数字ならばInt型に、小数ならDouble型に、文字列ならString型として変数を宣言される。

定数

C++

const int MOD = 1000000007;

Kotlin

val mod = 10007

varの代わりにvalを使う。

基本型

太字のものは重要。

Kotlinでの型 C++に相当する型 サイズ(byte) 取れる値
Byte ? 1  [-2^7+1, 2^7-1]
Short short int 2  [-2^{15}+1, 2^{15}-1]
Int int 4  [-2^{31}+1, 2^{31}-1]
Long long long 8  [-2^{63}+1, 2^{63}-1]
Float float 4
Double double 8 略、上の精度の倍
Char char 8
String std::string, char*
Boolean bool 8

参考資料:
qiita.com

値の型明示

値の型を明示するために、接尾辞(Suffix)を付けられる。

114514 //普通の値 Intとして扱われる
val num1 = 114514 //Int型の変数

114514L //Long型として扱われる値
val num2 = 114514L //Long型の変数

3.1416926 //普通の値 Doubleとして扱われる
val num3 = 3.1415926 // Double型の変数

3.1415926f //Float型として扱われる
val num4 = 3.1415926f // Float型の変数

0b11010110101 // "0b"と接頭辞をつけることで、2進数表記できる
0xd72a //"0x"と接頭辞をつけることで、16進数表記できる。
//4, 8進数はない

また、Kotlinでは、'_'、数値に混ざったアンダーバーを無視するので、好きなように区切りを入れて値をわかりやすくすることも可能

//巨大な数は3桁ごとに100,000,000と','で区切るように、Kotlinは'_'で区切れる。
123456789101112L
123_456_789_101_112L
//もちろんこうしてもよい。
1_234_56_789101_1_2

〇〇Range型

C++にはなかった機能として、Kotlinでは同じ基本型(Int, Doubleとか)で定めた両端を持つ区間という型もある。
型名は○○Range(IntRange, DoubleRange など)、(始点)..(終点)と表す。見ての通り、これは区間

val seg1 : IntRange = 1..10
var b = 2
val c = 15
val seg2 = b..c //このように変数or定数を両端にすることもできる

val seg3 : CharRange = 'a'..'g'
val seg4 : LongRange = 1145141919810..10_000_000_000_000
val seg5 : DoubleRange = 2.71..3.14
//このように、ほかの型から成るRangeも使用できる。

区間に含まれているか?という演算は、"in"で行う。

val heisei : IntRange = 1989..2019
var birth_year = 1998
if(birth_year in heisei)println("平成生まれ")
else println("平成生まれじゃない")

文字列関連

C++と同じ機能

var ch1 : Char = 'c' //文字。C++のように文字コード演算するのなら、'c'.toInt()関数を使うこと
var st1 : String = "abc"//文字列
var st2 = "de"
println(st1+st2)// C++のstd::stringと同じように連結も可能

C++にはない新機能

//文字列内に他 変数or定数 の値を埋め込む printf()の%dのイメージ
//${変数or定数名}
val embed_val = 114514
val embed_var = 1919810
println("俺は今日${embed_val}時間働いたぜ")
println("俺は今日${embed_var}時間働いたぜ")
//このように、{}内で変数or定数の演算、文字列の連結もOK
println("俺は今日${embed_val * 1200}円の給料がもらえるぜ")

//長文
val principal_talk = 
"""
|みなさん。おはようございます。今日は寒い上短縮授業なので、手短に話します。
|みなさん、3日前の夕食の献立を覚えていますか?私のような年に...(中略)
|...というわけです。
|すいません30分経ったみたいですね。では、話を終わりにします。
"""

これはつぎのように表示される。

みなさん。おはようございます。今日は寒い上短縮授業なので、手短に話します。
みなさん、3日前の夕食の献立を覚えていますか?私のような年に...(中略)
...というわけです。
すいません30分経ったみたいですね。では、話を終わりにします

このように、"""~"""で囲まれた文章は改行コード"\n"を使わずとも、見たままの改行になる。
各行の最初にある'|'は、'|'の左にある空白文字列を取り除く意味。そのままだとインデントの空白ぶんまで入るため

Boolean、真偽値、論理演算関連

真のリテラルはtrue, 偽のリテラルはfalse。C++と同じ
C++と同じように、式の評価結果としてのリテラルを代入させる、ことも可能。var x = (56 > 23)

論理演算の演算子も、"||", "&&", '!'とC++と同じ。

型変換

型を無理やり変換するのはas演算子というもの。C++におけるキャストと同じ(なはず)[要出典]

そうではなく、明確に変換するための関数群が用意されていて、これらの利用したほうが安全


下記のように、文字列を含む基本型はみなメンバー関数で変換できる。

val a : Int = 1000000007
a.toString() //文字列に変換
a.toByte() //Byteに変換
a.toShort() //Shortに変換
a.toInt() //Intに変換
a.toLong() //Longに変換
a.toChar() //Charに変換 たぶん無理やり変換だからよくないかも

条件分岐

if文、三項演算子

C++と同じことができる。

if(条件式){//something}
if(条件式2){
	//something
}else if(条件式3){
	//something
}else {
	//something
}

しかし、C++では次のように、簡単に条件に応じて返す値を決める参考演算子があるが、

int Max = a > b ? a : b;

Kotlinには三項演算子は存在しない。大本のJavaにはあるのに。
しかし、if文は式として扱えるので、次のように実質的に三項演算子のように使用できる。

var a = 567236
var b = 54334667
var Max = if(a < b){
    b
}else {
    a
}

//一行でまとめるのならば
var Min = if(a > b){b} else {a}
//文であることを示す{}まで取り除くのならば
Min = if(a > b) b else a
println("Max is ${Max} and Min is ${Min}")

参考文献:
qiita.com

when文

C++でいうとswitch文

int mode = 2;
switch(mode){
	case 1:
		//操作
		break;

	case 2:
		//操作
		break;
	
	default:
		//どれにも該当しないときの操作
}

Kotlinでは

var mode = 1
when(mode){
	1 -> println("一橋大学")
	2 -> println("二松学舎大学")
	3 -> println("三重大学")
	else -> println("他大学")
}

また、if文と同じように、式としても扱えるので、次のように書ける。

var mode = 5
var output = when(mode){
	1 -> "一橋大学"
	2 -> "二松学舎大学"
	3 -> "三重大学"
	else -> "他大学"
} + "の学生です"
println(output)

繰り返し文

for文

上がC++での書き方。
下がKotlinでの書き方。

//増分が+1の一般的なfor文 kotlinではin演算子と区間を使って書く。
for(int i = 0; i < a; i++);
for(i in 0..a-1)
//もちろん区間は〇〇Rangeでも述べた通り、区間の端は変数でも定数でもよい。

//増分が+1出ない場合次のようにする。
//Kotlinではstepを使う必要がある
for(int i = 0; i < a; i += 2);
for(i in 0..a-1 step 2)

//増分が負の場合は、また別の書き方がある
//downToを使用する必要がある。
//始まり downTo 終端(含む) 閉区間のようになる!
for(int i = a-1; i >= 0; i--);
for(i in a-1 downTo 0)
//もちろん、stepと組み合わせて減分を変化させることもできる。
//これは、100から40へ、3ずつ減らす
for(i in 100 downTo 40 step 3)

//C++やJavaで慣れたように、半開区間でfor文を回したい場合、untilを使えばできる。
//これは[0, a)まで回る
for(int i = 0; i < a; i++);
for(i in 0 until a)
//もちろん、stepも使用可能
for(i in 1 until a step 3)

while文

while文もdo-while文も、C++Javaと全く同じである。

break, continue

C++Javaと全く同じ挙動を示す。

参考文献

やさしいKotlin入門 初版 野崎英一

買う場合はこれ、定価2400円+税なのでamazonポチするよりかは書店で買った方がいいと思う。

dogwood008.github.io
公式リファレンス