2016-11-27 13 views
1

文字列の最初の文字と最後の文字を同じに保ち、最後の文字の後のすべての非文字を無視する関数を書くつもりです。私はstd :: random_shuffle()を使うはずです。私はドキュメントを読んだが、私はこの機能の概念を理解していないようだ。これは私のコードです:文字列をシャッフルするC++

#include <iostream> 
#include <algorithm> 
#include <string> 

std::string mix(std::string s){ 
    int last_char; 
    if(std::isalpha(s[s.size()-1]) == true){ 
     last_char = s.size()-1; 
    } else { 
    for(int i=s.size()-1 ; i>0; --i){ 
     if((std::isalpha(s[i]) == false) && (std::isalpha(s[i-1])==true)){ 
      last_char = i -1; 
      break; 
     } 
     } 
    } 
    std::random_shuffle(&s[1],&s[last_char]); 
    return s; 

} 

int main(){ 
    std::string test = "Hello"; 
    std::cout << mix(test) << std::endl; 
} 

編集:今、しかし、私はエラーを取得しておく:セグメンテーションフォールト(コアダンプ)。誰かが理由を知った?問題を見つけることができないようです。

+0

それは、ランダムにあなたがデバッガを使用する方法を学ぶ必要がある – Alex

+0

指定する引数の間で内容をシャッフル。一方、次の質問に答えてください:last_letterの最終的な価値は何ですか?それはどの行に割り当てられていますか? –

答えて

3

std::random_shuffleは、ソートされる配列/コンテナの値ではなく、イテレータまたはポインタを引数としてとります。 std::random_shuffleへのあなたの呼び出しは、おそらく次のようになります。

std::random_shuffle(&s[1],&s[last_char]); 

注2番目のパラメータは終了イテレータ値であること。終了イテレータは、ソートする最後の値を指すのではなく、それ以降のソートを指します。

これは、表示されたコードの唯一の問題ではありません。 std::random_shuffleの呼び出しに先行するいくつかのバグをコードで修正する必要があります。例:

for(int i=s.size() ; i>0; --i){ 
    if((std::isalpha(s[i]) == false) && (std::isalpha(s[i-1])==true)){ 

s.size()文字列のサイズを指定します。最初の反復では、isize()と等しくなりますが、s[i]にアクセスすると未定義の動作が発生し、s[i]は明らかに存在しないため、バグが発生します。 n文字を含む文字列では、文字はs[0]s[n-1]です。

あなたはlast_charは、次の文字、あなたが上記の、シャッフルした後、固定std::random_shuffleコールを使用したい後の1の指標なってしまうように、あなたのアルゴリズムを修正する必要があります。

あるいは、ソートする最後の文字のインデックスであることをlast_charを計算し、罰金になります

std::random_shuffle(&s[1],&s[last_char+1]); 

どちらのアプローチを呼び出します。

+0

ありがとうございました!非常に有益で有用でしたが、我々はまだポインタをカバーしていないので、そのようなエクササイズが渡されたのは非常に奇妙です。私は私のコードを修正したと思う(それはコンパイルされます)しかし、今私はエラーを取得し続ける:セグメンテーションフォールト(コアダンプ)と私は問題を見つけることができないようです。私は私のポストに自分のコードを修正しました。 – mthe25

+0

私はもともと同じバグを指摘しました。あなたの数学はオフです。あなたは1つの場所にいます。私は 's.size()'で問題を指摘しましたが、いくつかの場所で同じバグがあります。さらに、終了イテレータ値の計算を正しく実装していませんでした。終了イテレータの値が何であるかについての私の説明を見直し、デバッガを使って一度に1行ずつコードをステップ実行してください。 –

1
  1. 文字列の右側に一番左の「非文字」を見つける必要があります。

  2. この左側の1桁は、最後の文字の位置です。

  3. 右の1桁目が最初の文字です。

  4. "first"と "last"でrandom_shuffleを呼び出すだけです。ここで

は、いくつかの有用なリンクです:

http://www.cplusplus.com/reference/algorithm/random_shuffle/

"始まり" は包括的、 "終わり" であることを忘れないでください排他的である」

-1

あなたが始めるために何かそれは、少なくとも持っています。あなたが修正しなければならない1つのコーナーケース。cppreferenceにアクセスしてください。アルゴリズムの仕組みを理解する。

#include <iostream> 
#include <cctype> 
#include <algorithm> 
#include <string> 

std::string 
special_shuffle(std::string s) 
{ 
    if (s.size() < 3) return s; 
    auto begin = std::find_if(s.begin(), s.end(), ::isalpha); 
    auto end = std::find_if(s.rbegin(), s.rend(), ::isalpha).base(); 
    std::random_shuffle(++begin, --end); 
    return s; 
} 

int 
main() 
{ 
    std::string s1 = "Hello World!"; 
    std::string s2 = "AB"; 
    std::string s3 = "A"; 
    std::string s4 = ""; 
    std::string s5 = "a string going from a to z"; 

    std::cout << s1 << " --> " << special_shuffle(s1) << "\n" 
      << s2 << " --> " << special_shuffle(s2) << "\n" 
      << s3 << " --> " << special_shuffle(s3) << "\n" 
      << s4 << " --> " << special_shuffle(s4) << "\n" 
      << s5 << " --> " << special_shuffle(s5) << "\n"; 
} 

コンパイルして実行します。

$ g++ example.cpp -std=c++14 -Wall -Wextra 
$ ./a.out 
Hello World! --> Hooll eWlrd! 
AB --> AB 
A --> A 
--> 
a string going from a to z --> aarfritomgi nnso t g goz 
関連する問題