交换字符串 C++ 中的单词

Swap words in string C++

我是 Whosebug 的新用户!我需要帮助。我的任务是在字符串中找到列表中的两个动词 (_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] << " ";
    }
}

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

这个任务可以完成 in-place,通过使用一个实用函数来反转字符序列,给定一个指针和长度(或两个指针)。您还必须拥有许多其他可靠 操作,包括查找完整 单词的能力。 (例如,前面是空格或 begin-of-string,后面是空格或 end-of-string 的单词。写下这些,然后 彻底测试 。一旦你完成了, 请考虑以下内容。

字符串

this is a very simple sample of words

测试词

very of

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

this is a very simple sample of words
          1111               22

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

this is a very simple sample of words
          2222               11

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

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

this is a fo elpmas elpmis yrev words
          22               1111

接下来在他们的新家把两个字in-place反过来

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

这就是整个算法。一旦找到单词的位置和范围,您就可以完成四个 well-place 段反转来实现您的目标。显然,必须注意确保您不在字符串开头之前,也不超过 end-of-string,如果您要交换的单词位于这些位置。


更新:OP-provided样本。

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

大功告成。