C++で文字列の各文字をシフトするアルゴリズムを実装する方法
小文字のみで構成された文字列 S と整数型配列 shifts が与えられたとします。ここで「シフト」とは、ある文字をアルファベット順で次の文字に置き換えることを意味し、z の場合は a に戻ります(循環)。そして、各 shifts[i] = x に対して、文字列 S の先頭から i+1 文字目までをそれぞれ x 回シフトします。すべてのシフト操作を適用した後の最終的な文字列を求めるのがこの問題です。
例として、文字列が "abc"、shifts = [3, 5, 9] の場合を考えてみましょう。
- 最初の1文字を3回シフト →
"dbc" - 最初の2文字をそれぞれ5回シフト →
"igc" - 最初の3文字をそれぞれ9回シフト →
"rpl"(これが答え)
解法のアプローチ
この問題を素朴に解くと、各シフト操作ごとに文字を一つずつ動かす必要があり、計算量が大きくなってしまいます。そこで有効なのが「後ろからの累積和」の考え方です。ある位置の文字は、それ以降のすべてのシフト操作の影響を受けるため、配列を後ろから走査しながらシフト量を累積していきます。
具体的には以下の手順で解きます。
iをシフト配列のサイズ − 2 から 0 まで降順にループするshifts[i] += shifts[i + 1](後続のシフト量を累積)shifts[i] %= 26(オーバーフロー防止のため26で剰余を取る)
iを 0 から文字列Sのサイズ − 1 までループするS[i] = ((S[i] - 'a') + shifts[i]) % 26 + 'a'(実際に文字をシフト)
Sを返す
この方法により、時間計算量 O(n)、空間計算量 O(1)(入力配列を再利用する場合)で効率的に解くことができます。
C++での実装例
以下に実際のC++コードを示します。
#include <bits/stdc++.h>
using namespace std;
class Solution {
public:
string shiftingLetters(string S, vector<int>& shifts) {
// 後ろから累積シフト量を計算
for(int i = shifts.size() - 2 ;i >=0; i--){
shifts[i] += shifts[i + 1];
shifts[i] %= 26;
}
// 各文字を対応するシフト量だけ移動
for(int i = 0; i < S.size(); i++) {
S[i] = ( ((S[i] - 'a') + shifts[i]) % 26 + 'a');
}
return S;
}
};
main(){
vector<int> v = {3,5,9};
Solution ob;
cout << (ob.shiftingLetters("abc", v));
}
入力
"abc" [3,5,9]
出力
rpl
まとめ
この問題のポイントは、各文字が受けるシフト量を後ろから累積して求める点にあります。これにより、同じ文字を何度も書き換える無駄な処理を避けられます。また、剰余演算を適切に行うことで、大きなシフト量や整数オーバーフローにも対応できる堅牢な実装になります。同様の「区間への加算」を伴う問題では、この累積和(いもす法的な発想)のテクニックが応用できるので、ぜひ覚えておきましょう。
-
C++の識別子とは?命名ルールと具体例をわかりやすく解説
C++における識別子(identifier)とは、変数、関数、クラス、モジュールなど、プログラマが定義するさまざまな要素に名前を付けて識別するために使われる名称です。識別子の命名には以下のルールがあります。先頭は半角アルファベットの大文字(A〜Z)、小文字(a〜z)、またはアンダースコア(_)で始める必要があります。2文字目以降は、英字・数字(0〜9)・アンダースコアを自由に組み合わせられます。識別子の中に「@」「$」「%」などの記号(句読点・特殊文字)を使うことはできません。大文字と小文字は区別されるC++は大文字と小文字を厳密に区別するプログラミング言語です。そのため、「Manpower」
-
Linux向けC++開発に最適なIDEのおすすめ6選
大規模なプロジェクトをテキストエディタだけで管理するのは容易ではありません。そうしたケースではIDE(統合開発環境)を活用することで、生産性が向上し、フラストレーションも大幅に軽減されるでしょう。IDEにはさまざまな種類があり、自分のニーズに合ったものを選ぶことが重要です。「Linux上のC++開発において唯一のベスト」と呼べるIDEは存在せず、賢くツールを見極める必要があります。ここでは、人気が高く、編集部のおすすめでもあるLinux向けIDEを紹介します。Linuxで使えるC++向けIDE おすすめ6選1. NetBeansNetBeansは、C/C++をはじめ多くのプログラミング言語に対