I have a struct defined as follows
struct VariableList
{
void Add(simple_instr* instr)
{
//PrintOpcode(instr);
switch(instr->opcode)
{
case STR_OP:
case MCPY_OP:
Add(instr->u.base.src1);
Add(instr->u.base.src2);
break;
case LDC_OP:
Add(instr->u.ldc.dst);
break;
case BTRUE_OP:
case BFALSE_OP:
Add(instr->u.bj.src);
break;
case CALL_OP:
if (instr->u.call.dst != NO_REGISTER)
{
Add(instr->u.call.dst);
}
Add(instr->u.call.proc);
for (int i = 0; i < instr->u.call.nargs; i++)
{
Add(instr->u.call.args[i]);
}
break;
case MBR_OP:
Add(instr->u.mbr.src);
break;
case RET_OP:
if (instr->u.base.src1 != NO_REGISTER)
Add(instr->u.base.src1);
break;
case CVT_OP:
case CPY_OP:
case NEG_OP:
case NOT_OP:
case LOAD_OP:
Add(instr->u.base.dst);
Add(instr->u.base.src1);
break;
case LABEL_OP:
case JMP_OP:
break;
default:
Add(instr->u.base.dst);
Add(instr->u.base.src1);
Add(instr->u.base.src2);
break;
}
}
void Add(Variable var)
{
variableList.push_back(var);
}
void RemoveDuplicates()
{
if (variableList.size() > 0)
{
variableList.erase(unique(variableList.begin(), variableList.end()), variableList.end());
currentID = variableList.size();
}
}
VariableList()
{
currentID = 0;
dynamicallyCreated = false;
}
VariableList(VariableList& varList, bool setLiveness = false, bool LiveVal = false)
{
currentID = 0;
for (int i = 0; i < varList.size(); i++)
{
Variable* var = new Variable(varList[i]);
if (setLiveness)
{
var->isLive = LiveVal;
}
variableList.push_back(*var);
}
dynamicallyCreated = variableList.size() > 0;
}
Variable& operator[] (int i)
{
return variableList[i];
}
int size()
{
return variableList.size();
}
vector<Variable>::iterator begin()
{
return variableList.begin();
}
vector<Variable>::iterator end()
{
return variableList.end();
}
bool CompareLiveness(VariableList &var)
{
if(variableList.size() != var.size())
{
return false;
}
for (int i = 0; i < variableList.size(); i++)
{
if(variableList[i].isLive != var[i].isLive)
return false;
}
return true;
}
~VariableList()
{
if(dynamicallyCreated)
{
for (vector<Variable>::iterator it = variableList.begin(); it < variableList.end(); ++it)
{
//delete (&it);
}
}
}
protected:
int currentID;
vector<Variable> variableList;
bool dynamicallyCreated;
void Add(simple_reg* reg, bool checkForDuplicates = false)
{
if (reg == null)
{
cout << "null detected" << endl;
return;
}
if (reg->kind == PSEUDO_REG)
{
if (!checkForDuplicates || (checkForDuplicates && find(variableList.begin(), variableList.end(), reg->num) != variableList.end()))
{
cout << "Adding... Reg " << reg->num << endl;
Variable* var = new Variable(reg->num, currentID);
variableList.push_back(*var);
currentID++;
}
}
}
};
I'd like to be able to do a statement like this
VariableList varsIn(Variables, true, false);
that will create a deep copy and allow me to change a few properties. As you can see in my struct, I'm currently attempting to do this using
VariableList(VariableList& varList, bool setLiveness = false, bool LiveVal = false)
{
currentID = 0;
for (int i = 0; i < varList.size(); i++)
{
Variable* var = new Variable(varList[i]);
if (setLiveness)
{
var->isLive = LiveVal;
}
variableList.push_back(*var);
}
dynamicallyCreated = variableList.size() > 0;
}
I don't think this is the right way to do it though. What's the proper way to do this sort of copying? Is there a way to do it without using new? For reference, the Variable struct is as follows
struct Variable
{
int id;
int num;
bool isLive;
simple_op opcode;
Variable()
{
id = 0;
num = 0;
opcode = NOP_OP;
vClass = Basic;
isLive = false;
}
Variable(int _num, int _id = 0, simple_op _op = NOP_OP)
{
id = _id;
num = _num;
opcode = _op;
vClass = Basic;
isLive = false;
}
VariableClass GetClass()
{
return vClass;
}
bool operator==(const Variable &var) const
{
return num == var.num;
}
bool operator==(const int &x) const
{
return x == num;
}
protected:
VariableClass vClass;
};
VariableClass and simple_op are enums
Thanks in advance
Your code is not only doing dynamic allocation unnecessarily, it's also leaking Variable instances everywhere. Just use an automatic variable, push_back will make a copy:
VariableList(VariableList& varList, bool setLiveness = false, bool LiveVal = false)
{
currentID = 0;
for (int i = 0; i < varList.size(); i++)
{
Variable var(varList[i]);
if (setLiveness)
{
var.isLive = LiveVal;
}
variableList.push_back(var);
}
}
And take out the destructor, you can't delete the elements owned by the vector. If they pointed somewhere, sure, but you're not storing pointers.
Also, here's an even better way:
VariableList(VariableList& other, bool setLiveness = false, bool LiveVal = false)
: currentID(0)
, variableList(other.variableList)
{
if (setLiveness) {
for( int i = 0; i < size(); i++ )
variableList[i].isLive = LiveVal;
}
}
Related
I'm trying forward declare my functions in a namespace. But I get an error.
Let me show my .h and .cpp files first.
Header:
namespace DeviceList
{
int GetIDFromType(NNBSSString type);
NNBSSString GetTypeFromID(int id);
void CNNBSSDeviceListAddDevice(NNBSSString& DeviceName, NNBSSString& Address, int DeviceType,
__STRING__ DeviceNetName, __STRING__ DevicePath);
void CNNBSSDeviceListRemoveSelected();
void CNNBSSDeviceListRemoveCache(int index);
inline void CNNBSSDeviceListAddressConnectionRespond(NNBSSString& deviceAddress, bool OK, NNBSSThread* thread);
void CNNBSSDeviceListUpdate();
}
And Source file:
namespace DeviceList
{
int GetIDFromType(NNBSSString type)
{
int m_id;
if (type == _("USB Camera"))
{
m_id = NNBSS_EVT_DEVICETYPE_USBCAM;
}
else if (type == _("IP Camera"))
{
m_id = NNBSS_EVT_DEVICETYPE_IPCAM;
}
else if (type == _("Microphone"))
{
m_id = NNBSS_EVT_DEVICETYPE_MICROPHONE;
}
else if (type == _("DVR"))
{
m_id = NNBSS_EVT_DEVICETYPE_DVR;
}
else if (type == _("NVR"))
{
m_id = NNBSS_EVT_DEVICETYPE_NVR;
}
else
{
m_id = -100;
NNBSSErrorShow("Given DeviceType was wrong while getting int from NNBSSString!", 100);
}
return m_id;
}
NNBSSString GetTypeFromID(int id)
{
// Has to be given by using GetIDFromEnum
NNBSSString m_type;
switch (id)
{
case NNBSS_EVT_DEVICETYPE_USBCAM:
m_type = _("USB Camera");
break;
case NNBSS_EVT_DEVICETYPE_IPCAM:
m_type = _("IP Camera");
break;
case NNBSS_EVT_DEVICETYPE_MICROPHONE:
m_type = _("Microphone");
break;
case NNBSS_EVT_DEVICETYPE_DVR:
m_type = _("DVR");
break;
case NNBSS_EVT_DEVICETYPE_NVR:
m_type = _("NVR");
break;
default:
NNBSSErrorShow("Given DeviceType was wrong while getting NNBSSString from int!", 100);
break;
}
return m_type;
}
void CNNBSSDeviceListAddDevice(NNBSSString& DeviceName, NNBSSString& Address, int DeviceType,
__STRING__ DeviceNetName = __STRING__(), __STRING__ DevicePath = __STRING__())
{
SCNNBSSDeviceParameters params;
params.DeviceName = DeviceName;
params.Address = Address;
params.DeviceType = DeviceType;
params.DeviceNetName = DeviceNetName;
params.DevicePath = DevicePath;
SCNNBSSDeviceParametersList.emplace_back(params);
{
CNNBSSHardwareCheckCameraConnection* p_CNNBSSHardwareCheckCameraConnection =
new CNNBSSHardwareCheckCameraConnection(Address);
p_CNNBSSHardwareCheckCameraConnection->Run();
}
// Update all pages that have Device List active
for (int c = 0; c < (int)m_NNBSSContentPanelList.size(); c++)
{
int pageID = c - 1;
pageID < 0 ? pageID = 0 : pageID = c - 1;
if (CNNBSSDeviceListAddressHandle(m_NNBSSContentPanelList[c])->_IsCreated)
{
CNNBSSDeviceListAddressHandle(m_NNBSSContentPanelList[c])->_RecreateList();
}
}
}
void CNNBSSDeviceListRemoveSelected()
{
if (CNNBSSDeviceListAddressHandle(CNNBSSControlPanelAddressHandle()->_GetCurrentContentPanel())->_IsCreated)
{
CNNBSSDeviceListAddressHandle(CNNBSSControlPanelAddressHandle()->_GetCurrentContentPanel())
->_RemoveSelectedFromList();
}
// Update all pages that have Device List active
for (int c = 0; c < (int)m_NNBSSContentPanelList.size(); c++) {
int pageID = c - 1;
pageID < 0 ? pageID = 0 : pageID = c - 1;
if (CNNBSSDeviceListAddressHandle(m_NNBSSContentPanelList[c])->_IsCreated)
{
CNNBSSDeviceListAddressHandle(m_NNBSSContentPanelList[c])->_RecreateList();
}
}
}
void CNNBSSDeviceListRemoveCache(int index)
{
if (index < 0)
{
index = 0;
}
if (SCNNBSSDeviceParametersList.size() < index)
{
index = (int)SCNNBSSDeviceParametersList.size();
}
auto itr = SCNNBSSDeviceParametersList.begin();
std::advance(itr, index);
if (itr != SCNNBSSDeviceParametersList.end())
{
SCNNBSSDeviceParametersList.erase(itr);
}
}
void CNNBSSDeviceListAddressConnectionRespond(NNBSSString& deviceAddress, bool OK, wxThread* thread)
{
for (int c = 0; c < (int)SCNNBSSDeviceParametersList.size(); c++)
{
if (SCNNBSSDeviceParametersList[c].Address == deviceAddress)
{
if (OK)
{
SCNNBSSDeviceParametersList[c].DeviceConnectionStatus = NNBSS_DEVICE_CONNECTION_STATUS_STRING_ONLINE;
}
else
{
SCNNBSSDeviceParametersList[c].DeviceConnectionStatus = NNBSS_DEVICE_CONNECTION_STATUS_STRING_UNKNOWNERROR;
}
break;
}
}
// Update all pages that have Device List active
for (int c = 0; c < (int)m_NNBSSContentPanelList.size(); c++)
{
int pageID = c - 1;
pageID < 0 ? pageID = 0 : pageID = c - 1;
if (CNNBSSDeviceListAddressHandle(m_NNBSSContentPanelList[c])->_IsCreated)
{
CNNBSSDeviceListAddressHandle(m_NNBSSContentPanelList[c])->_RecreateList();
}
}
// Delete thread
thread->Delete();
delete thread;
}
void CNNBSSDeviceListUpdate()
{// Whenever a USB device is connected, this function will be called automatically
{
std::vector<__STRING__> currentDevices, currentDevicePaths;
CNNBSSHardwareAddressHandle()->GetConnectedUSBCameraList(currentDevices, currentDevicePaths);
// Update all pages that have Device List active
for (int c = 0; c < (int)m_NNBSSContentPanelList.size(); c++)
{
int pageID = c - 1;
pageID < 0 ? pageID = 0 : pageID = c - 1;
if (CNNBSSDeviceListAddressHandle(m_NNBSSContentPanelList[c])->_IsCreated)
{
CNNBSSDeviceListAddressHandle(m_NNBSSContentPanelList[c])->_RecreateList();
}
}
}
}
The problem is, when I remove inline keyword before CNNBSSDeviceListAddressConnectionRespond function, compiler throws an error though for others compiler does not do the same. I wonder, why others works without inline but not CNNBSSDeviceListAddressConnectionRespond function?
Additionally, the complete error message:
Severity Code Description Project File Line Suppression State
Error LNK1169 one or more multiply defined symbols found NNBSS NNBSS\Build\Debug\NNBSS.exe 1
Error LNK2005 "void __cdecl DeviceList::CNNBSSDeviceListAddressConnectionRespond(class NNBSSString &,bool,class NNBSSThread *)" (?CNNBSSDeviceListAddressConnectionRespond#DeviceList##YAXAEAVNNBSSString##_NPEAVNNBSSThread###Z) already defined in ClassManager.obj NNBSS NNBSS\Build\Thread.obj 1
I use include guards.
And my header file is included by over 128 files.
If anything's missing here, let me know
It seems you are using VS2019. I had the same problem and as internet says we're not alone. So, it's a bug that will be fixed once you rebuild the project.
I use Google’s dense_hash_map as a cache of some data. When I use the find function to find a key, I find that it doesn’t exist, but when traversing dense_hash_map, I can see that the key exists. Is it wrong where I used it? By the way, I have rewritten the EqualKey class required by dense_hash_map.
This is my test code:
class StringVal {
public:
StringVal(string &str) {
len = str.length();
ptr = new uint8_t[len];
memcpy(ptr, str.c_str(), len);
}
StringVal(uint8_t* ptr = NULL, int len = 0) : len(len), ptr(ptr) {
if(ptr == NULL) {
is_null = NULL;
}
}
StringVal(const char* ptr) : len(strlen(ptr)),ptr(const_cast<uint8_t*>(reinterpret_cast<const uint8_t*>(ptr))) {
if(ptr == NULL) {
is_null = NULL;
}
}
~StringVal() {
delete[] ptr;
}
uint8_t* ptr;
int len;
bool is_null;
static StringVal null() {
StringVal sv;
sv.is_null = true;
return sv;
}
bool operator==(const StringVal& other) const {
if (is_null != other.is_null) return false;
if (is_null) return true;
if (len != other.len) return false;
return ptr == other.ptr || memcmp(ptr, other.ptr, len) == 0;
}
bool operator!=(const StringVal& other) const { return !(*this == other); }
};
struct NewStringValCmp {
bool operator()(const StringVal* s1, const StringVal* s2) const {
if (s1 == NULL && s2 == NULL) return 1;
if (s1 == NULL || s2 == NULL) return 0;
if (s1->is_null != s2->is_null) return false;
if (s1->is_null) return true;
if (s1->len != s2->len) return false;
return memcmp(s1->ptr, s2->ptr, s1->len) == 0;
}
};
typedef dense_hash_map<StringVal*, StringVal*, std::hash<StringVal*>, NewStringValCmp> new_dict_map_string_t;
vector<string> data = {
"test1","1",
"test2","2",
"test3","3",
"test4","4",
"test5","5",
"test6","6",
"test7","7",
"test8","8",
"test9","9",
"test10","10"
};
int main() {
new_dict_map_string_t* cm = new new_dict_map_string_t();
cm->set_empty_key(NULL);
for (int i = 0; (i + 1) < data.size(); i+=2) {
StringVal *key = new StringVal(data[i]);
StringVal *value = new StringVal(data[i+1]);
(*cm)[key] = value;
}
string input = "";
while (1) {
cin >> input;
if (input == "q") {
break;
}
StringVal *target = new StringVal(input);
for (auto itor: *cm) {
if (*(itor.first) == *target) {
cout << "find target" << endl;
}
}
auto itor = cm->find(target);
if (itor == cm->end()) {
cout << "cm->find nothing" << endl;
} else {
cout << itor->second->ptr << endl;
}
delete target;
input = "";
}
for (auto iter : *cm) {
delete iter.first;
delete iter.second;
}
delete cm;
return 0;
}
I have method of class Stack, which compares 2 objects of this class:
bool comparison(T &stack) {
if (size == stack.size)
for (int i = 0; i < size; i++) {
if (!this->stackPr[i].comparison(stack.stackPr[i]))
return false;
}
else
return false;
return true;
}
and uses the method of class Time:
bool comparison(Time &time) {
if ((this->hours == time.hours) && (this->minutes == time.minutes) && (this->seconds == time.seconds))
return true;
return false;
When I try to use this comman in main:
bool temp = stack3.comparison(stack4);
MVS underlines |stack4| and shows me the error:
a reference of type "Time &"(non-const qualified) cannot be initialized with a value of type Stack<Time>
How could I handle this problem?
Thanks for your answers :)
There is class Stack:
class Stack {
private:
T *stackPr;
int size;
int top;
public:
//----------------CONSTRUCTORS-----------------
Stack(int n) {
if (n > 0)
size = n;
else
size = 10;
stackPr = new T[size];
top = -1;
}
Stack() {
size = 10;
stackPr = new T[size];
top = -1;
}
Stack(Stack &stack) {
stackPr = new T[stack.size];
size = stack.size;
top = stack.top;
for (int i = 0; i < size; i++)
stackPr[i] = stack.stackPr[i];
}
Stack(T *objs, int sizeMass) {
size = sizeMass;
stackPr = new T[size];
for (int i = 0; i < sizeMass; i++) {
this->push(objs[i]);
}
}
//----------------DESTRUCTOR-------------------
~Stack() {
delete[] stackPr;
}
//-----------------METHODS---------------------
//Add element to stack
void push(T &element) {
if (top == size - 1)
cout << "\nThere's no more place!!!\n";
else {
top++;
stackPr[top] = element;
cout << "\nElement was succesfully pushed\n";
}
}
//Read + Delete
T pop() {
if (top == -1)
cout << "\nStack is empty\n";
else {
T temp = stackPr[top];
stackPr[top] = 0;
top--;
cout << "\nElement was succesfully poped and deleted\n";
return temp;
}
}
//Read
T popup() {
if (top == -1)
cout << "\nStack is empty\n";
else {
cout << "\nElement was succesfully popped\n";
return stackPr[top];
}
}
//Comparison of 2 stacks
bool comparison(T &stack) {
if (size == stack.size)
for (int i = 0; i < size; i++) {
if (!this->stackPr[i].comparison(stack.stackPr[i]))
return false;
}
else
return false;
return true;
}
};
Try this, in your Stack class
change:
bool comparison(T &stack) {
for this:
bool comparison(Stack<T> &stack) {
First of all, abandon this comparison function, it hinders your code, use == instead.
Secondly, use const Stack<T> in your comparison function.
And finally, use auto to deduce the type of the variables.
Here is an example that shows the basics of what I just wrote:
#include <iostream>
using namespace std;
struct Time
{
bool operator==(const Time& time)
{
return true;// adjust it with your own needs.
}
};
template<typename T>
struct Stack
{
T val;
Stack(T& val_): val(val_) {}
bool operator==(const Stack<T>& stack)
{
return this->val == stack.val; // here is your business logic of comparison
}
};
int main()
{
Time t1;
Time t2;
Stack<Time> myStack1(t1);
Stack<Time> myStack2(t2);
auto temp = myStack1 == myStack2;
cout << temp << endl;
return 0;
}
I have to develop two functions. One is an application level function that merges two sortedlists implemented using dynamic arrays. The other is the same except its supposed to be a member function. I get invalid allocation size. When I trace the function it successfully returns without an error buy as soon as I reach the original calling code I get the error. Here is the code for both functions.
Application level function:
ArraySortedType& merge(const ArraySortedType& list1, const ArraySortedType& list2)
{
ItemType temp;
ArraySortedType ret, list1Copy=list1, list2Copy=list2;
list1Copy.ResetList();
while (list1Copy.GetNextItem(temp) == Success)
ret.InsertItem(temp);
list2Copy.ResetList();
while (list2Copy.GetNextItem(temp) == Success)
ret.InsertItem(temp);
return ret;
}
Member function:
ArraySortedType& ArraySortedType::merge(const ArraySortedType& list)
{
ArraySortedType s, copy = list;
ItemType temp;
copy.ResetList();
while (copy.GetNextItem(temp) == Success)
s.InsertItem(temp);
for (int k = 0; k < length; k++)
s.InsertItem(info[k]);
return s;
}
Code where I call functions:
ArraySortedType u = merge(s, n);
//ArraySortedType k = merge(s, n);
cout << "Length of u is: " << u.LengthIs() << endl;
// cout << "Length of k is: " << k.LengthIs() << endl;
Even the commented out code doesn't work.
Also there is alot of code for implementing the ArraySortedType that I've left out because I think it's unnecessary. Most of it was already given with the lab. InsertItem was implemented by me and is used quite a bit so I'll include it here:
Error_Code ArraySortedType::InsertItem ( ItemType item)
{
if(!length)
{
info[0] = item;
length++;
return Success;
}
for(int i=0;i<=length;i++)
{
if(info[i].ComparedTo(item) != LESS || i==length)
{
for(int j=length;j>i;j--)
info[j] = info[j-1];
info[i]=item;
length++;
return Success;
}
}
return Fail;
}
GetNextItem() and ResetList() were already given so they cant be the problem so I'll leave them out but just tell me if they are required.
I've traced both of them and googled quite a bit but this problem has left me scratching my head. Any help would be appreciated.
EDIT:
I guess the implementation of ArraySortedList will be necessary. Here it is. Guess I don't really expect anyone to actually go through it though:
//ArraySortedType.cpp
#include "ArraySortedType.h"
ArraySortedType::ArraySortedType (int max_items)
{
length =0;
MAX_ITEMS = max_items;
currentPos =-1;
try
{
info = new ItemType[MAX_ITEMS];
}
catch(std::bad_alloc exception)
{
//Severe problem, do not keep program running
cout <<"Memory full "<< endl;
exit(1);
}
}
ArraySortedType::~ArraySortedType()
{
delete [] info;
info = NULL;
}
void ArraySortedType::ResetList ( )
{
currentPos = -1;
}
bool ArraySortedType::IsFull ( ) const
{
if(length == MAX_ITEMS)
{
try
{//Check if memory allocation is fine
ItemType * temp = new ItemType[2*MAX_ITEMS];
delete [] temp;
return false;
}
catch(std::bad_alloc exception)
{
return true;
}
}
return false;
}
bool ArraySortedType::IsEmpty () const {
return (length==0);
}
int ArraySortedType:: LengthIs () const {
return length;
}
Error_Code ArraySortedType::DeleteItem ( ItemType item ) {
int location = 0;
while ((item.ComparedTo(info[location]) != EQUAL ) && location < length)
location++;
if (location == length) return Fail;
info[location] = info[length - 1];
length--;
return Success;
}
Error_Code ArraySortedType::GetNextItem (ItemType& item) {
currentPos++;
if( currentPos == length ) return Fail;
item = info[currentPos] ;
return Success;
}
ArraySortedType::ArraySortedType(const ArraySortedType & ust)
{
MAX_ITEMS =ust.MAX_ITEMS;
length=ust.length;
try
{
info = new ItemType[MAX_ITEMS];
}
catch(std::bad_alloc exception)
{
//Severe problem, do not keep program running
cout <<"Memory full "<< endl;
exit(1);
}
for(int i=0;i<length; i++)
info[i] = ust.info[i];
currentPos=ust.currentPos;
}
ArraySortedType& ArraySortedType::operator=(const ArraySortedType & ust)
{
if(this == &ust) return *this;
if(MAX_ITEMS !=ust.MAX_ITEMS)
{
delete [] info;
MAX_ITEMS = ust.MAX_ITEMS;
try
{
info = new ItemType[MAX_ITEMS];
}
catch(std::bad_alloc exception)
{
//Severe problem, do not keep program running
cout <<"Memory full "<< endl;
exit(1);
}
}
currentPos=ust.currentPos;
length=ust.length;
for(int i=0;i<length; i++)
info[i] = ust.info[i];
return *this;
}
//Assumes that an employee has unique ID
bool ArraySortedType::operator==(const ArraySortedType & ust)
{
if(this == &ust) return true;
if(length!=ust.length) return false;
if(currentPos!=ust.currentPos) return false;
for(int i=0;i<length; i++)
if(info[i].ComparedTo(ust.info[i])!=EQUAL) return false;
return true;
}
Error_Code ArraySortedType::InsertItem ( ItemType item)
{
if(!length)
{
info[0] = item;
length++;
return Success;
}
for(int i=0;i<=length;i++)
{
if(info[i].ComparedTo(item) != LESS || i==length)
{
for(int j=length;j>i;j--)
info[j] = info[j-1];
info[i]=item;
length++;
return Success;
}
}
return Fail;
}
Error_Code ArraySortedType::RetrieveItem (ItemType& item , bool& found)
{
found = false;
int front = 0, back = length - 1, midpoint=(length-1)/2;
while (front<=back)
{
switch (info[midpoint].ComparedTo(item))
{
case EQUAL:
item = info[midpoint];
found = true;
break;
case LESS:
front = midpoint + 1;
break;
case GREATER:
back = midpoint - 1;
break;
}
if (found)
break;
midpoint = ((back - front) / 2 + front);
}
return Fail;
}
Error_Code ArraySortedType::Delete(ItemType startKey, ItemType endKey)
{
bool startFound = false, endFound = false;
int numberDeleted=0, startLocation;
bool deleting = false;
for (int i = 0; i < length; i++)
{
if (info[i].ComparedTo(startKey) == EQUAL)
{
startLocation = i;
deleting = true;
startFound = true;
}
if (deleting)
numberDeleted++;
if (info[i].ComparedTo(endKey) == EQUAL)
{
deleting = false;
endFound = true;
}
}
if (!(startFound || endFound))
return Fail;
length -= numberDeleted;
for (int i = startLocation; i < length; i++)
info[i] = info[i + startLocation];
return Success;
}
ArraySortedType ArraySortedType::RetrieveItemsInRange(ItemType startKey, ItemType endKey)
{
ArraySortedType r;
bool startFound = false, endFound = false;
int numberDeleted = 0, startLocation;
bool retrieving = false;
for (int i = 0; i < length; i++)
{
if (info[i].ComparedTo(startKey) == EQUAL)
{
startLocation = i;
retrieving = true;
startFound = true;
}
if (retrieving)
r.InsertItem(info[i]);
if (info[i].ComparedTo(endKey) == EQUAL)
{
retrieving = false;
endFound = true;
}
}
return r;
}
ArraySortedType& ArraySortedType::merge(const ArraySortedType& list)
{
ArraySortedType s, copy = list;
ItemType temp;
copy.ResetList();
while (copy.GetNextItem(temp) == Success)
s.InsertItem(temp);
for (int k = 0; k < length; k++)
s.InsertItem(info[k]);
return s;
}
ItemType is defined as a class Employee. I really hope I don't have to include it here as well. The class Employee has a compareTo class defined as follows:
RelationType Employee::ComparedTo(const Employee & e)
{
if(eid < e.eid) return LESS;
else if(eid == e.eid) return EQUAL;
else return GREATER;
}
There is a an enum called relation type that has values LESS, EQUAL and GREATER.
about data structures,why i can't output paths of the maze? I use the stack to storage the information of the current position.Read map of maze through a text file,if the position cant't pass
will be marker by "#",it is a wall.the way marker by "+". written in C++.
PS:My English is very poor.
//stack.h
#ifndef _STACK_H_
#define _STACK_H_
#include<iostream>
#include<stdlib.h>
const int SIZE = 81;
using namespace std;
typedef struct
{
int x;
int y;
}PosType;
typedef struct SElemType{
int ord;//steps
PosType seat;//coordinate
int di;//direction
}SElemType;
typedef struct SqStack{
SElemType *base;
SElemType *top;
int StackSize;
}SqStack;
void Init_S(SqStack &S)
{
S.base = new SElemType[SIZE];
if(!S.base)
exit(EXIT_FAILURE);
S.top = S.base;
S.StackSize = SIZE;
}
bool StackEmpty(SqStack S)
{
if(S.top = S.base)
return true;
return false;
}
void Push(SqStack &S,SElemType e)
{
SElemType *newbase;
if(S.top-S.base>=S.StackSize)
{
newbase = new SElemType[S.StackSize*2];
if(!S.base)
exit(EXIT_FAILURE);
for(int i(0);i<S.top-S.base;i++)
*(newbase+i) = *(S.base+i);
delete[]S.base;
S.base = newbase;
S.top = S.base+S.StackSize;
S.StackSize *= 2;
}
*(S.top)++ = e;
}
void Pop(SqStack &S,SElemType e)
{
if(StackEmpty(S))
cout<<"empty stack!\n";
else
e = *(--S.top);
}
#endif
//maze.cpp
#include<iostream>
#include<cstdlib>
#include<fstream>
#include"stack.h"
using namespace std;
const int m = 10;
const int n = 10;
typedef char MazeG[m][n];
void Show_MG(MazeG MG)
{
for(int i(0);i<m;i++)
{
for(int j(0);j<n;j++)
{
cout<<MG[i][j];
}
cout<<"\t\n";
}
}
PosType Next(PosType &pos,int di)
{
PosType repos;
switch(di)
{
case 0://north
repos.x = pos.x-1;
repos.y = pos.y;
break;
case 1://east
repos.x = pos.x;
repos.y = pos.y+1;
break;
case 2://south
repos.x = pos.x+1;
repos.y = pos.y;
break;
case 3://west
repos.x = pos.x;
repos.y = pos.y-1;
break;
default:
break;
}
return repos;
}
int MazePath(MazeG &MG,PosType begin,PosType end)
{
PosType curpos = begin;
SqStack S;
Init_S(S);
SElemType e;
e.ord = 0;
do{
if(MG[curpos.x][curpos.y]=='*')
{
MG[curpos.x][curpos.y] = '+';
e.seat = curpos;
e.di = 0;
e.ord++;
Push(S,e);
if(curpos.x==end.x&&curpos.y==end.y)
{
cout<<"此迷宫的一条路径如下:(+标记为路径)\n";//the path of maze:
cout<<"走了"<<e.di<<"步到达出口\n";//The number of steps walked
Show_MG(MG);
return 0;
}
else
curpos = Next(curpos,e.di);
}
else
if(!StackEmpty(S))
{
Pop(S,e);
e.ord--;
while(e.di==3&&!StackEmpty(S))
{
MG[curpos.x][curpos.y] = '#';
Pop(S,e);
e.ord--;
}
if(e.di<3)
{
e.di++;
Push(S,e);
e.ord++;
curpos = Next(curpos,e.di);
}
}
}while(!StackEmpty(S));
cout<<"此迷宫没有入口到出口的路径!\n";//no path of the maze
//return -1;
}
int main()
{
MazeG MG;
PosType begin,end;
begin.x = 1; begin.y = 1;
end.x = 8; end.y = 8;
ifstream fin;
fin.open("file.txt");
if(!fin.is_open())
{
cout<<"erorr file!!\n";
exit(EXIT_FAILURE);
}
if(fin.good())
{
for(int i(0);i<m;i++)
for(int j(0);j<n;j++)
fin>>MG[i][j];
}
cout<<"迷宫图为:(*代表能通过)\n";//map of maze:('*' is means through)
Show_MG(MG);
cout<<begin.x<<begin.y<<end.x<<end.y<<endl;
fin.close();
MazePath(MG,begin,end);
return 0;
}
This is wrong
bool StackEmpty(SqStack S)
{
if(S.top = S.base)
return true;
return false;
}
It should be this
bool StackEmpty(SqStack S)
{
if(S.top == S.base) // == not =
return true;
return false;
}
Use == for equality not =.
Now,I understand my the error of code is that I mismatch the data will be stored by stack.
I have changed my code,that's right.
//stack.h
SElemType Gettop(SqStack S)
{
if(!Empty_S(S))
return *(S.top-1);
}
//maze_path.cpp
do{
if(MG[curpos.x][curpos.y]=='*')
{
MG[curpos.x][curpos.y] = '+';
e.seat = curpos;
e.di = 0;
e.ord++;
Push(S,e);
if(curpos.x==end.x&&curpos.y==end.y)
{
cout<<"此迷宫的一条路径如下:(+标记为路径)\n";//the path of maze:
cout<<"走了"<<e.di<<"步到达出口\n";//The number of steps walked
Show_MG(MG);
return 0;
}
else
curpos = Next(curpos,e.di);
}
else
if(!StackEmpty(S))
{
if(e.di<3)
{
e.ord++;
curpos = Next(curpos,e.di);
}
else
{
MG[curpos.x][curpos.y] = '#';
Pop(S,e);
e = Gettop(S);
}
}
}while(!StackEmpty(S));