0

どのように単語を入力し、その出力を逆にすることができますか. 単語の長さを計算する関数を作成しました。ここから、単語の長さに応じて単語を逆にする必要があります。どうやってやるの?

 #include<iostream>

using std::cout;
using std::endl;
using std::cin;
int LengthOfString(  const  char *); // declaring prototype for length of the string 

int reverse(const char []);


int main()
{
    char string1[100];
    cout<<"Enter a string: ";
    cin>>string1;

    cout<<"Length of string is "<<LengthOfString(string1);

    system("PAUSE");

    return 0;
}

int LengthOfString( const  char *x)
{
    int index;
    for(index = 0; *x!='\0';x++,index++);

    return index;
}

int reverse(const char y[])
{
/*   my attempted loop, its not right i know.
 a[] = *index; // length of the word 
        for(int i=0; i<=index/2; i++)
            for(j=0; j == length, j--) */ 

}
4

3 に答える 3

7

このホイールはすでに発明されており、標準ライブラリに存在します。

#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::setstd::vector、などの他のコンテナが存在しstd::listます。 std::stringは によく似ていてstd::vector、 の遠いいとこですstd::list。各コレクションは異なる動作をし、異なるものに適しています。

文字列クラスがそのデータを元に戻すためにどのようにデータを格納するかを理解する必要があると思うかもしれませんが、そうではありません。これが反復子の出番です。は、文字列内の単一要素の位置を格納する特別なオブジェクトである std::stringtypedef を所有します。は、2 つのイテレータを受け取り、それらの内容を繰り返し交換し、互いに向かって移動するライブラリ関数です。これは、次のようになります。std::string::iteratorstd::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);
}
于 2013-06-18T17:38:31.497 に答える
2

プロトタイプ関数の戻り値の型が であるという事実に基づいてint、文字列のインプレース反転を行いたいように見えます。最初に文字列の長さを調べる必要があります (前に計算しましたが、結果をこの関数に渡しませんでした)。次に、中間に達するまで要素を交換します。これを機能させるには、 ではなく を渡す必要がありconst char[]ますchar*(コンテンツを変更することを示します):

int reverse(char* y)
{
  int ii, n;
  n = LengthOfString(y); // "no built in functions - otherwise, use strlen()
  for(ii=0; ii<n/2;ii++) {
    char temp;
    temp = y[ii];
    y[ii] = y[n - ii - 1];
    y[n - ii] = temp;
  }
}
于 2013-06-18T17:39:43.797 に答える