-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

最重要的是执行循环并只复制每个字符一次。

所以不要试图一个一个地删除每个字符(并移动它之后的所有字符)。

在您的字符串中保留 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

您应该认真尝试编码.. 但无论如何您都可以将其用作开始的参考。

#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 回答
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 版本(in <ctype.h>isalpha通常也更快(只是不要忘记你不能char 直接传递它 a ——你必须先传递static_castunsigned char)。或者,您可以尝试使用std::ctype::scan_is而不是std::find_if; 但是,使用它需要一些黑客攻击,因为它只支持char const*: 如果我走这条路,我可能会使用和作为char const*我的迭代器和。( 界面设计得特别差。)&original[0]&original[0] + original.size()begin()end()std::locale

如果没有实际的实验和测量,我无法告诉你哪种解决方案最快。即使在实验和测量之后,我也只能告诉你哪个在我的机器上最快,并且在我进行测量的确切环境中。它可能不是您机器上最快的。只需使用两个简单版本中最合适的一个,在需要之前不要担心性能。

于 2012-04-25T08:35:23.570 回答