简体   繁体   中英

Swap words in string C++

I'm a new StackOverflow user. i need help. My task is to find two verbs in the string that are in the list ( _words[] ) and swap them. With string it's not that hard to implement, but I'm only allowed to use char .

My idea is this: I split the char ( char str[] ) array into words, and assign each word to a constant array( str2[] ), I do the same with known verbs. Next, I check - if the word in the first array matches the known verb, then I assign the number ( j ) to an integer array in order to know the location of this word. Well, then, with the help of a bubble method, I change their places. But that's bad luck, I looked through the debugger, and for some reason when comparing words, even though the words are the same, the check does not pass. (sorry for my English)

Could you help me figure out what I'm doing wrong? I will be grateful!

#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] << " ";
    }
}

Posted only because the OP asked for an alternative algorithm of how this can be done. There are other ways, but this has the benefit of being done entirely in place, using no additional storage besides some pointers and some lengths.

This task can be done in-place, by using a utility function to reverse a character sequence, given a pointer and length (or two pointers). You must have numerous other reliable operations at your disposal as well, including the ability to find complete words. (eg words that are preceded by whitespace or begin-of-string, and succeeded by whitespace or end-of-string. Write those, and test them thoroughly . Once you've done that, consider the following.

String

this is a very simple sample of words

Test Words

very of

We start by separating our two words, which you're already doing. Next we find both words, remembering their locations, using your well-tested utility functions. We know their lengths, so we can therefore calculate where they begin, and where they end.

this is a very simple sample of words
          1111               22

Side note: When doing this, you'll discover the order may be backward. For example, if your word list was of very , then the result would have your word positions looking like this:

this is a very simple sample of words
          2222               11

It doesn't matter, all that matters is that once you find both words, the word closest to the beginning of the string is the "first" word, and the one coming later is the "second" word from here on out.

That said (and now back to our original labeling), reverse the entire segment from the beginning of the first word through the end of the second word, not including any whitespace preceding the first, or succeeding the second:

this is a fo elpmas elpmis yrev words
          22               1111

Next, reverse the two words in-place at their new homes.

this is a of elpmas elpmis very words
          22               1111

And finally, reverse all characters past the end of the new first word until (but not including) the beginning of the new second word, including whitespace That means this region:

this is a of elpmas elpmis very words
            xxxxxxxxxxxxxxx

and it becomes this:

this is a of simple sample very words

That's the entire algorithm. Once you find your word locations and extents you're literally four well-place segment reversals from accomplishing your goal. Obviously, care must be undertaken to ensure you do not precede before beginning of string, nor exceed past the end-of-string, should your words being swapped reside in those locations.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM