2016-10-28 13 views
-1

関数に渡された文字列の長さを表示するのではなく、文字列の更新された長さを返すのはなぜですか?変更された文字列の長さを返さない関数

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

int number_needed(string a, string b) { 
    for(int i=0;i<a.length();i++) 
    { 
     for(int j=0;j<b.length();j++) 
     { 
      if(a[i]==b[j]){ 
       { 
       a[i]='\0'; 
       b[j]='\0'; 
       } 
      } 
     } 
    } 
    cout<<a<<" "<<b<<endl; 
    return a.length()+b.length(); 

} 

int main(){ 
    string x; 
    cin >> x; 
    string y; 
    cin >> y; 
    cout << number_needed(x, y) << endl; 
    return 0; 
} 

入力:

weasaa

asjdsa出力:

WEAのJDS
12(FUNCのnumber_neededから返された値)

FUNCの

戻り値があることがnumber_needed:期待

wea jds 
6 
+2

なぜ文字列の長さが変更されたと思いますか? – UnholySheep

+0

の内容を上書きしただけでは、cppを使用するとcに書き込まれません。 [string](http://www.cplusplus.com/reference/string/string/) – Stargateur

+1

脇に、 'using namespace std;'は悪い考えです。あるいは、そこにあるもの、そこにいるもの、またはいつかそこにいるかもしれないものすべてを知っていますか? – Deduplicator

答えて

3

std::string文字列ではなく、NUL終端いずれかをカウントします。

したがって、任意の文字を変更しても、その長さは変更されません。

サイズを変更する場合は、.resize(newlength)を使用してください。あなたが実際にあれば内部で何をしたいのか

+1

'/ 0'が文字の場合、どのようにresize()が助けますか? Resize()は、最後の数文字を削除するだけです。 –

+2

'resize()'は文字列のサイズを変更するためです。文字列に含まれる文字が文字列のサイズと関係があると誤解されているようです。たぶん、あなたは 'std :: string'がどのように動作するかについていくつかの誤解をはっきりと抱いているので、デバッガでコードをステップ実行してみるべきでしょう。 –

0

は次のようになります。これは、インデックスiで1つの要素(もちろん、および含む)開始、各文字列から(必要に応じて、数を変更)を除去し

if (a[i] == b[j]) 
    { 
      a.erase(i, 1); 
      b.erase(j--, 1); //decrement j so we can check the new char at b[j] 
    } 

。文字列には任意の数の '\ 0'を入れることができますが、サイズには影響しません。それが文字の場合は、文字列の合計サイズにカウントされます。

+0

いいえ、これはうまくいきません、 –

+0

私の悪いですが、b.erase()は 'i'の代わりに' j'を使うべきです。今はうまくいくはずです。ところで、 'a'の最後の要素を消去したかどうかを確認する必要があります。なぜなら、存在しない要素と' b [i] 'を比較しようとしてエラーが発生する可能性があるからです。 – Xzenon

+0

素晴らしいです。しかし、どうやって話を変えたの?私はインデックスjをb.eraseで使っていましたが、それでも近いものはありませんでした。 –

0

何を達成したいことはstd::stringBを文字を繰り返し削除しますが、唯一の文字列の長さを変更しない\0、それを変更することができます。また、あなたの結果はあなたのコードに応じて、次のようになります。

we\0\0\0a \0\0\0jds\0 
12 

だからあなたのコンソールで、それは次のようになります。

we a jds 
12 

しかし、あなたはあなたの期待どおりの結果をしたい場合は、チェック:

for (auto Itr_a = a.begin(); Itr_a != a.end(); ++Itr_a) 
{ 
    for (auto Itr_b = b.begin(); Itr_b != b.end();) 
    { 
     if (*Itr_a == *Itr_b) 
     { 
      Itr_a = a.erase(Itr_a); 
      Itr_b = b.erase(Itr_b); 
     } 
     else 
      ++Itr_b; 
    } 
} 

出力:

wea jds 
6 
+0

これを試しましたが、私のために働いていませんでした。あなたは私のコードでそれを行うことができますか? –

+0

関数のforループを私のものに置き換えましたか? –

0

length(好ましいsize方法と同じである)を返し:

stringCharT要素の数、すなわち、std::distance(begin(), end())

string::operator[]これはことを意味するイテレータを無効にしないため文字列内のすべての文字にnullを割り当てることができ、長さを変更することはできません。


あなたはstringに非'\0'文字の数を見つけるためにcount_ifを使用することができます。

return count_if(begin(a), end(a), [](const auto& i){ return i != '\0'; }) + count_if(begin(b), end(b), [](const auto& i){ return i != '\0'; }) 

EDIT:

カップルのコメントがここで行うことができ、このようになりますあなたのreturn -statementを変更これによりcount_if(begin(a), end(a), [](const auto& i){ return i != '\0'; })

:あなたはこのようにそれを使用することができます:

  1. 上記のどちらが望ましい場合cout -statementが必要な場合はcout -statement number_neededset_symetric_difference
  2. によって置き換えることができ、2つのset_difference文が
  3. 考慮しなければならない、if -statementはbreakと2で終わる必要がありますパラメータはconst参照によって渡されるべきです。
+0

OK、これは簡単ですが、どのように動作するかを説明します –

+0

@AvneetSingh答えの中の 'count_if'ハイパーリンクをクリックすると、関数のリファレンスページに移動します。しかし、仮面ライダーの言葉では、ラムダが返されるカウントをインクリメントするそのキャラクタに対して真を返すならば、文字列中のすべてのキャラクタを繰り返し処理します。ラムダは単に文字が ''\ 0' 'でなければチェックしています。 –