在其中每第 n 次出现时反转一个字符串[关闭]

Posted

技术标签:

【中文标题】在其中每第 n 次出现时反转一个字符串[关闭]【英文标题】:Reverse a string at every nth occurance in it [closed] 【发布时间】:2014-01-02 10:44:50 【问题描述】:

我有一个字符串 str[]="ABCDEFGHI" 并说 n=3。我需要为任何输入字符串实现 reversestring(arr,n) 逻辑,对于任何 n 值。在这种情况下,我的输出必须是str = "CBAFEDIHG"

如果我的str[]="PQRSTUVWXYZ",对于 n=4,我的输出必须是 str = "SRQPWVUTXYZ"。在这种情况下,您可以忽略最后一次出现的反转,因为少于 4 个字母。

是否可以在不使用 c++ 中的函数重载的任何第 n 个出现条件的情况下为 input[]="this is a simple test", output[]="sith si a elpmis tset" 推广类似的逻辑。

【问题讨论】:

是的,这是可能的,而且在 C++ 中它实际上非常简单。您可能想了解std::istringstreamstd::reversestd::ostringstream 您正在寻找的词是“词典排列”,现在您可以使用 Google 来执行此操作 :) 输出的'o/p'是常用的缩写吗?我花了整整 10 秒钟才弄清楚它的意思(尽管意图和句子的其余部分很清楚)。 @Elliot Robinson 我以前从未见过它,但对我来说有点成长。 为什么要使用重载? (根据原因,可能会或不能使用它) 【参考方案1】:

假设您正在处理 C 风格的字符串,如果您想反转每 n 个字符,您可以简单地执行以下操作:

//Iterators
int x, y;
char str[] = "ABCDEFGHI";
int n = 3;
int strLen = strlen(str);

//Assuming C99+ for variable length arrays...
char newStr[strLen + 1];


if (strLen % n != 0) 
    printf("For this simple example the length of str must be a multiple of n\n");
    return 0;


for (x = 0; x < strLen; x += n) 
    for (y = 0; y < n; y++) 
        newStr[x + y] = str[x + (n - y) - 1];
    


//Ensure string is terminated properly
newStr[strLen] = 0;

printf("Converted %s to %s\n", str, newStr);

return 0;

就概括而言,您给出的第二个示例涉及反转单词,而不是 n 字符块,因此您需要一种不同的方法,将字符串拆分为单独的单词并反转这些块,这是一种不同的方法问题

【讨论】:

【参考方案2】:

这是一个仅使用一个库函数std::reverse的示例:

#include <iostream>
#include <algorithm>

int main() 
    std::string s1 = "ABCDEFGHI";
    std::string s1_output = "CBAFEDIHG";
    std::string s2 = "PQRSTUVWXYZ";
    std::string s2_output = "SRQPWVUTXYZ";
    int N1 = 3;
    int N2 = 4;

    for (unsigned int i = 0; i < s1.size() / N1; i++)
        std::reverse(s1.begin() + (i * N1), s1.begin() + (i * N1 + N1));
    std::cout << std::boolalpha << (s1 == s1_output) << std::endl; // true
    for (unsigned int i = 0; i < s2.size() / N2; i++)
        std::reverse(s2.begin() + (i * N2), s2.begin() + (i * N2 + N2));
    std::cout << std::boolalpha << (s2 == s2_output) << std::endl; // true

您的第二个示例与您的第一个示例不同,因为您对单个单词而不是范围进行操作。它也不同,因为您不会忽略小于 N 的块。

按照 cmets 中的建议,您可以使用 std::istringstream 并使用提取运算符来提取空白之间的“块”。

#include <iostream>
#include <algorithm>
#include <sstream>
#include <iterator>

int main() 
    std::string s1 = "this is a simple test";
    std::string s1_output = "siht si a elpmis tset"; // you made a typo

    std::istringstream iss(s1);

    std::string chunk;
    std::string output = "";
    while (iss >> chunk) 
        std::reverse(chunk.begin(), chunk.end());
        output += chunk + " ";
    
    output.erase(output.size() - 1, output.size()); // chop off remaining space
    std::cout << std::boolalpha << (output == s1_output); // true

【讨论】:

以上是关于在其中每第 n 次出现时反转一个字符串[关闭]的主要内容,如果未能解决你的问题,请参考以下文章

每第 N 个单词插入字符串

从字符串中选择每第 n 个字符

不反转数字的字符反转[关闭]

在第 n 次出现字符时剪切字符串

gsoap 在我每第二次调用时都会对我的应用程序(用 C 编写)进行段错误

JavaScript删除文本文档中每第3行的文本