公式

A - A Substring 解説 by MMNMM


初心者の方へ

大きく分けて \(2\) つの方針があります。

  1. 消されずに残る文字を順に出力する
  2. 出力するべき文字列を作ってから出力する

それぞれの方針について説明します。

1. 消されずに残る文字を順に出力する方針

\(S\) から取り除かれる文字は、\(S\) の \(1\) 文字目 \(,2\) 文字目 \(,\ldots,A\) 文字目と、\(N-B+1\) 文字目 \(,N-B+2\) 文字目 \(,\ldots,N\) 文字目です。

つまり、取り除かれずに残る文字は \(A+1\) 文字目から \(N-B\) 文字目までの文字です。

これらの文字を順番に出力することで、この問題を解くことができます。 出力の最後にスペースや改行などがデフォルトでつく言語では、文字列を \(1\) 文字ずつ出力する際には余分な区切り文字が出力されないように注意してください。

実装例は以下のようになります。

C++ での実装例

#include <iostream>
#include <string>
using namespace std;

int main() {
    int N, A, B;
    cin >> N >> A >> B;
    string S;
    cin >> S;

    // 先頭から A 文字、末尾から B 文字だけ取り除く
    // → 0-indexed で A 文字目以降、N-B 文字目より前が残る
    int start = A;
    int end = N - B;

    // 取り除かれない文字を順番に出力する
    for (int i = start; i < end; ++i) {
        cout << S[i];
    }
    cout << endl;
    return 0;
}

Python での実装例

N, A, B = map(int, input().split())

S = input()

# 先頭から A 文字、末尾から B 文字だけ取り除く
# → 0-indexed で A 文字目以降、N-B 文字目より前が残る
start = A
end = N - B

# 取り除かれない文字を順番に出力する
for i in range(start, end):
    print(S[i], end='')

2. 出力するべき文字列を作って出力する方針

いくつかの言語では、文字列の連続する部分を取り出して新しい文字列を作る方法が用意されていることがあります。

例えば、C++ では string 型の変数のメンバ関数 substr を呼び出すことで、Python では str 型の変数にスライスでアクセスすることで、連続する部分を取り出した文字列を作ることができます。

実装例は以下のようになります。

C++ での実装例

C++ の substr 関数は、「先頭が何文字目か」と「合計何文字取り出すか」の値を与えることで連続する部分を取り出した文字列を作ることができます。

#include <iostream>
#include <string>
using namespace std;

int main() {
    int N, A, B;
    cin >> N >> A >> B;
    string S;
    cin >> S;

    // (0-indexed で) A 文字目から、合計 N - A - B 文字取り出す
    cout << S.substr(A, N - A - B) << endl;
    return 0;
}

Python での実装例

Python でスライスを用いて末尾から \(B\) 文字取り除いた文字列を作る際、[:-B] のような操作をすると \(B=0\) のときに意図しない挙動となってしまうため、一工夫必要になります。

\(B\) が \(1\) 以上になるように \(S\) の末尾に \(1\) 文字追加したり、\(-B\) ではなく \(N-B\) でアクセスすることで意図した動作にすることができます。

N, A, B = map(int, input().split())

S = input()
S += 'a' # [:-B] でアクセスしたいので、1 文字末尾に追加しておく
B += 1 # B も増やす

print(S[A:-B])

投稿日時:
最終更新: