Why does this code work:
#include <cstdio>
#include <cstdlib>
#define N n *
#define Q q *
#define S s *
typedef struct n
{
int data;
struct N nxt;
}n;
typedef struct q
{
N f;
N r;
}q;
typedef struct stack
{
Q q1;
Q q2;
}s;
Q Createq()
{
Q qq = (Q)malloc(sizeof(q));
qq->f = qq->r = 0;
return qq;
}
S CreateStk()
{
S stk = (S)malloc(sizeof(s));
stk->q1 = Createq();
stk->q2 = Createq();
return stk;
}
int Deq(Q qq)
{
if(qq->f == 0 && qq->r == 0) return -1;
N nn = qq->r;
int data = nn->data;
qq->r = qq->r->nxt;
free(nn);
if(!qq->r)
qq->f = 0;
return data;
}
void Enq(Q qq, int data)
{
if(!qq->f)
{
N nn = (N)malloc(sizeof(n));
nn->data = data;
nn->nxt = 0;
qq->f = qq->r = nn;
}
else
{
N nn = (N)malloc(sizeof(n));
nn->data = data;
nn->nxt = 0;
qq->f->nxt = nn;
qq->f = nn;
}
}
void Push(S stk, int data)
{
Enq(stk->q2,data);
while(stk->q1->f)
{
Enq(stk->q2,Deq(stk->q1));
}
Q t = stk->q1;
stk->q1 = stk->q2;
stk->q2 = t;
}
int Pop(S stk)
{
return Deq(stk->q1);
}
int main()
{
S stk = CreateStk();
Push(stk,10);
Push(stk,30);
Push(stk,40);
Push(stk,50);
printf("\nPopped: %d.", Pop(stk));
printf("\nPopped: %d.", Pop(stk));
printf("\nPopped: %d.", Pop(stk));
printf("\nPopped: %d.", Pop(stk));
return 0;
return 0;
}
Output:
Popped: 50.
Popped: 40.
Popped: 30.
Popped: 10.
While this does not:
#include <cstdio>
#include <cstdlib>
#define N n *
#define Q q *
typedef struct n
{
int data;
struct N nxt;
}n;
typedef struct q
{
N f;
N r;
}q;
Q Createq()
{
Q qq = (Q)malloc(sizeof(q));
qq->f = qq->r = 0;
return qq;
}
int Deq(Q qq)
{
if(qq->f == 0 && qq->r == 0) return -1;
N nn = qq->r;
int data = nn->data;
qq->r = qq->r->nxt;
free(nn);
if(!qq->r)
qq->f = 0;
return data;
}
void Enq(Q qq, int data)
{
if(!qq->f)
{
N nn = (N)malloc(sizeof(n));
nn->data = data;
nn->nxt = 0;
qq->f = qq->r = nn;
}
else
{
N nn = (N)malloc(sizeof(n));
nn->data = data;
nn->nxt = 0;
qq->f->nxt = nn;
qq->f = nn;
}
}
void Push(Q qq1, Q qq2, int data)
{
Enq(qq2,data);
while(qq1->f)
{
Enq(qq2,Deq(qq1));
}
Q t = qq1;
qq1 = qq2;
qq2 = t;
}
int Pop(Q qq1)
{
return Deq(qq1);
}
int main() {
// your code goes here
Q qq1 = Createq();
Q qq2 = Createq();
Push(qq1,qq2,10);
Push(qq1,qq2,30);
Push(qq1,qq2,40);
Push(qq1,qq2,50);
printf("\nPopped: %d.", Pop(qq1));
printf("\nPopped: %d.", Pop(qq1));
printf("\nPopped: %d.", Pop(qq1));
printf("\nPopped: %d.", Pop(qq1));
return 0;
}
Output:
Popped: -1.
Popped: -1.
Popped: -1.
Popped: -1.
The expected output is the first one as its obvious by the question heading. However i do not understand the gory details of why the code did not work when i did not encapsulate the 2 queues in a struct in my second example.
PS: I think the problem is with the Push method - but not sure what went wrong.
Aside from being horrendously hard to read, the problem is that your second Push function changes the values of its parameters in the following lines of code.
Q t = qq1;
qq1 = qq2;
qq2 = t;
qq1 and qq2 are parameters of the function, so the new values are not updated in the calling function (main).
One way to fix this is to make the parameters pass by reference:
void Push(Q &qq1, Q &qq2, int data)
That way, changes to qq1 and qq2 will also change the values in the calling function.
Related
Basically i cant make work this logic simulator! I made an adjacency list that connects all the gates one to each other and then assign a value to them and AdjList that is the head should calculate the value using the function pointer. Problem is the only function it calls is And!(Xor Nand etc.. are never called)
The specific points are where pointer are initialized
struct AdjList
{
struct AdjListNode *head;
string GateName;
string OutputName;
bool result;
function <bool (vector <bool>)> ptrf;
};
and were they are assigned
if(i < Gate_IO.size() )
{
ptrPos = Gate_IO[i].find_first_of(' ');
switch (strtoi ( (Gate_IO[i].substr(0,ptrPos).c_str() )))
{
case strtoi("AND"):
{
VectorHeadPtr[i].ptrf = And;
break;
}
case strtoi("NAND"):
{
VectorHeadPtr[i].ptrf = Nand;
break;
}
case strtoi("OR"):
{
VectorHeadPtr[i].ptrf = Or;
break;
}
case strtoi("NOR"):
{
VectorHeadPtr[i].ptrf = Nor;
break;
}
case strtoi("XOR"):
{
VectorHeadPtr[i].ptrf = Xor;
break;
}
default:
break;
}
Then in function CalcGateValue() they are called to execute the program! it seems like they are recognised and assigned to the right value in VectorHeadPtr[i].ptrf i tried to cout in that point and it goes into that cycle but the only function called when i call CalcGateValue() is And! Am I missing something?
Here is the complete code:
#include <iostream>
#include <cstdlib>
#include <string>
#include <sstream>
#include <vector>
#include <algorithm>
#include <functional>
using namespace std;
int compare(string a, string b)
{
int n = count(a.begin(), a.end(), 'I');
int q = count(b.begin(), b.end(), 'I');
return n > q;
}
constexpr unsigned int strtoi(const char* str, int h = 0) //string to int for switch cycle
{
return !str[h] ? 5381:(strtoi(str, h+1)*33)^str[h];
}
bool Xor(vector<bool> inputs)
{ cout<<"Xor function called!"<<endl;
int counter = 0;
for (unsigned int i = 0;i < inputs.size(); i++)
{
if (inputs.at(i) == 1)
{
counter++;
}
}
if (counter % 2) //Xor gate gives output 1 if and odd number of 1 inputs is given
{
return 1;
}
else
{
return 0;
}
}
bool And(vector<bool> inputs) //static per richiamare la funzione dalla classe
{ cout<<"And function called!"<<endl;
for (int i = 0; i < (inputs.size()-1); i++)
{
if(inputs.at(i) == 0)
{
return 0;
}
}
return 1;
}
bool Nand(vector<bool> inputs)
{ cout<<"Nand function called!"<<endl;
return !And(inputs);
}
bool Or(vector<bool> inputs)
{cout<<"Or function called!"<<endl;
for (int i = 0; i < (inputs.size()-1); i++)
{
if (inputs.at(i) != inputs.at(i+1) )
{
return 1;
}
}
return inputs.at(0);//Any position it's ok because all nPoss are the same.
}
bool Nor(vector<bool> inputs)
{ cout<<"Nor function called!"<<endl;
return !Or(inputs);
}
/*
* Adjacency list node
*/
struct AdjListNode
{
int nPos;
bool gValue;
string name;
struct AdjListNode* next;
};
/*
* Adjacency list
*/
struct AdjList
{
struct AdjListNode *head;
string GateName;
string OutputName;
bool result;
function <bool (vector <bool>)> ptrf;
};
/**
* Class Graph
*/
class Graph
{
private:
int V;
int circInputs = 3;
int circOutputs = 2;
int circGates;
int PrimaryInputs = 0;
vector<string> ioPuts;
struct AdjList* VectorHeadPtr;
public:
Graph(vector<string> Gate_IO)
{
int ptrPos,cntr;
int cntrIO = 0;
int prevPrimaryInputs = 0;
bool flag_remove_duplicates = 0;
string GateToConnect;
circGates = Gate_IO.size();
V=Gate_IO.size() + circInputs + circOutputs; //n°gates+input+output letti dal file
sort (Gate_IO.begin(), Gate_IO.end(), compare);
for (cntr = 0; cntr < (Gate_IO.size()-1) && (PrimaryInputs == prevPrimaryInputs); cntr++)
{
PrimaryInputs = count (Gate_IO[cntr+1].begin(), Gate_IO[cntr+1].end(), 'I');
prevPrimaryInputs = count (Gate_IO[cntr].begin(), Gate_IO[cntr].end(), 'I');
}
PrimaryInputs = cntr; //Here starts first N
for (int i = 0;i<Gate_IO.size();i++)
VectorHeadPtr = new AdjList [V];
for (int i = 0; i < V; i++)
{
if(i < Gate_IO.size() )
{
ptrPos = Gate_IO[i].find_first_of(' ');
switch (strtoi ( (Gate_IO[i].substr(0,ptrPos).c_str() )))
{
case strtoi("AND"):
{
VectorHeadPtr[i].ptrf = And;
break;
}
case strtoi("NAND"):
{
VectorHeadPtr[i].ptrf = Nand;
break;
}
case strtoi("OR"):
{
VectorHeadPtr[i].ptrf = Or;
break;
}
case strtoi("NOR"):
{
VectorHeadPtr[i].ptrf = Nor;
break;
}
case strtoi("XOR"):
{
VectorHeadPtr[i].ptrf = Xor;
break;
}
default:
break;
}
VectorHeadPtr[i].head = NULL;
stringstream ss;
ss << Gate_IO[i];
for (string temp; ss >> temp;)
{
if ( (temp.at(0)=='I') || (temp.at(0)=='O') && (temp!="OR") )
{
ioPuts.push_back(temp);
}
else if (temp.at(0) == 'U')
{
VectorHeadPtr[i].GateName=temp;
}
}
ptrPos = Gate_IO[i].find_last_of(' ');
VectorHeadPtr[i].OutputName = Gate_IO[i].substr(ptrPos);
}
else
{
if (flag_remove_duplicates == 0)
{
sort (ioPuts.begin(), ioPuts.end() );
ioPuts.erase (unique (ioPuts.begin(), ioPuts.end() ), ioPuts.end() );
flag_remove_duplicates = 1;
}
VectorHeadPtr[i].head = NULL;
VectorHeadPtr[i].ptrf = NULL;
VectorHeadPtr[i].GateName = ioPuts[cntrIO];
cntrIO++;
}
}
for (int i = 0; i < Gate_IO.size(); i++)
{
for(int j = 0; j < 2; j++)
{
ptrPos = Gate_IO[i].find_first_of(' ')+1;
Gate_IO[i].erase (0,ptrPos);
}
ptrPos = Gate_IO[i].find_last_of(' ')+1;
Gate_IO[i].erase( ptrPos);
stringstream ss;
ss << Gate_IO[i];
ss >> GateToConnect;
for (string temp; ss >> temp;)
{
addEdge(GateToConnect,temp);
}
}
}
/**
* Creates new adjacency list node for addEdge function
*/
AdjListNode* newAdjListNode(int nPos, string Name)
{
AdjListNode* newNode = new AdjListNode;
newNode->nPos = nPos;
newNode->name = Name;
newNode->next = NULL;
return newNode;
}
/**
* Add edge to graph
*/
void addEdge(string source, string destination)
{
int from, to;
for (int i = 0; i < V; ++i)
{
if ( (source == VectorHeadPtr[i].GateName) || (source == VectorHeadPtr[i].OutputName) )
{
from = i;
}
else if (( destination == VectorHeadPtr[i].GateName) || (destination == VectorHeadPtr[i].OutputName) )
{
to = i;
}
}
AdjListNode* newNode = newAdjListNode(to, destination);
newNode->next = VectorHeadPtr[from].head;
VectorHeadPtr[from].head = newNode;
}
/*
* Print the graph
*/
void printGraph()
{
for (int i = 0; i < circGates; i++)//meno ooutput+input
{
AdjListNode* Ptr = VectorHeadPtr[i].head;
cout<<endl<<"Gate connections for "<<VectorHeadPtr[i].GateName;
while (Ptr)
{
cout <<"-> "<< Ptr->name;
Ptr = Ptr->next;
}
cout<<" Output name is:"<<VectorHeadPtr[i].OutputName<<endl;
}
}
void calcGateVal()
{
vector<bool> Val={0, 1, 0};
vector<bool> Op;
for (int i = 0; i < circOutputs; i++)
{
ioPuts.pop_back();
}
for (int i = 0; i < circGates; i++)
{
AdjListNode* Ptr = VectorHeadPtr[i].head;
while (Ptr)
{
if (Ptr->name.at(0) == 'I')
{
for (int j = 0; j < ioPuts.size(); j++)
{
if (Ptr->name == ioPuts[j])
{
Ptr->gValue = Val[j];
}
}
}
Ptr = Ptr->next;
}
}
for (int i = 0; i < PrimaryInputs; i++)
{
AdjListNode* Ptr = VectorHeadPtr[i].head;
while (Ptr)
{
Op.push_back(Ptr->gValue);
Ptr = Ptr->next;
}
VectorHeadPtr[i].result = VectorHeadPtr[i].ptrf(Op);
cout<<"Gate Value is: "<<VectorHeadPtr[i].result<<" OutputName: "<<VectorHeadPtr[i].OutputName<<" GateName: "<<VectorHeadPtr[i].GateName<<endl;
Op.clear();
}
for (int i = PrimaryInputs; i < V; i++)
{
AdjListNode* Ptr = VectorHeadPtr[i].head;
while (Ptr)
{
for (int j = 0; j < PrimaryInputs; j++)
{
if (Ptr->name == VectorHeadPtr[j].OutputName)
{
Ptr->gValue = VectorHeadPtr[j].result;
}
}
Ptr = Ptr->next;
}
}
for (int i = PrimaryInputs; i < circGates; i++)
{
AdjListNode* Ptr = VectorHeadPtr[i].head;
while (Ptr)
{
Op.push_back(Ptr->gValue);
Ptr = Ptr->next;
}
VectorHeadPtr[i].result = VectorHeadPtr->ptrf(Op);
Op.clear();
}
}
void displayOutput()
{ cout<<endl;
for (int i = 0; i < circGates; i++)
{
cout<<"Value of outputs are ("<<VectorHeadPtr[i].GateName<<") "<<VectorHeadPtr[i].OutputName<<": "<<VectorHeadPtr[i].result<<endl;
}
}
};
/*
* Main
*/
int main()
{
vector<string> G_d;
G_d.push_back("AND 2 U0 I0 I1 N0");
G_d.push_back("XOR 2 U1 N0 I2 O0");
G_d.push_back("AND 2 U2 N0 I2 N1");
G_d.push_back("AND 2 U3 I0 I1 N2");
G_d.push_back("OR 2 U4 N1 N2 O1");
Graph gh(G_d);
gh.calcGateVal();
gh.displayOutput();
gh.printGraph();
// print the adjacency list representation of the above graph
return 0;
}
I think your code does not produce what you say it produces. Please see here:
http://coliru.stacked-crooked.com/a/405b04c8d9113790 - Check the output of this
Why do you want to convert strings to integers with strtoi with your case comparisons? :
case strtoi("NAND"):
a better approach would be strcmp or store each in a string perhaps a look up table and do a "==" equal equal comparison which is overloaded for strings.
Consider passing your vectors and objects around by reference rather than value, you might be expecting a return in your object but since you pass by value you never see them and this also avoids the overhead of making a copy of the vectors.
Background
Creating a dice game where the dice roll value should be stored in a Linked List.
Question
How should an implementation of Linked List be completed in C++? '
Example (What I have tried using struct instead of class)
#include <time.h>
#include <stdlib.h>
#include <stdio.h>
#include <iostream>
struct Score {
int d1;
int d2;
int total;
int totals[13];
int value;
struct Score * next;
}
score_dice1, score_dice2, score_total, score_totals;
struct Score * ordered_insert(struct Score * , struct Score * );
int dice = 2;
void Randomize() {
srand((unsigned) time(NULL));
}
int Random(int Max) {
return (rand() % Max) + 1;
}
int main(int argc, char * argv[]) {
struct Score * myList = NULL;
if (argc == 2) {
int dice_rolls;
dice_rolls = atoi(argv[1]);
Randomize();
for (dice = 2; dice <= 12; dice++)
score_totals.totals[dice] = 0;
for (dice = 0; dice < dice_rolls; dice++) {
score_dice1.d1 = Random(6);
score_dice2.d2 = Random(6);
score_total.total = score_dice1.d1 + score_dice2.d2;
score_totals.totals[score_total.total]++;
}
for (dice = 1; dice <= 13; dice++) {
printf("%i %i\n\r", dice, score_totals.totals[dice]);
}
} else {
std::cout << "How many times should we roll the dice?" << '\n' <<
"One number please" << '\n';
}
return 0;
}
You probably want to use the STL, and include the std::list class. You should look at the methods for that class. I will show you how using the std::vector class.
Suppose you want to place the following into the list,
struct roll_t {
int dice1; //value of dice1
int dice2; //value of dice2
int total; //total of dice1+dice2
roll_t() dice1(0), dice2(0), total(0) { }
roll_t(int d1, int d2) : dice1(d1), dice2(d2), total(d1+d2) { };
};
Here is a C++ list reference
Here is an example with explanation
But, let me also add an example here,
#include <vector>
using namespace std;
int main(int argc, char* argv[])
{
vector<roll_t> dv;
roll_t rolls[13+1];
//suppose you have initialized totals[] here...
for( ndx=1; ndx<=12; ++ndx ) {
rolls[ndx] = roll_t.new(random(6),random(6));
}
//move totals to vector (convert to list left as exercise for poster)
int ndx;
for( ndx=1; ndx<=12; ++ndx ) {
dv.push_back(rolls[ndx]);
}
//traverse vector (convert to list, you will need iterator)
cout << "Loop by index:" << endl;
for(ndx=0; ndx < dv.size(); dv++)
{
cout << "["<<ndx<<"]"
<< dv[ndx].dice1 <<','<< dv[ndx].dice2 <<','<< dv[ndx].total << endl;
}
}
The above uses the STL, but maybe this question is for a class? And you need to roll your own linked list? I have linked to some stackoverflow answers,
I built one of those,
Trying to make linkedlist in C
Here is a description of single-linked list,
Singly-list insert to end of list
Here is a basic C++ dice game,
Basic C++ Dice game
Here is an explanation of how to sort a linked list by moving pointers,
Trying to Sort a Linked List only by Manipulating Pointers
Those should help.
Answer
Use a class to create the Linked List logic.
Example
linklist.h
#pragma once
#ifndef LINKLIST_H
#define LINKLIST_H
#include <iostream>
using namespace std;
class linklist {
private:
struct node {
int data;
node * link;
}* p;
public:
linklist();
void append(int num);
void add_as_first(int num);
void addafter(int c, int num);
void del(int num);
void display();
int count();
~linklist();
};
linklist::linklist() {
p = NULL;
}
void linklist::append(int num) {
node * q, * t;
if (p == NULL) {
p = new node;
p -> data = num;
p -> link = NULL;
} else {
q = p;
while (q -> link != NULL)
q = q -> link;
t = new node;
t -> data = num;
t -> link = NULL;
q -> link = t;
}
}
void linklist::add_as_first(int num) {
node * q;
q = new node;
q -> data = num;
q -> link = p;
p = q;
}
void linklist::addafter(int c, int num) {
node * q, * t;
int i;
for (i = 0, q = p; i < c; i++) {
q = q -> link;
if (q == NULL) {
cout << "\nThere are less than " << c << " elements.";
return;
}
}
t = new node;
t -> data = num;
t -> link = q -> link;
q -> link = t;
}
void linklist::del(int num) {
node * q, * r;
q = p;
if (q -> data == num) {
p = q -> link;
delete q;
return;
}
r = q;
while (q != NULL) {
if (q -> data == num)
{
r -> link = q -> link;
delete q;
return;
}
r = q;
q = q -> link;
}
cout << "\nElement " << num << " not Found.";
}
void linklist::display() {
node * q;
cout << endl;
for (q = p; q != NULL; q = q -> link)
cout << endl << q -> data;
}
int linklist::count() {
node * q;
int c = 0;
for (q = p; q != NULL; q = q -> link)
c++;
return c;
}
linklist::~linklist() {
node * q;
if (p == NULL)
return;
while (p != NULL) {
q = p -> link;
delete p;
p = q;
}
}
#endif
main.cc
#include <time.h>
#include <stdlib.h>
#include <stdio.h>
#include <iostream>
#include <list>
#include <vector>
#include "linklist.h"
struct score {
int d1;
int d2;
int total;
int totals[13];
}
score_dice1, score_dice2, score_total, score_totals;
int dice = 2;
void Randomize() {
srand((unsigned) time(NULL));
}
int Random(int Max) {
return (rand() % Max) + 1;
}
int main(int argc, char * argv[]) {
linklist ll;
if (argc == 2) {
int dice_rolls;
dice_rolls = atoi(argv[1]);
Randomize();
for (dice = 2; dice <= 12; dice++)
score_totals.totals[dice] = 0;
for (dice = 0; dice < dice_rolls; dice++) {
score_dice1.d1 = Random(6);
score_dice2.d2 = Random(6);
score_total.total = score_dice1.d1 + score_dice2.d2;
score_totals.totals[score_total.total]++;
}
for (dice = 1; dice <= 13; dice++) {
ll.append(score_totals.totals[dice]);
std::cout << ll.count() << '\n';
ll.display();
}
} else {
std::cout << "How many times should we roll the dice?" << '\n' <<
"One number please" << '\n';
}
return 0;
}
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));
I got this implementation for maximum matching off the net and is trying to give its input through main class. But I am getting zero for all the places in match. What am I doing wrong?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iostream>
#include <queue>
using namespace std;
void add_edge(int u, int v);
void edmonds();
struct edge {
int v, nx;
};
const int MAXN = 1000, MAXE = 2000;
edge graph[MAXE];
int last[MAXN], match[MAXN], px[MAXN], base[MAXN], N, M, edges;
bool used[MAXN], blossom[MAXN], lused[MAXN];
int main ()
{
// return 0;
add_edge(1,4);
add_edge(1,5);
add_edge(1,6);
add_edge(2,5);
add_edge(2,7);
add_edge(3,4);
add_edge(4,1);
add_edge(4,3);
add_edge(5,1);
add_edge(5,2);
add_edge(6,1);
add_edge(7,2);
edmonds();
cout << match[0];
cout << match[1];
cout << match[2];
cout << match[3];
cout << match[4];
cout << match[5];
cout << match[6];
}
inline void add_edge(int u, int v) {
graph[edges] = (edge) {v, last[u]};
last[u] = edges++;
graph[edges] = (edge) {u, last[v]};
last[v] = edges++;
}
void mark_path(int v, int b, int children) {
while (base[v] != b) {
blossom[base[v]] = blossom[base[match[v]]] = true;
px[v] = children;
children = match[v];
v = px[match[v]];
}
}
int lca(int a, int b) {
memset(lused, 0, N);
while (1) {
lused[a = base[a]] = true;
if (match[a] == -1)
break;
a = px[match[a]];
}
while (1) {
b = base[b];
if (lused[b])
return b;
b = px[match[b]];
}
}
int find_path(int root) {
memset(used, 0, N);
memset(px, -1, sizeof(int) * N);
for (int i = 0; i < N; ++i)
base[i] = i;
used[root] = true;
queue<int> q;
q.push(root);
register int v, e, to, i;
while (!q.empty()) {
v = q.front(); q.pop();
for (e = last[v]; e >= 0; e = graph[e].nx) {
to = graph[e].v;
if (base[v] == base[to] || match[v] == to)
continue;
if (to == root || (match[to] != -1 && px[match[to]] != -1)) {
int curbase = lca(v, to);
memset(blossom, 0, N);
mark_path(v, curbase, to);
mark_path(to, curbase, v);
for (i = 0; i < N; ++i)
if (blossom[base[i]]) {
base[i] = curbase;
if (!used[i]) {
used[i] = true;
q.push(i);
}
}
} else if (px[to] == -1) {
px[to] = v;
if (match[to] == -1)
return to;
to = match[to];
used[to] = true;
q.push(to);
}
}
}
return -1;
}
void build_pre_matching() {
register int u, e, v;
for (u = 0; u < N; ++u)
if (match[u] == -1)
for (e = last[u]; e >= 0; e = graph[e].nx) {
v = graph[e].v;
if (match[v] == -1) {
match[u] = v;
match[v] = u;
break;
}
}
}
void edmonds() {
memset(match, 0xff, sizeof(int) * N);
build_pre_matching();
register int i, v, pv, ppv;
for (i = 0; i < N; ++i)
if (match[i] == -1) {
v = find_path(i);
while (v != -1) {
pv = px[v], ppv = match[pv];
match[v] = pv, match[pv] = v;
v = ppv;
}
}
}
You set elements of match in two locations: In build_pre_matching() and in edmonds(). In both of these cases, no change will happen if match[x] for some index x isn't -1. The only other place elements of match get a value is during static initialization where the values get zero initialized. Since the initial value is zero and the values are only ever changed if at least one of them happens to be -1, I would expect that the values retain the value 0.
You might want to use something like
std::fill(std::begin(match), std::end(match), -1);
at a strategic location since you seem to assume that the values are initially -1. Of course, you also should consider the idea of not using global variables because this doesn't scale and works really badly in a multi-threaded program.
As an exercise (largely an exercise in trying to write something using pointers), I'm writing a cache simulation, specifically of the pseudo least recently used system from the old 486. I'm getting an "Access violation reading location" error on the line:
int min = treeArray[set]->root->findPLRU();
Initially the treeArray seems to be initialised properly (if I pause the program at the start and take a look, it's all as should be), but when the programme breaks and I delve in to examine things the root of the tree in question isn't defined.
I feel it's quite probable that I'm making some sort of very elementary pointer mistake, which is causing the pointer to the node to be "lost" somewhere, but I've no clue what it might be. Is there something in particular I need to do to "hold on" to a pointer value?
#include "stdafx.h"
#include "stdlib.h"
#include <conio.h>
#include <stdio.h>
#include <fcntl.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#include <io.h>
#include "main.h"
//char fn[80]; // trace filename
int tf; // trace file
trace buf[BUFSZ / sizeof(trace)]; // buffer SIZE
int LRUHits = 0;
int pLRUHits = 0;
int randomHits = 0;
int height;
int cachelinenumber;
//log2 helper function
int log2(int n)
{
int i = 0;
while (n)
{
n = n >> 1;
i++;
}
return i - 1;
}
class CacheLine{
public:
int tag;
int access;
CacheLine();
};
class Cache;
class Node{
public:
bool goRight;
Node* left;
Node* right;
int leftCacheLine;
int rightCacheLine;
Node(int depth) // constructor
{
goRight = false;
if (depth < height - 1)
{
left = new Node(depth + 1);
right = new Node(depth + 1);
leftCacheLine = -1;
rightCacheLine = -1;
}
else
{
leftCacheLine = cachelinenumber;
cachelinenumber++;
rightCacheLine = cachelinenumber;
cachelinenumber++;
}
//printf("Depth: %d, Height: %d, Left: %d, Right: %d\n", depth, height, leftCacheLine, rightCacheLine);
}
~Node()
{
delete left;
delete right;
}
int findPLRU()
{
if (leftCacheLine < 0 || rightCacheLine < 0)
{
if (goRight)
{
goRight = false;
return right->findPLRU();
}
else
{
goRight = true;
return left->findPLRU();
}
}
else
{
if (goRight)
{
goRight = false;
return rightCacheLine;
}
else
{
goRight = true;
return leftCacheLine;
}
}
}
};
class Tree{
public:
Node* root;
Tree()
{
root = new Node(0);
}
~Tree()
{
delete root;
}
};
//cache class
class Cache
{
public:
CacheLine *cache;
int l, k, n, replacementPolicy;
int log2l, log2n;
int access;
Tree** treeArray;
//constructor
Cache(int ll, int kk, int nn, int _replacementPolicy)
{
l = ll;
k = kk;
n = nn;
replacementPolicy = _replacementPolicy;
log2l = log2(l);
log2n = log2(n);
cache = (CacheLine*)malloc(sizeof(CacheLine)*k*n);
for (int i = 0; i < k*n; i++)
{
cache[i].tag = 0x80000000;
cache[i].access = 0;
}
if (replacementPolicy == 1)
{
cachelinenumber = 0;
treeArray = new Tree*[n];
for (int i = 0; i < n; i++)
{
treeArray[i] = new Tree();
}
}
access = -1;
}
//destructor
~Cache()
{
free(cache);
}
//test for hit
void hit(int a)
{
access++;
int set = (a >> log2l) & (n - 1);
int tag = a >> (log2n + log2l);
CacheLine* c = &cache[set*k];
for (int i = 0; i < k; i++)
{
if (c[i].tag == tag)
{
c[i].access = access;
if (replacementPolicy == 0)
LRUHits++;
else if (replacementPolicy == 1)
pLRUHits++;
else if (replacementPolicy == 2)
randomHits++;
break;
}
}
if (replacementPolicy == 0) //LRU
{
int min = 0;
int minv = c[0].access;
for (int i = 1; i < k; i++)
{
if (c[i].access < minv)
{
minv = c[i].access;
min = i;
}
}
c[min].tag = tag;
c[min].access = access;
}
else if(replacementPolicy == 1) // pseudoLRU
{
int min = treeArray[set]->root->findPLRU();
c[min].tag = tag;
c[min].access = access;
}
else // random
{
srand(clock());
int randomNumber = rand()%k;
c[randomNumber].tag = tag;
c[randomNumber].access = access;
}
return;
}
};
void analyse (int l, int k, int n)
{
height = log2(k) + 1;
char fn[] = "ico0.trace";
if ((tf = open(fn, _O_RDONLY | _O_BINARY )) == -1) {
printf("unable to open file %s\n", fn);
exit(0);
}
LRUHits = 0;
pLRUHits = 0;
randomHits = 0;
Cache *cache0 = new Cache(l, k, n, 0); // LRU
Cache *cache1 = new Cache(l, k, n, 1); // pseudoLRU
Cache *cache2 = new Cache(l, k, n, 2); // random
int bytes, word0, a, type, burstcount;
int hits = 0;
int tcount = 0;
while (bytes = read(tf, buf, sizeof(buf)))
{
for (int i = 0; i < bytes / (int) sizeof(trace); i++, tcount++)
{
word0 = buf[i].word0;
a = (word0 & ADDRESSMASK) << 2;
type = (word0 >> TYPESHIFT) & TYPEMASK;
burstcount = ((word0 >> BURSTSHIFT) & BURSTMASK) + 1;
cache0->hit(a);
cache1->hit(a);
cache2->hit(a);
}
}
printf("Hits: %d Total: %d\n", LRUHits, tcount);
printf("Hits: %d Total: %d\n", pLRUHits, tcount);
printf("Hits: %d Total: %d\n\n\n", randomHits, tcount);
delete cache0;
delete cache1;
delete cache2;
}
int _tmain(int argc, _TCHAR* argv[])
{
//analyse(16, 1, 8);
analyse(16, 2, 512);
//analyse(16, 4, 256);
//analyse(16, 8, 128);
//analyse(16, 1024, 1);
_getch();
return 0;
}
Your question hasn't yet been pounced upon, probably because your code still doesn't compile since you've not provided main.h.
And even then it would annoy most folks trying to help you because you make no mention of the ico0.trace file that is required to prevent the code from immediately exiting.
You say int min = treeArray[set]->root->findPLRU(); access violates.
1) the value of set can never exceed the size n of your treeArray since you & n-1 the range of input values.
2) since your ~Tree() destructor is never called there will always be a treeArray[set]->root
3) since you *always create new left & right nodes whenever leftCacheLine = -1 or rightCacheLine = -1 it cannot be due to recursive findPLRUs
So, the pointer to the node is not being "lost" somewhere; it is being stomped on.
Try replacing:
int min = treeArray[set]->root->findPLRU();
c[min].tag = tag;
c[min].access = access;
with:
int min = treeArray[set]->root->findPLRU();
if (min >= k*n)
{
printf("ook\n");
}
else
{
c[min].tag = tag;
c[min].access = access;
}
and I think you will discover what's doing the stomping. ;)