Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 55 additions & 0 deletions YuriyKuznetsov_HomeWork5_ReverseOrRotate.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
// Reverse or rotate
#include <algorithm>
#include <iostream>
#include <string>

void revrot(std::string &inout_sStr, const unsigned int in_cuiPieceSize);

int main() {
std::string myString{"563000655734469485"};
std::cout << myString << '\n';
revrot(myString, 4);
std::cout << myString << '\n';

return 0;
}

void revrot(std::string &inout_sStr, const unsigned int in_cuiPieceSize) {
if (in_cuiPieceSize == 0) {
inout_sStr.clear();

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

а зачем чистить строку?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

так как сказано в задании, что если размер <= 0 вернуть пусто. Вот и чищу, что возвращаю

return;
}
if (in_cuiPieceSize == 1) {
return;

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

а тут не чистим

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

на счет размер == 1 в задании не сказано чтоб возвращать пусто. Но и манипуляции над строкой бессмысленны.

}
if (inout_sStr.length() < in_cuiPieceSize) {
inout_sStr.clear();

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

тоже самое

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ага. Так как длина куска больше длины строки. В задании сказано - чистить

return;
}
size_t szNewLength{(inout_sStr.length() / in_cuiPieceSize) * in_cuiPieceSize};

inout_sStr.resize(szNewLength);

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

а зачем это?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

в задании сказано "проигнорировать последний кусок если размер меньше чем sz". Вот и отбрасываю лишнее


for (size_t szCharIndex = 0; szCharIndex <= (szNewLength - in_cuiPieceSize);
szCharIndex += in_cuiPieceSize) {
std::string sPieceOfString{inout_sStr, szCharIndex, in_cuiPieceSize};
unsigned int uiCriterion{};
for (auto itPieceOfString = sPieceOfString.begin();
itPieceOfString != sPieceOfString.end(); ++itPieceOfString) {
if (!std::isdigit(*itPieceOfString)) {

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

может это в начале сделать перед циклом? а то не понятно мы делаем resize строке, а потом проверяем символы этой строки.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

согласен, можно вынести проверку на то, что в составе строки только цифры в начало

inout_sStr.clear();
return;
}
std::string sOneChar{*itPieceOfString};

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

а обьязательно создавать строку для одного символа?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

функция stoi принимает в качестве аргумента строку, а манипулировать дальше надо с каждым символом строки. Поэтому и было принято такое решение

uiCriterion +=
std::stoi(sOneChar) * std::stoi(sOneChar) * std::stoi(sOneChar);
}
if ((uiCriterion % 2) == 0) {
std::reverse(sPieceOfString.begin(), sPieceOfString.end());
} else {
std::rotate(sPieceOfString.begin(), sPieceOfString.begin() + 1,
sPieceOfString.end());
}
inout_sStr.replace(szCharIndex, in_cuiPieceSize, sPieceOfString);
}
}
189 changes: 189 additions & 0 deletions list_impl.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,189 @@
#include "list_interface.h"

structNode *GetLastEl(const structList &in_oList) {
constexpr size_t csizeOneElem{1};
if (bIsEmpty(in_oList)) {
return nullptr;
}
if (Size(in_oList) == csizeOneElem) {
return in_oList.oFirstNode;
}
structNode *oNode{in_oList.oFirstNode};
while (oNode->oNext != nullptr) {
oNode = oNode->oNext;
}
return oNode;
}

void vPushFront(structList &in_oList, int in_iData) {
structNode *oNode =
new (structNode){}; // make "try" for catching allocation troubles

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
new (structNode){}; // make "try" for catching allocation troubles
new structNode{}; // make "try" for catching allocation troubles

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

промахнулся :)

oNode->iData = in_iData;
if (bIsEmpty(in_oList)) {
in_oList.oFirstNode = oNode;
++in_oList.sizeSize;
return;
}
oNode->oNext = in_oList.oFirstNode;
in_oList.oFirstNode->oPrev = oNode;
in_oList.oFirstNode = oNode;
++in_oList.sizeSize;
}

void vPushBack(structList &in_oList, int in_iData) {
structNode *oNode =
new (structNode){}; // make "try" for catching allocation troubles
oNode->iData = in_iData;
if (bIsEmpty(in_oList)) {
in_oList.oFirstNode = oNode;
++in_oList.sizeSize;
return;
}
structNode *oLastNode{GetLastEl(in_oList)};
oLastNode->oNext = oNode;
oNode->oPrev = oLastNode;
++in_oList.sizeSize;
}

bool bInsert(structList &in_oList, structNode *oCurrentNode, int in_iData) {
if (!bCheckNode(in_oList, oCurrentNode)) {
return false;
}
if (oCurrentNode == in_oList.oFirstNode) {
vPushFront(in_oList, in_iData);
return true;
}
structNode *oNode = new (structNode){}; // make "try"...
oNode->iData = in_iData;
oNode->oPrev = oCurrentNode->oPrev;
oNode->oNext = oCurrentNode;
(oCurrentNode->oPrev)->oNext = oNode;
oCurrentNode->oPrev = oNode;
++in_oList.sizeSize;
return true;
}

// Deleting element
bool bPopFront(structList &in_oList) {
constexpr size_t csizeOneElem{1};

if (bIsEmpty(in_oList)) {
return false;
}
if (Size(in_oList) == csizeOneElem) {
delete in_oList.oFirstNode;
in_oList.oFirstNode = nullptr;
--in_oList.sizeSize;
return true;
}
structNode *oFirstNode{in_oList.oFirstNode};
structNode *oNewFirstNode{in_oList.oFirstNode->oNext};
oNewFirstNode->oPrev = nullptr;
in_oList.oFirstNode = oNewFirstNode;
--in_oList.sizeSize;

delete oFirstNode;
return true;
}

bool bPopBack(structList &in_oList) {
constexpr size_t csizeOneElem{1};

if (bIsEmpty(in_oList)) {
return false;
}
if (Size(in_oList) == csizeOneElem) {
delete in_oList.oFirstNode;
in_oList.oFirstNode = nullptr;
--in_oList.sizeSize;
return true;
}
structNode *oLastNode{GetLastEl(in_oList)};
structNode *oNewLastNode{oLastNode->oPrev};
oNewLastNode->oNext = nullptr;
--in_oList.sizeSize;

delete oLastNode;
return true;
}

bool bErase(structList &in_oList, structNode *oCurrentNode) {
if (!bCheckNode(in_oList, oCurrentNode)) {
return false;
}
if (oCurrentNode == in_oList.oFirstNode) {
return bPopFront(in_oList);
}
if (oCurrentNode == (GetLastEl(in_oList))) {
return bPopBack(in_oList);
Comment on lines +117 to +118

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

я думаю это тут не нужно. Вы добавляете оверхед по том что нужно пробежаться по всему листу а потом если это не последний элемент вы ему переставляете указатели. Думаю пробежка по всему листу явно не надо

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

да, возможно. Тогда нужно проконтроллировать на nullptr при дальнейшем переприсваивании указателей

}

structNode *oPrevNode{oCurrentNode->oPrev};
structNode *oNextNode{oCurrentNode->oNext};
oPrevNode->oNext = oNextNode;
oNextNode->oPrev = oPrevNode;
--in_oList.sizeSize;

delete oCurrentNode;
return true;
}

void vClear(structList &in_oList) {
if (bIsEmpty(in_oList)) {
return;
}
structNode *oNode{GetLastEl(in_oList)};
while (oNode != in_oList.oFirstNode) {
structNode *oTempNode{oNode};
oNode = oTempNode->oPrev;
delete oTempNode;
}

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

а зачем тут два раза бегать сначало в конец а потом в начало?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

идея была - удалять все с конца и потом явно удалить первый нод. Если начать удалять сначала, то мы теряем указатель на первый элемент и, если что-то пойдет не так и часть нод не удалится, то уже потенциально не сможем повторно удалить. При удалении с конца можно дописать возможность возвращения к удалению.

delete in_oList.oFirstNode;
in_oList.oFirstNode = nullptr;
in_oList.sizeSize = 0;
}

structNode *FindByValue(structList &in_oList, const int in_iValue) {
structNode *oNode{in_oList.oFirstNode};
while (oNode->oNext != nullptr) {
if (bEqual(oNode, in_iValue)) {
return oNode;
}
oNode = oNode->oNext;
}
if (bEqual(oNode, in_iValue)) {
return oNode;
}
return nullptr;
}

bool bCheckNode(structList &in_oList, structNode *oNodeToCheck) {
if (bIsEmpty(in_oList)) {
return false;
}
structNode *oNode{in_oList.oFirstNode};
while (oNode->oNext != nullptr) {
if (bEqual(oNodeToCheck, oNode)) {

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

а для этого обьязательно делать отдельную функцию?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ИМХО так нагляднее. К тому же функция эквивалентности перегружена для разных случаев.

return true;
}
oNode = oNode->oNext;
}
if (bEqual(oNodeToCheck, oNode)) {
return true;
}
return false;
}

void vPrintList(const structList &in_oList) {
if (bIsEmpty(in_oList)) {
std::cout << "List is empty\n";
return;
}
structNode *oNode{in_oList.oFirstNode};
std::cout << "List: ";
while (oNode->oNext != nullptr) {
std::cout << oNode->iData << ' ';
oNode = oNode->oNext;
}
std::cout << oNode->iData << " \n";
}
55 changes: 55 additions & 0 deletions list_interface.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
#pragma once

#include <iostream>

struct structNode {
structNode *oPrev{};
int iData;
structNode *oNext{};
};

struct structList {
structNode *oFirstNode{};
size_t sizeSize{};
};

// Element access
inline structNode *GetFirstEl(const structList &in_oList) {
return in_oList.oFirstNode;
};
structNode *GetLastEl(const structList &in_oList);

// Inserting element
void vPushFront(structList &in_oList, int in_iData);
void vPushBack(structList &in_oList, int in_iData);
bool bInsert(structList &in_oList, structNode *oCurrentNode, int in_iData);

// Deleting element
bool bPopFront(structList &in_oList);
bool bPopBack(structList &in_oList);
bool bErase(structList &in_oList, structNode *oCurrentNode);
void vClear(structList &in_oList);

// Compare
inline bool bCmp(structNode *oLess, structNode *oMore) {
return (oLess->iData < oMore->iData);
}
inline bool bEqual(structNode *oFirst, structNode *oSecond) {
return (oFirst->iData == oSecond->iData);
}
inline bool bEqual(structNode *oFirst, int iSecond) {
return (oFirst->iData == iSecond);
}

// Find element
structNode *FindByValue(structList &in_oList, const int in_iValue);

// Capacity
inline size_t Size(const structList &in_oList) { return in_oList.sizeSize; };
inline bool bIsEmpty(const structList &in_oList) {
return (in_oList.sizeSize == 0);
};

// Helpers
bool bCheckNode(structList &in_oList, structNode *oNodeToCheck);
void vPrintList(const structList &in_oList);
33 changes: 33 additions & 0 deletions main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#include "list_interface.h"

int main() {
structList myList{};
int myData{5};
vPrintList(myList);

vPushBack(myList, myData);
vPushFront(myList, 8);
vPushBack(myList, 32);
vPrintList(myList);

bInsert(myList, FindByValue(myList, 5), 123);
vPrintList(myList);

std::cout.setf(std::ios::boolalpha);
std::cout << "First element < Last element?: "
<< bCmp(GetFirstEl(myList), GetLastEl(myList)) << '\n';

bPopBack(myList);
bPopFront(myList);
vPrintList(myList);

vPushBack(myList, 45);
vPushBack(myList, 280);
bErase(myList, FindByValue(myList, 5));
vPrintList(myList);

vClear(myList);
vPrintList(myList);

return 0;
}