1.00 はじめに
文字列の出力
PHP7(7.0.15)でAtCorderを解く場合、文字列の出力に改行も必要であるため、以下のコードでは、「WA」となる。
<?php
echo "Hello, world!";
?>
「AC」にするには、\nを入れる。
<?php
echo "Hello, world!\n";
?>
1.01 出力とコメント
出力 echo "(出力したいこと)";
コメント 文頭に#、// もしくは、コメントしたい範囲を/* */で囲む。
EX.1
<?php
#hoge
//hoge
/*
hoge
*/
echo "こんにちは\n";
echo "AtCoder\n";
?>
1.02 プログラムの書き方とエラー
コンパイルエラー : 文法のエラー。プログラムは実行されない。
実行時エラー : 内容のエラー。プログラムは強制終了される。
論理エラー : プログラムは正しく動いているように見えてしまう。
エラーの直し方
行してエラーや出力を確認→プログラムを修正→実行してエラーや出力を確認→... を繰り返す。
Ex.2
<?php
echo "いつも2525\n";
echo "AtCoderくん\n";
?>
1.03 四則演算と優先順位
四則演算
| 演算子 | 計算内容 |
|---|---|
+ |
足し算 |
- |
引き算 |
* |
掛け算 |
/ |
割り算 |
% |
割った余り |
演算子の優先順位
| 優先順位 | 高い | 低い |
|---|---|---|
| 演算子 | * / % |
+``````- |
注意
割り算はできるだけ後ろの方で行うようにしたほうが正しい結果になる。
3 / 0や3 % 0のように0で割ることはできない。(実行時エラー)
0 / 3や0 % 3のように割られる数が0の場合は問題なく計算できる。
Ex.3
<?php
echo (100*(100+1))/2;
echo "\n";
?>
1.04 変数と型
| 型 | |
|---|---|
| boolean | 論理型 |
| integer | 整数 |
| float(または、double) | 浮動小数点数 |
| string | 文字列 |
| array | 配列 |
| resource | リソース |
| NULL | ヌル型 |
宣言
$name
代入
$name = 10
読み込み
echo $name; //10
echo $name + 2; //10 + 2 → 12
echo $name * 3; //10 * 3 → 30
Ex.4
<?php
$seconds = 365 * 24 * 60 * 60;
echo $seconds;
echo "\n";
echo $seconds * 2;
echo "\n";
echo $seconds * 5;
echo "\n";
echo $seconds * 10;
echo "\n";
?>
1.05 実行順序と入力
入力
入力例
1 2 3
fgets()
$line = fgets(STDIN);
echo $line; //1 2 3
fscanf()
fscanf(STDIN, "%d %d %d", $a, $b, $c);
echo $a; //1
echo $b; //2
echo $c; //3
Ex.5
<?php
fscanf(STDIN,"%d %d", $a, $b);
echo $a + $b;
echo "\n";
?>
1.06 if文・比較演算子・論理演算子
if文
if文を使うと「ある条件が正しい時だけ処理をする」というプログラムが書ける
else句を使うと「条件式が正しくなかった時」の処理を書ける
比較演算子
| 演算子 | 意味 |
|---|---|
x == y |
xとyは等しい |
x != y |
xとyは等しくない |
x > y |
xはyより大きい |
x < y |
xはyより小さい |
x >= y |
xはy以上 |
x <= y |
xはy以下 |
論理演算子
| 演算子 | 意味 | 真になる時 |
|---|---|---|
!(条件式) |
条件式の結果の反転 | 条件式が偽 |
条件式1 && 条件式2 |
条件式1が真かつ条件式2が真 | 条件式1と条件式2のどちらも真 |
条件式1||条件式2 |
条件式1が真または条件式2が真 | 条件式1と条件式2の少なくとも片方が真 |
Ex.6
floor関数
floor(数値)
float型の小数点以下の切り捨て。
<?php
fscanf(STDIN,"%d %s %d", $a, $op, $b);
if ($op == "+") {
echo $a + $b;
} else if ($op == "-") {
echo $a - $b;
} else if ($op == "*") {
echo $a * $b;
} else if ($op == "/" && $b != 0) {
echo floor($a / $b);
} else {
echo "error";
}
echo "\n";
?>
ceil関数
ceil(数値)
float型の小数点以下の切り上げ。
round関数
round(数値[,桁数])
float型の任意の桁数以下を四捨五入。
桁数を指定しなければ、小数点以下を四捨五入。
1.07 条件式の結果とbool型
条件式の結果
条件式の「計算結果」が真の時は1を返し、偽の時は何も返さない。
<?php
echo 5 == 5;
echo "\n";
echo 5 > 10;
echo "\n";
echo 5 < 10;
echo "\n";
?>
標準出力⬇️
1
1
条件式の部分に直接0や1を書ける。
<?php
if (1) { //true でも可
echo "hello";
}
if (0) { //false でも可
echo "world!";
}
echo "\n";
?>
標準出力⬇️
hello
Ex.7
<?php
// 変数$a,$b,$cにtrueまたはfalseを代入してAtCoderと出力されるようにする。
$a = true;
$b = false;
$c = true;
// ここから先は変更しないこと
#phpに対応するように変更します。
if ($a) {
echo "At";
}
else {
echo "Yo";
}
if (!$a && $b) {
echo "Bo";
}
else if (!$b || $c) {
echo "Co";
}
if ($a && $b && $c) {
echo "foo!";
}
else if (true && false) {
echo "yeah!";
}
else if (!$a || $c) {
echo "der";
}
echo "\n";
?>
1.08 変数のスコープ
-
{ }で囲われた部分のところをブロックという - 変数が使える範囲のことをスコープという
- 変数のスコープは「変数が宣言されてからそのブロックが終わるまで
- スコープが重なっている場合は最も内側のブロックで宣言された変数が選ばれる
Ex.8
<?php
fscanf(STDIN,"%d", $p);
if ($p == 1) {
fscanf(STDIN,"%d", $price);
}
if ($p == 2) {
fscanf(STDIN,"%s", $text);
fscanf(STDIN,"%d", $price);
echo $text."!\n";
}
fscanf(STDIN,"%d", $N);
echo $price * $N;
echo "\n";
?>
1.09 複合代入演算子
x = x + (1 + 2)とx += 1 + 2は、一緒の意味。
他にも-=、*=、/=、%=がある。
x = x + 1はx++または++xと書くことができる。
「1増やす操作」をインクリメントと言う。
x = x - 1はx--または--xと書くことができる。
「1減らす操作」をデクリメントと言う。
プログラムを短く書くための記法をシンタックスシュガーと言う。
Ex.9
<?php
fscanf(STDIN,"%d %d %d", $x, $a, $b);
$x++;
echo $x."\n";
$x *= $a + $b;
echo $x."\n";
$x *= $x;
echo $x."\n";
$x--;
echo $x."\n";
?>
1.10 while文
- while文を使うと繰り返し処理ができる
- 条件式が真の時処理を繰り返す
ループする回数を指定する場合、カウンタ変数をインクリメントもしくはデクリメントして、条件式が偽になるようにする必要がある。
Ex.10
<?php
fscanf(STDIN,"%d %d", $A, $B);
$count = 0;
echo "A:";
while ($count < $A) {
echo "]";
$count++;
}
echo "\n";
$count = 0;
echo "B:";
while ($count < $B) {
echo "]";
$count++;
}
echo "\n";
?>
1.11 for文・break・continue
for文は、「初期化」→「条件式」→「処理」→「更新」→「条件式」→「処理」→...という順で実行され、条件式が真のとき繰り返し続ける。
for (初期化; 条件式; 更新) {
処理
}
breakを使うとループを途中で抜けられる。
continueを使うと後の処理を飛ばして次のループへ行ける。
Ex.11
マイナスの値を切り捨てる時
floor関数は、値が小さくなる方向で小数点を切り捨てるため、floor(-2.3)は-3と返される。
引数がマイナスの値の場合、整数にキャストした時と結果が異なる。
floor(-2.9) → -3
(int)-2.9 → -2
<?php
fscanf(STDIN,"%d", $N);
fscanf(STDIN,"%d", $A);
for ($i=1; $i<=$N; $i++) {
fscanf(STDIN,"%s %d", $op, $B);
if ($op == "+") {
$A += $B;
echo "{$i}:{$A}"."\n";
} else if ($op == "-") {
$A -= $B;
echo "{$i}:{$A}"."\n";
} else if ($op == "*") {
$A *= $B;
echo "{$i}:{$A}"."\n";
} else if ($op == "/" && $B != 0) {
$A /= $B;
$A = (int)$A;
echo "{$i}:{$A}"."\n";
} else {
echo "error\n";
break;
}
}
?>
1.12 文字列と文字
$str = 'abc'とすると、
strlen($str)でstringのバイト数(ここでは3)を返す。
$str[i]でi文字目にアクセスできる。iは添え字といい、0から始まる。
Ex.12
<?php
fscanf(STDIN,"%s", $S);
$len = strlen($S);
$a = 1;
for ($i=1; $i<$len; $i++) {
if ($i % 2 == 1) {
$op = $S[$i];
} else {
if ($op == "-") {
$a -= 1;
} else {
$a += 1;
}
}
}
echo $a."\n";
?>
1.13配列
array()で配列を作ることができる。
<?php
$array = array(
"foo" => "bar",
"bar" => "foo",
);
// PHP 5.4 以降ではこのようにも書けます
$array = [
"foo" => "bar",
"bar" => "foo",
];
?>
<?php
$array = array("foo", "bar", "hello", "world");
?>
$array[i]でi番目の要素へアクセスできる。
count[$array]で配列の要素数を取得できる。
Ex.13
explode()
文字列を区切り文字で分割した結果を配列として返す。
$line = fgets(STDIN);
// 半角スペースを区切りとして、配列に格納
$arr = explode(" ", $line);
echo $arr[0]; // 1
echo $arr[1]; // 2
echo $arr[2]; // 3
array_sum()
配列の合計値を返す。
abs()
絶対値を返す。
<?php
$N = fgets(STDIN);
$line = fgets(STDIN);
$arr = explode(" ", $line);
$mean = array_sum($arr)/$N;
for ($i=0; $i<$N; $i++) {
echo abs((int)$mean-$arr[$i])."\n";
}
?>
1.14 STLの関数
min関数
min(a, b)
aとbの2つの引数のうち、小さい方の値が取得できる。
max関数
max(a, b)
aとbの2つの引数のうち、大きい方の値が取得できる。
swap関数
swap(a, b)
aとbの2つの引数の値を交換する。
array_reverse関数
array_reverse($array)
配列の要素の並びを逆にする。
sort関数
asort($array)
配列の要素を小さい順に並び替えられる。
arsort($array)
配列の要素を大きい順に並び替えられる。
Ex.14
<?php
fscanf(STDIN,"%d %d %d", $arr[0], $arr[1], $arr[2]);
echo max($arr) - min($arr)."\n";
?>
1.15 関数
<?php
function foo($arg_1, $arg_2, /* ..., */ $arg_n)
{
echo "関数の例\n";
return $retval; //戻り値
}
foo(); //実行
?>
Ex.15
<?php
function output($sum_a, $sum_b, $sum_c){
echo $sum_a * $sum_b * $sum_c."\n";
}
function input(){
$line = fgets(STDIN);
$arr = explode(" ", $line);
return $arr;
}
function main(){
$N = fgets(STDIN);
$A = input();
$B = input();
$C = input();
$sum_A = array_sum($A);
$sum_B = array_sum($B);
$sum_C = array_sum($C);
output($sum_A, $sum_B, $sum_C);
}
main();
?>