-1

このような文字列がある場合:

asdasda=1lsdn=sdf=3dfsdf=-sadf= adfgh=1fbfg=fgfg

=1) 文字の後に来て、2) その文字が非アルファベットである場合、文字を削除する最も速い方法は何ですか?

この場合、関数の o/p は次のようになります。

asdasda=lsdn=sdf=dfsdf=sadf=adfgh=fbfg=fgfg

私はc ++でコーディングしています。

これは私がこれまでに持っているものです

std::string b = "asdasda=1lsdn=sdf=3dfsdf=-sadf= adfgh=1fbfg=fgfg";
int a= 1;
while(a != 0){ 
    a = b.find('=', a);
    a++;
    if(!isalpha(b[a])){
        b.erase(a,1);
    }   
}   
std::cout << b << std::endl;
4

4 に答える 4

1

最も重要なのは、ループを実行して各文字を 1 回だけコピーすることです。

そのため、各文字を 1 つずつ削除しようとしないでください (その後のすべての文字をシフトしてください)。

文字列に 2 つのポインターを保持します。

  • 最後の有効な/保存された文字を指すもの
  • チェックする次の文字を指すもの

最初の文字を指す両方を初期化します。

2 番目のポインターの文字を確認します。

  • それが通常の文字であり、削除されない場合は、最初のポインターの場所に置き (ポインターがまだ同一でない場合)、最初と 2 番目のポインターを増やします。
  • 削除する文字の場合は、2 番目のポインターを増やすだけです

最後に必ずターミネータを書きます。

于 2012-04-25T06:35:48.717 に答える
1

私は C++ 開発者ではありませんが、C++ についてどれだけ知っているか、あなたの問題に対する最善の解決策だと思います。

std::string s("asdasda=1lsdn=sdf=3dfsdf=-sadf=adfgh=1fbfg=fgfg");
std::string::size_type k = 0;
/*erase character after =*/ 
while((k=s.find('=',k))!=s.npos) {
   s.erase(k+1, 1);
}

/*erase numeric*/
for(i=0;i<=9;i++) {
 std::string::size_type n = 0;
 while((n=s.find(i,n))!=s.npos) {
   s.erase(n, 1);
}

}

コードに構文エラーがある可能性があります。使用前にこのコードを確認してください。

ありがとう

于 2012-04-25T07:16:26.887 に答える
0

最も簡単な方法は、アルゴリズムで関数を使用して結果を返すことです。

std::string
eraseAfterEq( std::string const& original )
{
    std::string results;
    std::string::const_iterator current = original.begin();
    std::string::const_iterator next = std::find( current, original.end(), '=' );
    while ( next != original.end() ) {
        ++ next;
        results.append( current, next );
        current = std::find_if( next, original.end(), IsAlpha() );
        next = std::find( current, original.end(), '=' );
    }
    results.append( current, next );
    return results;
}

または、文字列をその場で変更する場合:

void
eraseAfterEq( std::string& original )
{
    std::string::iterator current = std::find( original.begin(), original.end(), '=' );
    while ( current != original.end() ) {
        ++ current;
        std::string::iterator next = std::find_if( current, original.end(), IsAlpha() );
        current = std::find( original.erase( current, next ), original.end(), '=' );
    }
}

どちらの場合も、IsAlphaツールボックスにある機能オブジェクトです。

template <std::ctype_base::mask m>
class Is : public std::unary_function<char, bool>
{
    std::locale myLocale;    //  To ensure lifetime of facet...
    std::ctype<char> const* myCType;
public:
    Is( std::locale const& locale = std::locale() )
        : myLocale( locale )
        , myCType( &std::use_facet<std::ctype<char> >( myLocale ) )
    {
    }
    bool operator()( char toTest ) const
    {
        return myCType->is( m, toTest );
    }
};

typedef Is<std::ctype_base::alpha> IsAlpha;
//  ...

私は通常、機能的なバージョンを使用します。速度が十分でない場合は、他の方法を試すことができます。新しいメモリを割り当てる必要がないため、より高速になる可能性があります。(または、より多くをコピーするため、遅くなる可能性があります。サンプル文字列の場合、コピーはおそらく割り当てよりも安価ですが、これは実際のデータ、コンパイラ、および作業しているシステムによって異なります。 )

IsAlphaロケールのサポートが必要ない場合、または使用している の寿命が確実な場合は、 より単純なバージョンの を試すこともできlocaleます。の C バージョン (の<ctype.h>)は、多くの場合、同様に高速です (ただし、 直接isalpha渡すことができないことを忘れないでください。最初に渡さなければなりません)。または、代わりに;を使用して実験することもできます。ただし、これは のみをサポートするため、使用するには多少のハッキングが必要になります。( インターフェイスの設計が特に不十分です。)charstatic_castunsigned charstd::ctype::scan_isstd::find_ifchar const*char const*&original[0]&original[0] + original.size()begin()end()std::locale

実際に実験して測定しないと、どのソリューションが最速かはわかりません。実験と測定を行った後でも、自分のマシンと、測定を行った正確なコンテキストでどちらが最速であったかしかわかりませんでした. あなたのマシンでは最速ではないかもしれません。2 つの単純なバージョンのどちらか適切な方を使用するだけで、必要になるまでパフォーマンスについて心配する必要はありません。

于 2012-04-25T08:35:23.570 に答える
0

あなたは真剣にコーディングを試みる必要があります..しかし、とにかく、これを参考にして開始することができます.

#include <stdio.h>
#include <ctype.h>

void remove_non_alpha(char *s)
{ 
    int i=0, j=0;

    while(s[i]) {
        if (isalpha(s[i])) {
            s[j++] = s[i];
        }
        i++;
    }

    s[j] = '\0';

    return;
}

void remove_after(char *s, char c)
{
    int i=0, j=0;

    while(s[i]) {
        if (s[i] == c) {
            s[j++] = s[i++];
            if (s[i] == '\0') break;
        } else { 
            s[j++] = s[i];
        }
        i++;
    }

    s[j] = '\0';

    return;
}

int main()
{
    char a[] = "asdasda=1lsdn=sdf=3dfsdf=-sadf= adfgh=1fbfg=fgfg";
    char b[] = "asdasda=1lsdn=sdf=3dfsdf=-sadf= adfgh=1fbfg=fgfg";

    printf("sample string: %s \n", a);
    remove_after(a, '=');
    printf("final string : %s \n", a);

    printf("sample string: %s \n", b);
    remove_non_alpha(b);
    printf("final string : %s \n", b);

    return 0;
}

出力は次のとおりです。

$ gcc remove.c 
$ ./a.out 
sample string: asdasda=1lsdn=sdf=3dfsdf=-sadf= adfgh=1fbfg=fgfg 
final string : asdasda=lsdn=df=dfsdf=sadf=adfgh=fbfg=gfg 
sample string: asdasda=1lsdn=sdf=3dfsdf=-sadf= adfgh=1fbfg=fgfg 
final string : asdasdalsdnsdfdfsdfsadfadfghfbfgfgfg 
$ 

C私はあなたにプログラムを与えました。C++では、を使ったプログラムを試してみてSTLください。

于 2012-04-25T06:42:27.787 に答える