尝试反转除特殊字符外的字符串时出错

Posted

技术标签:

【中文标题】尝试反转除特殊字符外的字符串时出错【英文标题】:Error when trying to reverse string except for special characters 【发布时间】:2016-03-06 13:59:44 【问题描述】:

我只需要反转字符串中的字母部分,同时保持字符串中的特殊字符不变。例如,

Input:   str = "Ab,c,de!$"
Output:  str = "ed,c,bA!$"

我已经编写了以下 C++ 代码来做同样的事情:

#include<stdio.h>
#include<iostream>
#include<string>
#include<math.h>
#include<stdlib.h>
#include<ctype.h>
using namespace std;


int main() 
    char s[100],t[100];
    cin>>s;

    int len;
    for ( len = 0; ; len++ ) 
        if( s[len] =='\0') 
            break;
        
    

    //cout<<len<<endl;

    t[len] = '\0';
    for ( int i = 0; i < len; i++ ) 
        if ( isalpha(s[i])) 
            t[len-i-1] = s[i];
           // cout<<t[len-i-1]<<endl;
        
        else 
            t[i] = s[i];
            //cout<<t[i]<<endl;
        
    
    //cout<<s<<endl;
    cout<<t;
    return 0;

对于上述示例输入,我将 SOH 作为输出。我犯了什么错误?

【问题讨论】:

那么,在使用调试器单步执行代码时,您观察到了什么? 【参考方案1】:

我突然想到用boost::iterator::filter_iteratorstd::reverse 来写这个是很自然的:

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

#include <boost/iterator/filter_iterator.hpp>

using namespace std;

int main()

    auto is_regular = [](char c)return c != ',';;
    string s"hello, cruel world";                                                                                                         
    std::reverse(
        boost::make_filter_iterator(is_regular, s.begin(), s.end()),
        boost::make_filter_iterator(is_regular, s.end(), s.end()));
    cout << s << endl;
   

这个输出:

dlrow, leurc olleh

请注意,这仅将逗号视为特殊,但您明白了。


以下是一个更符合您问题中代码行的解决方案。我认为问题在于,要正确执行此操作,您需要有 两个 索引 - 一个从左侧运行,一个从右侧运行 - 并一直运行直到它们相互交叉。否则你会得到各种奇怪的东西,比如事情被交叉两次。

#include<stdio.h>                                                                                                                                                                                            
#include<iostream>
#include<string>
#include<math.h>
#include<stdlib.h>
#include<ctype.h>
#include<cstring>


using namespace std;


int main()

    char s[101]="hello, cruel world", t[100];

    auto len = strlen(s);
    t[len--] = '\0';

    //cout<<len<<endl;

    int i = 0;
    while(i <= len)
        if (!isalpha(s[i]))
        
            t[i] = s[i];
            ++i;
            continue;
        
        else if (!isalpha(s[len]))
        
            t[len] = s[len];
            --len;
            continue;
        
        else
        
            t[len] = s[i];
            t[i] = s[len];
            ++i;
            --len;
        

    cout<<t<< endl;
    return 0;

【讨论】:

看,我花了很长时间从头开始编写迭代器,来发布它,6分钟太晚了。我需要学习更多的提升。提问者可以使用std::isalpha 代替is_regular @BoBTFish :-) 它经常发生在我身上。不过,这不是一个糟糕的运动。谢谢! 您好,感谢您提出解决问题的替代方法。您能否也让我知道我的代码中导致输出为 SOH 的错误是什么?我无法弄清楚 是的,我去看看。我建议你也考虑这种方法,它(在我的偏见中)是“更多的 C++”。【参考方案2】:

使用标准类std::string而不是字符数组更好也更安全。

程序可以如下所示

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

int main()

    std::string s;

    std::getline( std::cin, s );

    if ( !s.empty() )
            
        for ( std::string::size_type first = 0, last = s.size(); first < --last; ++first )
        
            while ( first != last && !std::isalpha( ( unsigned char )s[first] ) ) ++first;
            while ( first != last && !std::isalpha( ( unsigned char )s[last] ) ) --last;
            if ( first != last ) std::swap( s[first], s[last] );
        

        std::cout << s << std::endl;
            
    

如果要输入字符串

Ab,c,de!$

那么输出会是这样的

Ab,c,de!$
ed,c,bA!$

【讨论】:

以上是关于尝试反转除特殊字符外的字符串时出错的主要内容,如果未能解决你的问题,请参考以下文章

正则表达式中的特殊字符

RegEx 用于匹配除一些特殊字符和“:)”之外的所有字符

Oracle SQL REGEXP_REPLACE - 除指定字符串外的所有内容

正则表达式

正则表达式

通过websocket python发送特殊字符时出错 Hele me?