HHeLiBeXの日記 正道編

日々の記憶の記録とメモ‥

各言語でMap

手元にある各言語で、Map構造を使うプログラムを書いてみようと思ったメモ。

Map構造と言っても、「連想配列」がその言語にあればそれを使う。

要件は以下の通り。

  • 標準入力は、以下のデータから構成される
    • 1行目に、空白区切りのキーワードがいくつか入力される
    • 2行目以降は、1行に空白区切りの文字列が2つ書かれた行が入力される
  • 2行目以降の2つの文字列をkey-valueとしてmapに放り込む
  • 不正入力のチェックは不要とする
  • 標準出力には、1行目で指定されたキーワードに対応する値を改行区切りで出力する

環境

手元にあるものということで、環境は以下のものに限定する。

なお、そもそもが「使ってみようシリーズ」だったことを思い出し、今回はC言語bashにはお休みしてもらうことにした。

入力ファイルの例

  • 001.txt
One Six Two Five
Zero 000
One 111
Two 222
Three 333
Four 444
Five 555
Six 666
Seven 777
Eight 888
Nine 999
Eight 8
Five 5
Four 4
Nine 9
One 1
Seven 7
Six 6
Three 3
Two 2
Zero 0

期待される出力の例

  • 001.txt
1
6
2
5

Java

Javaでは、入力の処理を2パターン書いてみた。

BufferedReader版

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class Main {
    public static void main(String[] args) {
        try (BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
            PrintWriter out = new PrintWriter(System.out)
        ) {
            String buf;

            buf = in.readLine();
            List<String> keywords = Arrays.asList(buf.split(" "));

            Map<String, String> map = new HashMap<>();

            while ((buf = in.readLine()) != null) {
                String[] tokens = buf.split(" ");
                map.put(tokens[0], tokens[1]);
            }

            for (String keyword : keywords) {
                if (map.containsKey(keyword)) {
                    out.println(map.get(keyword));
                } else {
                    out.println("");
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

Scanner版

import java.io.PrintWriter;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        try (Scanner in = new Scanner(System.in);
            PrintWriter out = new PrintWriter(System.out)
        ) {
            String buf = in.nextLine();
            List<String> keywords = Arrays.asList(buf.split(" "));

            Map<String, String> map = new HashMap<>();

            while (in.hasNext()) {
                String key = in.next();
                String value = in.next();
                map.put(key, value);
            }

            for (String keyword : keywords) {
                if (map.containsKey(keyword)) {
                    out.println(map.get(keyword));
                } else {
                    out.println("");
                }
            }
        }
    }
}

C++

#include <iostream>
#include <vector>
#include <map>
#include <string>
#include <sstream>

using namespace std;

int main(int argc, char** argv) {
    // 1行目を読み込んで、空白区切りでリストに放り込む
    string line;
    getline(cin, line);

    stringstream ss(line);

    vector<string> keywords;
    string keyword;
    while (getline(ss, keyword, ' ')) {
        keywords.push_back(keyword);
    }

    // 2行目以降を読み込んで、マップに放り込む
    map<string, string> map;
    string key;
    string value;
    while (cin >> key >> value) {
        map[key] = value;
    }

    // 指定されたキーワードに対応する値を出力する
    for (vector<string>::iterator it = keywords.begin(); it != keywords.end(); ++it) {
        cout << map[*it] << endl;
    }

    return EXIT_SUCCESS;
}

PHP

<?php

$lines = file('php://stdin');

$keywords = split(' ', trim($lines[0]));
array_shift($lines);

$map = array();
foreach ($lines as $line) {
    $line = trim($line);
    $tmp = split(' ', $line);
    $map[$tmp[0]] = $tmp[1];
}

foreach ($keywords as $keyword) {
    if (array_key_exists($keyword, $map)) {
        printf("%s\n", $map[$keyword]);
    } else {
        printf("\n");
    }
}

Python 2

import sys

line = sys.stdin.readline()
keywords = line.split()

map = {}

while True:
    line = sys.stdin.readline()
    if line == '':
        break
    tmp = line.split()
    map[tmp[0]] = tmp[1]

for keyword in keywords:
    if keyword in map:
        print map[keyword]
    else:
        print ""

Python 3

import sys

line = sys.stdin.readline()
keywords = line.split()

map = {}

while True:
    line = sys.stdin.readline()
    if line == '':
        break
    tmp = line.split()
    map[tmp[0]] = tmp[1]

for keyword in keywords:
    if keyword in map:
        print(map[keyword])
    else:
        print("")

Ruby

line = STDIN.gets
keywords = line.split()

map = {}

while line = STDIN.gets
    tmp = line.split()
    map[tmp[0]] = tmp[1]
end

for keyword in keywords
    print map[keyword],"\n"
end

Perl

my $line = readline(STDIN);
chomp($line);
my @keywords = split(/ /, $line);

my %map = ();
while ($line = readline(STDIN)) {
    chomp($line);
    my @tmp = split(/ /, $line);
    $map{@tmp[0]} = @tmp[1];
}

foreach my $keyword(@keywords) {
    print "$map{$keyword}\n";
}

Go

package main

import (
    "bufio"
    "fmt"
    "io"
    "os"
    "strings"
)

func ReadLine(reader *bufio.Reader) (str string, err error) {
    prefix := false
    buf := make([]byte, 0, 1024)
    line := make([]byte, 0, 1)
    for {
        line, prefix, err = reader.ReadLine()
        if err == io.EOF {
            return
        }
        buf = append(buf, line...)
        if prefix {
            continue
        }
        str = string(buf)
        return
    }
}

func main() {
    stdin := bufio.NewReader(os.Stdin)

    line, err := ReadLine(stdin)
    if err == io.EOF {
        panic(err)
    }
    keywords := strings.Split(line, " ")

    aMap := map[string]string{}
    for {
        line, err := ReadLine(stdin)
        if err == io.EOF {
            break
        }
        tmp := strings.Split(line, " ")
        aMap[tmp[0]] = tmp[1]
    }

    for i := 0; i < len(keywords); i += 1 {
        value, exists := aMap[keywords[i]]
        if exists {
            fmt.Println(value)
        } else {
            fmt.Println()
        }
    }
}

ついに、指定されたReaderから1行を読み込む関数を自作した‥