{ }codelper
部分文字列P0054

何文字目から何文字目まで切り出す

一行目に文字列 s、二行目に質問の数 q が与えられる。
続く q 行に二つの数 a、b が与えられる。
質問ごとに、s の a 文字目から b 文字目まで(両端の文字を含む)を切り出した文字列を一行に出力せよ。
この問題では位置は人が数えるように 1 から数える。
例えば s が "codelper" で a = 1、b = 4 なら "code" である。

入力
s は英小文字と数字、長さ 1〜1,000。
1 ≤ q ≤ 1,000。
1 ≤ a ≤ b ≤ s の長さ
出力
q 行、質問ごとに切り出した文字列
例 1 · stdin
codelper
3
1 4
5 8
3 3
stdout
code
lper
d
main.py
入力(stdin)

実行すると、これらの行が順に input()・標準入力に渡されます(実行中に入力を求めません)。

$ 準備完了

コードを入力して解くにはパソコンで開いてください。モバイルでは問題と解答を見られます。

ほかの言語では?言語別の解答を見る · 8 言語の解答

切り出す関数の二つ目の値の意味が言語ごとに違います。
終わりの位置(その位置は含まない):Python s[a-1:b]、JS・TS s.slice(a - 1, b)、Java s.substring(a - 1, b)。
文字数:C# s.Substring(a - 1, b - a + 1)、C++ s.substr(a - 1, b - a + 1)、Craykon s.切り出す(a - 1, b - a + 1)。
C には切り出す関数がなく、printf("%.*s", b - a + 1, s + a - 1) のように開始ポインタと文字数で出力します。
落とし穴は三つ:① 1 から数えた位置を 0 から数える番号に直さないと(s[a:b])一つずれます。
② Java substring に文字数を、C# Substring に終わりの位置を渡すと、違う文字列になるか範囲外の例外になります。
③ C++ substr は個数が大きすぎてもエラーにならず末尾まで切り出すので、間違いに気づきにくいです(Python のスライスも範囲を超えると黙って切ります)。
JS の substr(開始, 個数) は古い関数なので使わず、substring は二つの値が逆なら入れ替えてくれる点が slice と違います。

Pythonmain.py · 5 行
s = input()q = int(input())for _ in range(q):    a, b = map(int, input().split())    print(s[a - 1:b])
JavaScriptmain.js · 7 行
const [s, q, ...rest] = require("fs").readFileSync(0, "utf8").split("\n").map((x) => x.trim());const out = [];for (let i = 0; i < Number(q); i++) {  const [a, b] = rest[i].split(" ").map(Number);  out.push(s.slice(a - 1, b));}console.log(out.join("\n"));
TypeScriptmain.ts · 8 行
import { readFileSync } from "node:fs";const [s, q, ...rest]: string[] = readFileSync(0, "utf8").split("\n").map((x) => x.trim());const out: string[] = [];for (let i = 0; i < Number(q); i++) {  const [a, b]: number[] = rest[i].split(" ").map(Number);  out.push(s.slice(a - 1, b));}console.log(out.join("\n"));
JavaMain.java · 17 行
import java.io.BufferedReader;import java.io.InputStreamReader; public class Main {    public static void main(String[] args) throws Exception {        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));        String s = br.readLine().trim();        int q = Integer.parseInt(br.readLine().trim());        StringBuilder out = new StringBuilder();        for (int i = 0; i < q; i++) {            String[] p = br.readLine().trim().split(" ");            int a = Integer.parseInt(p[0]), b = Integer.parseInt(p[1]);            out.append(s.substring(a - 1, b)).append('\n');        }        System.out.print(out);    }}
C#Main.cs · 19 行
using System;using System.Text; class Program{    static void Main()    {        string s = Console.ReadLine().Trim();        int q = int.Parse(Console.ReadLine());        var out_ = new StringBuilder();        for (int i = 0; i < q; i++)        {            string[] p = Console.ReadLine().Split(' ', StringSplitOptions.RemoveEmptyEntries);            int a = int.Parse(p[0]), b = int.Parse(p[1]);            out_.Append(s.Substring(a - 1, b - a + 1)).Append('\n');        }        Console.Write(out_);    }}
C++main.cpp · 13 行
#include <iostream>#include <string> int main() {    std::ios::sync_with_stdio(false);    std::string s;    int q, a, b;    std::cin >> s >> q;    for (int i = 0; i < q; i++) {        std::cin >> a >> b;        std::cout << s.substr(a - 1, b - a + 1) << '\n';    }}
Cmain.c · 12 行
#include <stdio.h> int main(void) {    char s[1001];    int q, a, b;    if (scanf("%1000s %d", s, &q) != 2) return 0;    for (int i = 0; i < q; i++) {        scanf("%d %d", &a, &b);        printf("%.*s\n", b - a + 1, s + a - 1);    }    return 0;}
Craykonmain.cray · 9 行
s = コンソール.行読み().空白除去();q = コンソール.行読み().数に();繰り返す (i = 0; i < q; i++){    ab = コンソール.数読み();    a = ab[0];    b = ab[1];    コンソール.書く(s.切り出す(a - 1, b - a + 1));}