1

Тема: Шаблонний клас і робота з int/string масивом

Всім привіт.
Писав ось такий шаблонний клас:

Код. Оголошення класу
template <typename TData>
class CArray
{
public: // Interface
    CArray();
    CArray(size_t size);
    CArray(const CArray & _array);
    ~CArray();
    void push_back(const TData& _value);
    void insert(unsigned int  _index, const TData & _value);
    void erase(unsigned int _index);
    void clear();
    unsigned int size() const;
    TData& operator[](unsigned int _index);
    void SetIntArray();
    void SetStrArray();
    void GetArray();
    void sort();

private:
    int m_Size; // розмір
    TData* m_Array; // вказівник на масив
    TData m_Top; // перший елемент масиву
};

Визначення класу:

Код. Визначення класу
#include "stdafx.h"
#include "CArray.h"

using namespace std;

using namespace std;

//коструктор по замовчуванню
template <typename TData>
CArray<TData>::CArray()
{
    m_Size = 1;
    m_Array = new TData[m_Size];
    for (int i = 0; i < m_Size; i++)
        m_Array[i] = 0;
}

//конструктор з 1 параметром
template <typename TData>
CArray<TData>::CArray(size_t size)
{
    m_Size = size;
    m_Array = new TData[m_Size];
    m_Top = -1; // масив порожній
    for (int i = 0; i < m_Size; i++)
        m_Array[i] = 0 || ' ';
}

//конструктор копіювання
template <typename TData>
CArray<TData>::CArray(const CArray & _array)
{
    m_Array = new CArray<TData>(*(_array.m_Array));
    m_Size = _array.m_Size;
}

//деструктор
template <typename TData>
CArray<TData>::~CArray()
{
    delete[] m_Array;
}

//добавити елемент в кінець масиву
template <typename TData>
void CArray<TData>::push_back(const TData& _value)
{
    m_Top += 1;
    if (m_Array[m_Top] != 0) // чи існує останній елемент
    {
        cout << "> push_back(): Array is fullest. You can't add new element. But you can set new data instead first element." << endl;
        while (true)
        {
            cout << "Do that? (y/n) - ";
            char choose;
            cin >> choose;
            if (choose == 'y')
            {
                m_Array[m_Top] = _value;
                cout << "> push_back(): Element added instead first." << endl;
                break;
            }
            else if (choose == 'n')
            {
                cout << "> push_back(): peration is denied." << endl;
                break;
            }
            else
                cout << "> push_back(): Illegal symbol." << endl;
        }
    }
    else
    {
        cout << "> push_back(): Element added succesfully." << endl;
        m_Array[m_Top] = _value; // записуємо елемент в масив
    }
}

//вставити елемент по індексу
template <typename TData>
void CArray<TData>::insert(unsigned int  _index,const TData& _value)
{
    char choose;
    do
    {
        cout << "Warning! If array is full the last element will be uninstalled. Continue? (y/n) - ";
        cin >> choose;
        if (choose == 'y')
        {
            for (int i = m_Size; i >= _index; i--)
            {
                m_Array[i] = m_Array[i - 1]; //зсуваємо
            }
            m_Array[_index] = _value; //записуємо задані дані
            break;
        }
        else if (choose == 'n')
        {
            cout << "> insert(): Operation is denied." << endl;
            break;
        }
        else
            cout << "> insert(): Illegal symbol." << endl;
    } while (choose != 'n');
}

//видалити елемент по індексу
template <typename TData>
void CArray<TData>::erase(unsigned int _index)
{
    if (m_Array[_index] != 0) //якщо елемент існує
    {
        for (long i = _index; i < m_Size; ++i)
        {
            m_Array[i] = m_Array[i + 1]; //зсуваємо
        }
        m_Array[m_Size - 1] = 0 || '0'; //останній - 0
        cout << "> erase(): Element indexed " << _index << " was erased" << endl;
    }
    else
        cout << "> erase(): Element is not exist." << endl;
}

//очистити масив
template <typename TData>
void CArray<TData>::clear()
{
    char choose;
    do
    {
    cout << "Warning! All items are deleted. Continue? (y/n) - ";
    cin >> choose;
    if (choose == 'y')
    {
        memset(m_Array, 0, m_Size * sizeof(*m_Array));//видаляємо всі елементи
        cout << "> clear(): Array is empty." << endl;
        break;
    }
    else if (choose == 'n')
    {
        cout << "> clear(): Operation is denied." << endl;
        break;
    }
    else
        cout << "> insert(): Illegal symbol." << endl;
    } while (choose != 'n');
}

//повернення розміру масиву
template <typename TData>
unsigned int CArray<TData>::size() const
{
    cout << "> size(): Size of array is ";
    return m_Size;
}

//перевантаження оператора індексування
template <typename TData>
TData& CArray<TData>::operator[](
    unsigned int _index
    )
{
    return m_Array[_index - m_Size];
}

//заповнення масиву
template <typename TData>
void CArray<TData>::SetIntArray()
{
    srand(static_cast<unsigned int>(time(NULL)));
    char choose;
    cout << "Warning! The size of the array is limited. If you do not want to completely fill an array write list the rest of the data as 0." << endl;
    cout << "Do you want to enter data manually or randomly? (m/r) - ";
    cin >> choose;
    while (true)
    {
        if (choose == 'm')
        {
            cout << "Input " << m_Size << " data through space: ";
            for (int i = 0; i < m_Size; i++)
            {
                cin >> m_Array[i]; //заповнити вручну
            }
            break;
        }
        else if (choose == 'r')
        {
            cout << "> SetArray(): Entering data randomly... " << endl;
            for (int i = 0; i < m_Size; i++)
            {
                int val = rand() % 100;
                m_Array[i] = val; //заповнити рандомно
            }
            cout << "> SetArray(): Entered." << endl;
            break;
        }
        else
        {
            cout << "> SetArray(): Illegal symbol.\nDo you want to enter data manually or randomly? (m/r) - ";
            cin >> choose;
        }
    }
}

template <typename TData>
void CArray<TData>::SetStrArray()
{
    srand(static_cast<unsigned int>(time(NULL)));
    char choose;
    cout << "Warning! The size of the array is limited. If you do not want to completely fill an array write list the rest of the data as 0." << endl;
    cout << "Do you want to enter data manually or randomly? (m/r) - ";
    cin >> choose;
    while (true)
    {
        if (choose == 'm')
        {
            cout << "Input " << m_Size << " data through space: ";
            for (int i = 0; i < m_Size; i++)
            {
                cin >> m_Array[i]; //заповнити вручну
            }
            break;
        }
        else if (choose == 'r')
        {
            cout << "> SetArray(): Entering data randomly... " << endl;
            string words[32] = { "cat ", "dog ", "bike ", "moon ", "file ", "language ", "cake ", "resource ",
                "low ", "find ", "break ", "alpha ", "cpp ", "scope ", "target ", "write ", "read ", "test ", "window ", "array ",
                "hight ", "left ", "rigth ", "new ", "old ", "dad ", "mum ", "car ", "plane ", "table ", "computer ", "programming " };
            random_shuffle(begin(words), end(words));
            for (int i = 0; i < m_Size; i++)
                m_Array[i] = words[i]; //заповнити рандомно
            cout << "> SetArray(): Entered." << endl;
            break;
        }
        else
        {
            cout << "> SetArray(): Illegal symbol.\nDo you want to enter data manually or randomly? (m/r) - ";
            cin >> choose;
        }
    }
}

//сортування по зростанню
template <typename TData>
void CArray<TData>::sort()
{
    TData temp;
    int i;
    cout << "> sort(): Sorting array..." << endl;
    for (int x = 1; x < m_Size; x++)
    {
        temp = m_Array[x];
        for (i = x; temp < m_Array[i - 1] && i != 0; i--)
            m_Array[i] = m_Array[i - 1];
        m_Array[i] = temp;
    }
    cout << "> sort(): Sorted." << endl;
}

template <typename TData>
void CArray<TData>::GetArray()
{
    cout << "Array is: ";
    for (int i = 0; i < m_Size; i++)
        cout << setw(4) << m_Array[i];
    cout << endl;
}

Main функція:

Код. Main
void intArr();
void stringArr();

int main()
{
    int chooseArr;
    do
    {
        cout << "Main menu:" << endl;
        cout << "0 - Exit." << endl;
        cout << "1 - Create new int array." << endl;
        cout << "2 - Create new string array." << endl;
        cout << "Choose: ";
        cin >> chooseArr;
        switch (chooseArr)
        {
        case 0:
            break;
        case 1:
            intArr();
            break;
        case 2:
            stringArr();
            break;
        default:
            cout << "Illegal symbol." << endl;
            break;
        }
    } while (chooseArr != 0);
    
    return 0;
}

void intArr()
{
    int size, newData, index;
    cout << "Enter size: ";
    cin >> size;

    CArray<int> myIntArray(size);

    int chooseMenu;
    cout << "intArr() function menu:" << endl;
    cout << "0 - Exit." << endl;
    cout << "1 - Put data of array." << endl;
    cout << "2 - Find out array size." << endl;
    cout << "3 - View array." << endl;
    cout << "4 - Push new data." << endl;
    cout << "5 - Insert data." << endl;
    cout << "6 - Erase data." << endl;
    cout << "7 - Clean." << endl;
    cout << "8 - Sort." << endl;
    do
    {
        cout << "Choose: ";
        cin >> chooseMenu;
        switch (chooseMenu)
        {
        case 0:
            break;
        case 1:
            myIntArray.SetIntArray();
            break;
        case 2:
            cout << myIntArray.size() << endl;
            break;
        case 3:
            myIntArray.GetArray();
            break;
        case 4:
            cout << "Enter new data - ";
            cin >> newData;
            myIntArray.push_back(newData);
            break;
        case 5:
            cout << "Enter data - ";
            cin >> newData;
            cout << "Enter index - ";
            cin >> index;
            myIntArray.insert(index, newData);
            break;
        case 6:
            cout << "Enter index to erase - ";
            cin >> index;
            myIntArray.erase(index);
            break;
        case 7:
            myIntArray.clear();
            break;
        case 8:
            myIntArray.sort();
            break;
        default:
            cout << "Illegal symbol." << endl;
            break;
        }
    } while (chooseMenu != 0);
}

void stringArr()
{
    int size, index;
    string newData;
    cout << "Enter size: ";
    cin >> size;

    CArray<string> myStrArray(size);

    int chooseMenu;
    cout << "intArr() function menu:" << endl;
    cout << "0 - Exit." << endl;
    cout << "1 - Put data of array." << endl;
    cout << "2 - Find out array size." << endl;
    cout << "3 - View array." << endl;
    cout << "4 - Insert data." << endl;
    cout << "5 - Clean." << endl;
    cout << "6 - Sort." << endl;
    do
    {
        cout << "Choose: ";
        cin >> chooseMenu;
        switch (chooseMenu)
        {
        case 0:
            break;
        case 1:
            myStrArray.SetStrArray();
            break;
        case 2:
            cout << myStrArray.size() << endl;
            break;
        case 3:
            myStrArray.GetArray();
            break;
        case 4:
            cout << "Enter data - ";
            cin >> newData;
            cout << "Enter index - ";
            cin >> index;
            myStrArray.insert(index, newData);
            break;
        case 5:
            myStrArray.clear();
            break;
        case 6:
            myStrArray.sort();
            break;
        default:
            cout << "Illegal symbol." << endl;
            break;
        }
    } while (chooseMenu != 0);
}

Про проект: я створюю об'єкти масиву типу int/string і виконую певні операції над ними - записати елементи, очистити, сортувати і т.д.
Проблема: проблем, по суті, немає. Точніше з int проблем немає. А для string об'єкта мені необхідно видалити з масиву слово, що містить певну букву. В процесі програми я заповнюю масив випадковими словами. Я пробував написати функцію, яка проходить по масиву типу string, і звіряє елементи масиву на наявність букви. Якщо така буква зустрічається в слові, то це слово видаляється, а решта елементів в масиві зміщуються. Ось тут і виникає питання.
Питання: як визначити чи знаходиться конкретна буква в слові? Нагадую, масив складається з слів, і відповідно при проходженні циклу я перевіряю цілі слова, а як перевірити саме слово на наявність потрібної букви?

Що пробував

Пробував різні методи: проходження подвійним циклом, запис в строку і назад в масив (це мало б працювати або я криво-мило зроби), STL (можливо не знаю потрібної функції) та ін.

Прикріпив файл коду:

Post's attachments

Carray.cpp 9.34 kb, 307 downloads since 2017-04-19 

2

Re: Шаблонний клас і робота з int/string масивом

А метод std::string::find() чим вас не влаштував?
http://www.cplusplus.com/reference/string/string/find/

Подякували: koala, varkon, LoganRoss3

3 Востаннє редагувалося LoganRoss (20.04.2017 21:11:28)

Re: Шаблонний клас і робота з int/string масивом

Arete написав:

А метод std::string::find() чим вас не влаштував?
http://www.cplusplus.com/reference/string/string/find/

Пробував, працює не так як треба. Дякую за відгук.
Але задачу вирішив. Мудрено, правда, але працює як треба.

Код функції
template <typename TData>
void CArray<TData>::eraseStr()
{
    string current;
    string get;
    string symbols = "abcde";
    bool deleteWord = false;
    for (int i = 0; i < m_Size; i++)
        current += m_Array[i];
    int pos = 0;
    int j, lastSpace, iter;
    lastSpace = 0;
    for (int i = 0; i < current.size(); i++) 
    {
        lastSpace += sizeof(current[i]);
        if (current[i] == ' ' || current.size() - 1 == i)
        {
            for (j = 1; j < lastSpace; )
            {
                for (int a = 0; a < symbols.size(); a++)
                {
                    if (current[i - j] == symbols[a])
                    {
                        deleteWord = true;
                        break;
                    }
                }
                j++;
                if (deleteWord == true)
                    break;
            }
            if (!deleteWord)
            {
                for (; pos <= i; pos++) 
                    get += current[pos];
                pos = i;
            }
            else 
            {
                pos = i;
                deleteWord = false;
            }
            lastSpace = 0;
        }
    }
    if (!get.empty())
        cout << "> eraseStr(): Erased. Click 3 to watch." << endl;
    else
        cout << "> eraseStr(): Empty. All words contain symbol a, b, c, d or e" << endl;
    memset(m_Array, 0, m_Size * sizeof(*m_Array));
    for (int i = 0; i < m_Size; i++)
        *m_Array = get;
}

Скрін, як працює:

Post's attachments

test.PNG 29.6 kb, 197 downloads since 2017-04-20