0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

AOJ PG入門 #4

Last updated at Posted at 2025-01-23

問1.2つの整数 a と b を読み込んで、以下の値を計算するプログラムを作成して下さい

  • a ÷ b : d (整数)
  • a ÷ b の余り : r (整数)
  • a ÷ b : f (浮動小数点数)
  • d, r, f を1つの空白で区切って1行に出力して下さい。fについては、0.00001以下の誤差があってもよいものとします。

PHP

AOJ.php
<?php
fscanf(STDIN,"%d %d",$a,$b);
$d = intdiv($a,$b);
$r = $a%$b;
$f = $a/$b;
printf("%d %d %f\n",$d,$r,$f);
?>
  • 整数除算のとき→intvalとintdivは同じ動作だが、intdivの方が明確に整数除算を意図しているため、可読性が向上
  • a / b はデフォルトで浮動小数点数として計算される

Java

AOJ.java
import java.util.Scanner;
public class Main{
    public static void main(String[]args){
      Scanner sc = new Scanner(System.in);
      int a = sc.nextInt();
      int b = sc.nextInt();
      int d = a/b;
      int r = a%b;
      double f = (double)a/b;
      System.out.printf("%d %d %f",d,r,f);
      sc.close();
    }
}

問2.半径 r の円の面積と円周の長さを求めるプログラムを作成して下さい。

面積と円周の長さを1つの空白で区切って1行に出力して下さい。出力は浮動小数点数とし、0.00001 以下の誤差を含んでもよいものとします。

PHP

AOJ.php
<?php
fscanf(STDIN,"%f",$r);
printf("%f %f\n",M_PI*$r*$r,2*M_PI*$r);
?>
  • M_PIはPHPの定義済み定数。πの近似値を返す。

Java

AOJ.java
import java.util.Scanner;
public class Main{
    public static void main(String[]args){
       Scanner sc = new Scanner(System.in);
       double r = sc.nextDouble();
       System.out.printf("%f %f\n",r*r*Math.PI,2*r*Math.PI);
       sc.close();
    }
}

  • 定義済み定数Math.PIは円周率を返す

問3.2つの整数 a, b と1つの演算子 op を読み込んで、a op b を計算するプログラムを作成して下さい。

ただし、演算子 op は、"+"(和)、"-"(差)、"*"(積)、"/"(商)、のみとし、割り算で割り切れない場合は、小数点以下を切り捨てたものを計算結果とします。

  • 入力は複数のデータセットから構成されています。各データセットの形式は以下のとおりです:
    a op b
  • op が '?' のとき 入力の終わりを示します。このケースの出力は行ってはいけません。
  • 各データセットについて、計算結果を1行に出力して下さい。

PHP

AOJ.php
<?php
while($input=fgets(STDIN)){
    list($a,$op,$b) = explode(" ",trim($input));
    $a = (int)$a;
    $b = (int)$b;

   if($op == "?")break;
   switch($op){
       case "+" : $ans = $a + $b;
       break;
       case "-" : $ans = $a - $b;
       break;
       case "/" : $ans = floor($a / $b);
       break;
       case "*" : $ans = $a * $b;
       break;
   }
   echo "$ans\n";
}
?>
  • 演算子は文字列扱い
  • 小数点以下切り捨て→floor関数

今回入力が  a op bのように空白を入れて入力しているので、例えば3 + 5 と入力を受け取れば
trimで文字列の前後の空白(および改行)を削除
→explodeで空白(スペース)を区切り文字として、文字列「3 + 5」を分割
→分割された要素のそれぞれをlist関数でそれぞれの変数に格納

としている。
しかし入力が 3+5のように空白のないものだった場合、explodeは使えないので正規表現で分割する。

example.php
$line = "3+5"; // スペースなし
$line = trim($line); // "3+5"

// 正規表現で演算子を分割
if (preg_match('/(\d+)([+\-*/])(\d+)/', $line, $matches)) {
    $a = (int)$matches[1];
    $op = $matches[2];
    $b = (int)$matches[3];
    
    // 演算の処理(switch文など)
    switch ($op) {
        case '+': $c = $a + $b; break;
        case '-': $c = $a - $b; break;
        case '*': $c = $a * $b; break;
        case '/': $c = floor($a / $b); break;
    }
    echo $c . "\n";
}

  • preg_match() は 正規表現にマッチした部分を $matches 配列に格納する関数。
  • () で囲んだ部分(キャプチャグループ)は、それぞれ $matches[1], $matches[2], ... に格納される。キャプチャグループを使わないとマッチした全体のみ取得。
  • 書式は 
preg_match(パターン, 検索対象の文字列, マッチ結果を格納する配列);

成功すると preg_match() は 1 を返し、配列にその結果が入る。失敗すると 0 を返す。

  • \d+=一個以上の数字(\d=数字、+=一回以上)
  • []=どれかひとつ
    例えば$line = "3+5" の場合、上記の$matches配列の中身は以下のようになる
$matches = [
    0 => "3+5",   // 全体のマッチ部分(入力全体)
    1 => "3",     // 1つ目の `(\d+)` にマッチ(最初の数値)
    2 => "+",     // `([+\-*/])` にマッチ(演算子)
    3 => "5"      // 2つ目の `(\d+)` にマッチ(次の数値)
];

Java

AOJ.java
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        
        while (true) {
            String input = sc.nextLine(); 
            String[] math = input.split(" "); 
            
            if (math[1].equals("?")) break; // "?" ならループ終了
            
            int a = Integer.parseInt(math[0]); 
            int b = Integer.parseInt(math[2]); 
            int ans = 0;
            
            switch (math[1]) {
                case "+": ans = a + b; break;
                case "-": ans = a - b; break;
                case "*": ans = a * b; break;
                case "/": ans = a / b; break; 
            }
            
            System.out.printf("%d%n", ans); 
        }
        
        sc.close();
    }
}
  • split() の引数は 正規表現 なので、 " "(ダブルクォートの空白)
  • Javaでは文字列を比較する際は == ではなく equals() を使う。
  • math[0] や math[2] は String 型 なので、そのまま計算できない。
    →Integer.parseInt() でString型をint 型に変換

別解

other.java
import java.util.Scanner;
     
    /* Name of the class has to be "Main" only if the class is public. */
    class Main{
    	public static void main(String[] args) {
    		Scanner scanner = new Scanner(System.in);
    		while(scanner.hasNext()){          //入力がある間はループ継続
    		 long a = scanner.nextLong();
    		 String str = scanner.next();
    		 long b = scanner.nextLong();
    		 
    		 switch(str) {
    		 case "+":
    			 System.out.println(a+b);
    			 break;
    		 case "-":
    			 System.out.println(a-b);
    			 break;
    		 case "/":
    			 System.out.println(a/b);
    			 break;
    		 case "*":
    			 System.out.println(a*b);
    			 break;
    			 default:
    				 break;
    		 }
    		}
    	}
     // 
    }

  • hasNext関数→次の入力があるかどうかを確認するメソッド。次のトークン (単語) があるなら true を返す。
    入力が終わっていたら false を返す。next() を呼び出す前に使うとエラーを防げる

  • Scanner クラスの next() は、スペースや改行で区切られた次の文字列を取得するメソッド。

  • nextInt() や nextLong() は、空白 (スペース, タブ) や改行を区切りとして、次の数値だけを取得する。
    数値の後に空白 ( ) や改行 (\n) があると、そこで読み取りを終了し、次の入力を待つ。

other2.java
import java.io.*;
import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int a, b;
        
        while (true) {
            a = sc.nextInt();  // 整数aを入力
            String c = sc.next();  // 演算子をStringとして取得
            b = sc.nextInt();  // 整数bを入力
            
            if (c.equals("?")) break;  // 演算子が「?」の場合、ループを終了
            
            // 演算子に応じて計算
            if (c.equals("+")) {
                System.out.println(a + b);
            } else if (c.equals("-")) {
                System.out.println(a - b);
            } else if (c.equals("*")) {
                System.out.println(a * b);
            } else if (c.equals("/")) {
                System.out.println(a / b);
            }
        }
    }
}

問4.n個の整数ai(i=1,2,...n)を入力し、それらの最小値、最大値、合計値を求めるプログラムを作成してください。

  • 1行目に整数の数nが与えられます。2行目にn個の整数aiが空白区切りで与えられます。
  • 最小値、最大値、合計値を空白区切りで1行に出力してください。

PHP

AOJ.php
<?php
 $n = intval(trim(fgets(STDIN)));   
 $a = array_map('intval',explode(" ",(trim(fgets(STDIN)))));
 printf("%d %d %d\n",min($a),max($a),array_sum($a));
?>
  • explodeで文字列の要素から成る配列→array_mapで全要素をintval適用で整数にして整数要素から成る配列にする。

Java

AOJ.java
import java.util.Scanner;
public class Main{
    public static void main(String[]args){
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int[]a = new int[n];
        for(int i = 0;i<n;i++){
            a[i] = sc.nextInt();
        }
        int mi = 1000000;
        int ma = -1000000;
        
        int sum = 0;
        for(int j = 0;j<a.length;j++){
            mi = Math.min(mi,a[j]);
            ma = Math.max(ma,a[j]);
            sum += a[j];
        }
       
        System.out.println(mi + " " + ma + " " + sum);
        sc.close();
    }
}
  • sumの型→intにしたら大きな数の合計で整数オーバーフローエラー。注意!
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?