【问题标题】:Swap words in string C++在字符串 C++ 中交换单词
【发布时间】:2022-01-24 11:30:45
【问题描述】:

我是 StackOverflow 的新用户!我需要帮助。我的任务是在列表中的字符串中找到两个动词 (_words[]) 并交换它们。使用字符串实现起来并不难,但我只能使用char

我的想法是这样的:我将char(char str[]) 数组拆分为单词,并将每个单词分配给一个常量数组(str2[]),我对已知动词也是如此。接下来,我检查 - 如果第一个数组中的单词与已知动词匹配,那么我将数字 (j) 分配给一个整数数组,以便知道该单词的位置。好吧,那么,在冒泡方法的帮助下,我改变了他们的位置。但是运气不好,我查看了调试器,并且由于某种原因在比较单词时,即使单词相同,检查也没有通过。 (对不起我的英语)

你能帮我弄清楚我做错了什么吗?我将不胜感激!

#pragma warning(disable:4996)

#include <iostream>
#include <conio.h>

void words() {
    char str[] = "i like to make programm";
    char _words[] = "like make";
    char* l1 = strtok(_words, " ");
    const char* z[10]; 
    const char* str2[10];
    const char* temp[1];
    int arr_num[2];
    int i = 0, control = 0;
    int word = 0;

    char* stream;

    while (l1 != NULL)
    {
        z[i] = l1;
        l1 = strtok(NULL, " ");
        i++;
    }

    for (int i = 0; i < 2; i++) {
        cout << z[i] << endl;
    }

    i = 0;

    for (int i = 0; i < strlen(str); i++) {
        if (str[i] == ' ') {
            word++;
        }
    }
    word++;
    stream = strtok(str, " ");

    while (stream != NULL)
    {
        str2[i] = stream;
        if(stream == z[0]) cout << "lol";
        stream = strtok(NULL, " ");
        i++;
    }

    for (int i = 0; i < word; i++) {
        cout << str2[i] << endl;
    }

    for (int i = 0; i < 2; i++) {
        for (int j = 0; j < word; j++) {
            if ((z[i] == str2[j]) && (control < 3)) {
                control++;
                arr_num[i] = j;
            }
        }
    }

    if (control == 2) {
        temp[0] = str2[arr_num[0]];
        str2[arr_num[0]] = str2[arr_num[1]];
        str2[arr_num[1]] = temp[0];
    }

    for (int i = 0; i < word; i++) {
        cout << str2[i] << " ";
    }
}

【问题讨论】:

  • 我们不是读心术的人。我们阅读代码。您的代码应为 included in your question 格式正确的 minimal reproducible example,并包括任何示例输入、预期输出、实际输出以及迄今为止的调试工作和发现。
  • 当你比较单词时,你真的比较char*s吗?如果这些指针指向不同的位置,它们就会变得不同,但是指向位置的内容可能是相同的。
  • 对不起,我忘了贴代码
  • 我想你的任务是交换给定字符串(字符数组)中的单词,例如“red apple is the 最甜蜜的一个。”变成“sweetest apple is the red one。”这不仅涉及将两个选择的单词相互替换,而且还可能在它们之间移动内容......
  • @zerocukor287 ,是的,我按照你说的做。你能推荐一个替代方案吗?

标签: c++ string char


【解决方案1】:

发布只是因为 OP 要求提供一种替代算法来说明如何做到这一点。还有其他方法,但这样做的好处是完全就地完成,除了一些指针和一些长度之外不使用额外的存储。

这个任务可以在原地完成,通过使用一个实用函数来反转一个字符序列,给定一个指针和长度(或两个指针)。您还必须拥有许多其他可靠操作供您使用,包括查找完整单词的能力。 (例如,前面是空格或字符串开头的单词,后面是空格或字符串结尾的单词。写下这些,并彻底测试它们。一旦你这样做了,考虑关注。

字符串

this is a very simple sample of words

测试词

very of

我们首先将两个词分开,您已经在这样做了。接下来,我们使用您经过充分测试的实用函数找到这两个词,记住它们的位置。我们知道它们的长度,因此我们可以计算它们的起点和终点。

this is a very simple sample of words
          1111               22

旁注:执行此操作时,您会发现 顺序 可能是向后的。例如,如果您的单词列表是of very,那么结果将是您的单词位置如下所示:

this is a very simple sample of words
          2222               11

没关系,重要的是一旦你找到了两个词,最接近字符串开头的词是“第一个”词,后面的词是从这里开始的“第二个”词出去。

也就是说(现在回到我们原来的标签),从第一个单词的开头到第二个单词的结尾反转整个片段,包括第一个单词之前的任何空格,或者接二连三:

this is a fo elpmas elpmis yrev words
          22               1111

接下来,在他们的新家将这两个词原地颠倒。

this is a of elpmas elpmis very words
          22               1111

最后,反转所有字符过去新的第一个单词的结尾直到(但不包括)新的第二个单词的开头,包括空格这意味着地区:

this is a of elpmas elpmis very words
            xxxxxxxxxxxxxxx

它变成了这样:

this is a of simple sample very words

这就是整个算法。一旦你找到了你的词的位置和范围,你实际上是完成你的目标的四个很好的段反转。显然,如果要交换的单词位于这些位置,则必须注意确保不要在字符串开头之前,也不要超过字符串结尾。


更新:OP 提供的示例。

OP 提供了一个示例,显然不了解上述算法是如何应用的,所以我也在通过该示例运行它

单词

like eat

句子

I like to eat apples

第 1 步:找到这两个词,注意它们的位置和长度。

I like to eat apples
  1111    222

第 2 步:从第一个单词的开头到第二个单词的结尾反转整个片段。因此,下面标有“x”的段:

I like to eat apples
  xxxxxxxxxxx

变成这样:

I tae ot ekil apples
  222    1111

第 3 步:在每个单词都在新位置后反转它们

I eat ot like apples
  222    1111

第 4 步:反转两个词之间的完整段,包括空格。例如。下面标记的部分:

I eat ot like apples
     xxxx

变成这样:

I eat to like apples

你已经完成了。

【讨论】:

  • 我想你误会了,我的意思是:我喜欢吃苹果 -> 我喜欢吃苹果
  • @arnold 我认为你误解了 WhozCraig——答案正是你在评论中所说的。
  • 好的,我会试着理解这个答案!
  • @arnold 请看另一个在Ab Cde Fghij Klmnopq Rst 中交换第二个和第四个单词的示例。首先在字符串中找到两个单词。然后就地反转两个单词以及它们之间的部分(可能为空):Ab edC jihgF qponmlK Rst。最后将它们全部反转为一个子字符串:Ab Klmnopq Fghij Cde Rst。完成。
  • 谢谢,但我使用string) 完成了这项工作
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-09
  • 1970-01-01
  • 2013-01-10
  • 2016-04-26
  • 1970-01-01
相关资源
最近更新 更多