Нужно сформировать новую строку из неповторяющихся слов без использования библиотеки string

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <string.h>
#include <stdlib.h>
using namespace std;
int main()
{
    setlocale(LC_ALL, "Russian");
    char x_str[200];
    char x_str2[200] = "";
    char x_copy[200];
    cout << "Введите строку: ";
    cin.getline(x_str, 200);
    cout << "Исходная строка: " << x_str << endl;
    strcpy(x_copy, x_str);
    char* v = strtok(x_str, " ,.-");
    while (v != NULL) {
        cout << v << endl;
        if (strstr(x_copy, v) == NULL) {
            strcat(x_str2, v);
            strcat(x_str2, " ");
        }
        v = strtok(NULL, " ,.-");
    }
    cout << "Сформированная строка: " << x_str2;
    return 0;
}

попробовал как то так, не получается


Ответы (2 шт):

Автор решения: NunOfIt

Получилось, конечно, довольно коряво, но работает...

#include <vector>
#include <clocale>
#include <iostream>

class String {
    int _hash;
    char* _beg;
    char* _end;
    size_t _len;

public:
    String() { (void) _null(); }

    String(char* _beg, char* _end): _beg(_beg), _end(_end), _hash(0), _len(0) {
        for(char* it = _beg; it != _end; ++it) {
            ++_len;
            _hash += *it;
        }
    }

    void copy(char* ptr) {
        if(!_len) { return; }

        for(char* it = _beg; it != _end; ++it, ++ptr)
            *ptr = *it;
    }

    void clear() { (void) _null(); }

    size_t size() const { return _len; }

    bool operator==(const String& other) const {
        if(_hash != other._hash || _len != other._len) { return false; }

        for(size_t i = 0; i < _len; ++i)
            if((*this)[i] != other[i])
                return false;
        return true;
    }

    char& operator[](size_t idx) {
        if(idx >= _len) { throw std::out_of_range("index out of range!"); }
        return *(_beg + idx);
    }
    const char& operator[](size_t idx) const {
        if(idx >= _len) { throw std::out_of_range("index out of range!"); }
        return *(_beg + idx);
    }

private:
    void _null() {
        _len = 0;
        _hash = 0;
        _beg = nullptr;
        _end = nullptr;
    }
};

int main() {
    setlocale(LC_ALL, "");
    const size_t LENGTH = 201;

    char input[LENGTH]{};
    char output[LENGTH]{};
    std::vector<String> vec;

    std::cout << "Введите строку: ";
    std::cin.getline(input, LENGTH - 1);

    bool key = false;
    for(size_t j, k = 0, i = 0; i < LENGTH; ++i)
        if(input[i] == ' ' || input[i] == '\0') {
            if(key) {
                key = false;
                vec.push_back(String(&input[j], &input[i]));
            }
            if(input[i] == '\0') { break; }
        }
        else if(!key) { j = i; key = true; }

    for(size_t i = 0; i < vec.size(); ++i)
        for(size_t j = 0; j < vec.size(); ++j)
            if(i != j && vec[i] == vec[j])
                vec[j].clear();

    size_t i = 0;
    for(String& str: vec)
        if(str.size()) {
            str.copy(&output[i]);
            i += str.size();
            output[i++] = ' ';
        }
    if(i) { output[--i] = '\0'; }

    std::cout << "Результат: " << output << '\n';
    return 0;
}
→ Ссылка
Автор решения: Harry

Вот самая простая и не очень эффективная переделка вашего кода:

int main()
{
    char   x_str[200];
    char   x_str2[200] = "";
    char*  wptr[100] = {}; // За глаза хватит...
    int    words = 0;

    cout << "Input string: ";
    cin.getline(x_str, 200);

    for(char* v = strtok(x_str, " ,.-"); v; v = strtok(NULL, " ,.-"))
    {
        bool found = false;
        for(int i = 0; i < words; ++i)
            if (strcmp(wptr[i],v)==0)
            {
                found = true;
                break;
            }
        if (!found)
        {
            wptr[words++] = v;
            strcat(x_str2, v);
            strcat(x_str2, " ");
        }
    }
    cout << "Result string: " << x_str2;
}
→ Ссылка