标准::替换的逻辑错误

Logic error with std::replace

本文关键字:错误 替换 标准      更新时间:2023-10-16

今天我在做学校项目时遇到了一个逻辑错误。对于此项目,需要切换chars

例如,用户输入字母A .它被切换到U,一切都很好。但是,当用户输入字母 U 时,会出现此问题。角色保持不变。我实现了两个规则来从A切换到UU切换到A。字符串通过这两个规则传递,因此保持不变。我该如何防止这种情况?

#include <iostream>
#include <algorithm>
#include <string>
using namespace std;
int main()
{
 string seq;
 getline(cin, seq);
 transform ( seq.begin(), seq.end(), seq.begin(), ::toupper );
 replace ( seq.begin(), seq.end(), 'A', 'U' );
 replace ( seq.begin(), seq.end(), 'U', 'A' );
 cout << seq;
 return 0;
}

通过您的实现,您可以将A替换为U然后UA

replace ( seq.begin(), seq.end(), 'A', 'U' );
replace ( seq.begin(), seq.end(), 'U', 'A' );

您需要一次性进行更换,例如使用std::transform

std::transform(begin(seq), end(seq), begin(seq), some_function_object);

你只需要写这个神秘的some_function_object.它可以是一个自由函数:

char some_function_object(char input) { /* ... */ }
std::transform(begin(seq), end(seq), begin(seq), some_function_object);

或 lambda 函数:

std::transform(begin(seq), end(seq), begin(seq), [](char input) { /* ... */ } );

此函数对象必须采用char并返回:

  • A input是否U;
  • U input是否A;
  • input否则。

如果它是一个免费函数,你应该如何称呼它?好吧,为什么不像swapAandU这样的自我描述性名称呢?

当基于范围的 for 循环比使用标准算法(例如 std::transform(更合适、更有效时,情况似乎就是这样。

例如

#include <iostream>
#include <string>
int main() 
{
    std::string s( "AUAUA" );
    std::cout << s << std::endl;
    for ( char &c : s )
    {
        if ( c == 'A' ) c = 'U';
        else if ( c == 'U' ) c = 'A';
    }
    std::cout << s << std::endl;
    return 0;
}

程序输出为

AUAUA
UAUAU

您可以编写一个单独的函数,例如

#include <iostream>
#include <string>
std::string & convert( std::string &s1, const std::string &s2, const std::string &s3 )
{
    for ( char &c : s1 )
    {
        auto i = s2.find( c );
        if ( i != std::string::npos ) c = s3[i]; 
    }
    return s1;
}
int main() 
{
    std::string s( "AUAUA" );
    std::cout << s << std::endl;
    std::cout << convert( s, "AU", "UA" ) << std::endl;
    return 0;
}

如果对字符串 s2 进行排序,则可以使用二叉搜索算法而不是线性搜索。

如果你想使用标准算法,那么在我看来,最合适的算法是std::for_each与基于范围的 for 循环相对应。例如,第一个演示程序可以使用算法重写如下方式

#include <iostream>
#include <string>
#include <algorithm>
int main() 
{
    std::string s( "AUAUA" );
    std::cout << s << std::endl;
    std::for_each( s.begin(), s.end(), 
        []( char &c ) 
        { 
            if ( c == 'A' ) c = 'U';
            else if ( c == 'U' ) c = 'A';
        } );
    std::cout << s << std::endl;
    return 0;
}