【问题标题】:How to efficiently replace elements of char string with different integer elements?如何用不同的整数元素有效地替换 char 字符串的元素?
【发布时间】:2017-05-28 18:34:01
【问题描述】:

我正在寻找用整数元素替换字符串的元素。我想用1替换A,用2替换B,用3替换C,用4替换D

我怎样才能有效地做到这一点?

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


int main()
{
    std::string str = "ABCDDCBA";

    std::replace(str.begin(), str.end(), 'A', '1'); // Replacing 
    std::replace(str.begin(), str.end(), 'B', '2');  
    std::replace(str.begin(), str.end(), 'C', '3'); 
    std::replace(str.begin(), str.end(), 'D', '4');  
    // ...

    std::cout << str << std::endl; // displaying 
    return 0;
}

【问题讨论】:

  • 您的数据如此之小,您的程序如此简单,而今天的计算机如此之快,编译器如此之好,以至于几乎任何解决方案都将是有效的,甚至没有机会测量一个区别。
  • @ChristianHackl 有2000000000 长度
  • 什么意思?长度为 18 的字符串?
  • 还是指 2^9?那是512。它仍然什么都没有。你真的测量过速度吗?

标签: c++ string replace integer


【解决方案1】:

大概您的意思是在一次遍历中进行替换?有华丽的 C++ 标准库方法可以做到这一点,或者您甚至可以使用 std::regex 解决它。但是在std::string 类上利用重载的[] 运算符在性能方面将很难被击败,而且很明显。

for (std::size_t i = 0; i < str.size(); ++i){
    switch (str[i]){
    case 'A':
        str[i] = '1';
        break;
    case 'B':
        /*etc*/
    }
}

如果您要转换多个字符(我从字面上理解您的问题,即您只想映射 A、B、C 和 D),那么请考虑定义一个描述转换的 const char[] 数组;依赖特定字符的 不是严格可移植的 C++。

【讨论】:

  • 任何算法都是 O(字符串长度)。使用const char[] 数组定义转换将很难(如果不是不可能的话)被击败。它也将是完全便携的。
【解决方案2】:

或者您可以尝试输入字符串是否仅包含 ASCII 格式的大写字母

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

int main()
{

std::string str = "ABCDDCBA";
for(int i=0;i<str.size();i++)
{
    str[i]=str[i]-'A'+'0';
}
std::cout << str << std::endl; // displaying 
return 0;
}

【讨论】:

  • 不错,但不是严格的可移植性。阿尔法不一定必须是连续的。 (例如,它们是 ASCII 格式,但不是 EBCDIC 格式)。如果您在答案中提到这一点,我会投票。
  • @Bathsheba 使用给定的输入字符串,这恰好适用于 EBCDIC,因为 A...I 是连续的。没有明确说明输入字符串中是否可能存在超出 A...D 范围的字符。
  • 触摸。是的,这在 EBCDIC 中适用于 A、B、C 和 D。请点赞。
【解决方案3】:

您的方法对于用另一个任意字符替换任意字符非常有效。

但是,目前您将连续的拉丁字母替换为连续的整数数字,因此您可以利用 ASCII 表示也是连续的这一事实:

for(char& c : str)
     c += '1' - 'A';

当然,这取决于本地字符编码来表示具有连续值的连续拉丁字母,例如 ASCII。它还取决于连续表示的数字,但这是标准规定的。

此外,此方法目前不检查替换字符,并将更改所有遇到的字符。这不是您的输入字符串的问题,但如果您打算只替换某些类型的字符而保持其他类型不变,那么您需要添加条件检查。

【讨论】:

  • @AwaitedOne 与您的 O(n * m) 相比,这具有 O(n) 复杂性,其中 n 和 m 是字符串的长度和不同字符映射的数量。
  • 太棒了!!它是否适用于任何非连续字母说ADGI
  • @AwaitedOne 我不知道 ADGI,但总的来说,这要求要替换的字母字符必须用本机编码中的连续值表示,如答案中所述。
【解决方案4】:

一个有趣的方法是使用每个字符的 ASCI 值: 例如: int('A') = 65, int('B') = 66 所以你只需要用 val = int(c) - 64; (仅当您有 maj char 时才有效)

【讨论】:

    【解决方案5】:

    O(n) 中的一个提议

    void MyReplaceFunction(char& c)
    {
        static const int delta='A'-'1';
        if(c>='A' && c<='Z')
        {
            c-=delta;
        }
    }
    
    std::for_each(str.begin(), str.end(), MyReplaceFunction);
    

    【讨论】:

      猜你喜欢
      • 2016-08-04
      • 1970-01-01
      • 1970-01-01
      • 2017-05-14
      • 1970-01-01
      • 2020-09-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多