このホイールはすでに発明されており、標準ライブラリに存在します。
#include <iostream>
#include <string>
#include <algorithm>
int main()
{
std::string word;
std::cout << "Enter a word: ";
std::cin >> word;
std::reverse(word.begin(), word.end());
std::cout << "Reverse: " << word << std::endl;
return 0;
}
ここで何が起こっているのかを正確に理解するには、最初に説明しなければならないことがいくつかあります。
クラスとは何かをすでに知っていることを願っています。まだ入門的な内容の場合、クラスは基本的にユーザー定義の状態と動作のコレクションです。作成者は、さまざまな理由で、クラスの状態または動作へのアクセスを制限することを選択できます。の場合std::string
、標準ライブラリの文字列クラスでは、すべての状態が非表示になり、動作のみがアクセス可能になります。
string クラスは、文字を含むコンテナです。他にも多数のコンテナー クラスがあり、それぞれに異なる長所と短所があります。文字列クラスには、厳密な順序で一連の文字が含まれています。std::set
、std::vector
、などの他のコンテナが存在しstd::list
ます。 std::string
は によく似ていてstd::vector
、 の遠いいとこですstd::list
。各コレクションは異なる動作をし、異なるものに適しています。
文字列クラスがそのデータを元に戻すためにどのようにデータを格納するかを理解する必要があると思うかもしれませんが、そうではありません。これが反復子の出番です。は、文字列内の単一要素の位置を格納する特別なオブジェクトである std::string
typedef を所有します。は、2 つのイテレータを受け取り、それらの内容を繰り返し交換し、互いに向かって移動するライブラリ関数です。これは、次のようになります。std::string::iterator
std::reverse
v v <-- positions of iterators (start at the start, end at the end)
ABC <-- initial state
v v <-- the end iterator moved back
ABC
v v
CBA <-- the iterators swapped their values
vv <-- the begin iterator moved forward
CBA
V <-- the end iterator moved back; both iterators are in the same place
CBA <-- therefore, we're done, the string is reversed
イテレータについての 1 つのことは、それらがポインタのようなものであるということです。実際、構文的に同じように動作するため、反復子を必要とするいくつかの関数にポインターを渡すことができます。したがって、s を除いて、基本的にこれと同じことを行うポインターを使用する独自の逆関数を作成できるはずですchar *
。
関数を記述できるはずの疑似コードを次に示します (宿題なので、完全には書きません)。
namespace BaidNation
{
void reverse(char *begin, char *end)
{
loop forever
{
if (end equals begin):
done;
move end backwards;
if (end equals begin):
done;
swap end's and begin's characters;
move begin forwards;
}
}
}
最後の要素を参照するイテレータではなく、コレクションの末尾の後に要素を参照するイテレータを end に期待することに注意してBaidNation::reverse
ください。では、これを使用することはどのように理にかなっていますか?std::reverse
関数LengthOfString
は、文字列内の null 以外の文字の数を返します。配列はゼロインデックスなので、他の配列と同様に、 をチェックするstring1 + LengthOfString(string1)
と、最後の文字へのポインターが得られることがわかっています。
したがって、これを使用して文字列を逆にすることができます。
BaidNation::reverse(string1, string1 + LengthOfString(string1));
以前の署名を正確に使用する必要がある場合は、この設計を別の設計に適合させることができます。
int reverse(const char str[])
{
char *start = str, *end = str + LengthOfString(str);
BaidNation::reverse(start, end);
}