Dictionary function with BST returns vector - c++

The function dictionary_select returns a vector which contains words that are starting with W.
In this code dictionary_select gives an error message. But I can not find it. Is there anybody can help me?
#include <iostream>
#include <string>
#include <vector>
using namespace std;
struct tree {
string data;
tree *left;
tree *right;
};
typedef tree* dictionary;
bool dictionary_ins_word(dictionary & D, const string & W)
{
if(W == "" || W == " ")
return false;
tree* dic;
dic = new tree;
dic->data = W;
dic->left = NULL;
dic->right = NULL;
if(D == NULL) {
D = dic;
}
else {
if(W <= D->data)
dictionary_ins_word(D->left, W);
else
dictionary_ins_word(D->right, W);
}
return true;
}
bool dictionary_lookup(const dictionary & D, const string & W)
{
if(W == "" || W == " ")
return false;
if(D == NULL)
return false;
if(W == D->data)
return true;
else if (W < D->data)
return dictionary_lookup(D->left, W);
else
return dictionary_lookup(D->right, W);
}
bool dictionary_is_empty(const dictionary & D)
{
if(D == NULL)
return true;
else
return false;
}
bool dictionary_del_word(dictionary & D, const string & W)
{
if(!dictionary_lookup(D, W))
return false;
if(W < D->data)
dictionary_del_word(D->left, W);
else if(W > D->data)
dictionary_del_word(D->right, W);
else {
string item;
tree* temp;
temp = D;
if(D->left == NULL) {
D = D->right;
delete temp;
}
else if(D->right == NULL) {
D = D->left;
delete temp;
}
else {
while(D->left->right != NULL)
D->left = D->left->right;
item = D->left->data;
D->data = item;
dictionary_del_word(D->left, W);
}
}
return true;
}
bool dictionary_min(string & W, const dictionary & D)
{
dictionary min;
if(D == NULL)
return false;
min = D;
while(min->left != NULL)
min = min->left;
W = min->data;
return true;
}
vector <string> dictionary_select(const dictionary & D, const string & W)
{
vector < string > result;
vector < string > zeroVec;
string temp;
zeroVec.push_back("");
if(D == NULL)
return zeroVec;
temp = D->data;
size_t found = temp.find(W);
if(found == 0)
result.push_back(D->data);
if(W <= D->data)
return dictionary_select(D->left, W);
else
return dictionary_select(D->right, W);
}
int main()
{
bool b[5];
dictionary l;
string W, str;
vector <string> vec;
l = new tree;
l->data = "berdi";
l->left = NULL;
l->right = NULL;
b[0] = dictionary_ins_word(l, "atas");
b[1] = dictionary_ins_word(l, "cara");
b[2] = dictionary_ins_word(l, "ata");
b[3] = dictionary_ins_word(l, "atax");
vec = dictionary_select(l, "ata");
for(int i=0; i<vec.size(); i++) {
cout << vec[i] << " ";
}
getchar();
return 0;
}

The problem is your function dictionary_select declares the result vector and never returns it. Below is how you would change this:
vector <string> dictionary_select(const dictionary & D, const string & W)
{
vector < string > result;
vector < string > tempVector; // add this to store the result from the recursion
vector < string > zeroVec;
string temp;
zeroVec.push_back("");
if(D == NULL)
return zeroVec;
temp = D->data;
size_t found = temp.find(W);
if(found == 0)
result.push_back(D->data);
if(W <= D->data)
tempVector = dictionary_select(D->left, W); // get the recursion result
else
tempVector = dictionary_select(D->right, W); // get the recursion result
result.insert(result.end(), tempVector.begin(), tempVector.end()); // append all the results
return result; // return the result
}
UPDATE
In order for the function to return the correct data, you have to also ensure that you look at both left and right sides of the tree to get the appropriate results. The function below has the update:
vector <string> dictionary_select(const dictionary & D, const string & W)
{
vector < string > result;
vector < string > tempVectorLeft; // add this to store the result from the left recursion
vector < string > tempVectorRight; // add this to store the result from the right recursion
vector < string > zeroVec;
string temp;
zeroVec.push_back("");
if(D == NULL)
return zeroVec;
temp = D->data;
size_t found = temp.find(W);
if(found == 0)
result.push_back(D->data);
if(found == 0 || W <= D->data)
tempVectorLeft = dictionary_select(D->left, W); // store results
if(found == 0 || W > D->data)
tempVectorRight = dictionary_select(D->right, W); // store results
result.insert(result.end(), tempVectorLeft.begin(), tempVectorLeft.end()); // append all the left results
result.insert(result.end(), tempVectorRight.begin(), tempVectorRight.end()); // append all the right results
return result;
}

I propose you the following variant:
vector <string> dictionary_select(const dictionary & D, const string & W)
{
vector < string > result;
vector < string > zeroVec;
if (D == NULL)
return zeroVec;
string temp = D->data;
size_t found = temp.find(W);
if (found == 0)
result.push_back(D->data);
if (found || W <= D->data)
for(auto x: dictionary_select(D->left, W))
result.push_back(x);
if (found || W > D->data)
for (auto x : dictionary_select(D->right, W))
result.push_back(x);
return result;
}
The problem in the if / else approach used in you initial algortihm to choose between recureion on left or right node, is that you could have a note like this:
atar
/ \
ata atax
So if the data in the head of the node matches, you need to check both left and right to be sure that you're not missing something.

Related

Backspace String Compare given two strings s and t, return true if they are equal

I am getting a runtime error for this test case using stack
"bxj##tw", "bxj###tw"
Line 171: Char 16: runtime error: reference binding to misaligned address 0xbebebebebebec0ba for type 'int', which requires 4 byte alignment (stl_deque.h)
0xbebebebebebec0ba: note: pointer points here
<memory cannot be printed>
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior /usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/stl_deque.h:180:16
class Solution {
public:
bool backspaceCompare(string s, string t) {
stack<int>st1;
stack<int>st2;
for(int i=0; i<s.size(); i++){
if(st1.empty() && s[i]!='#'){
st1.push(s[i]);
}
else{
if(!st1.empty() && s[i]=='#'){
st1.pop();
}
else if(s[i]=='#' && (st1.empty())){
continue;
}
else{
st1.push(s[i]);
}
}
}
for(int i=0; i < t.size(); i++){
if(st2.empty() && t[i]!='#'){
st2.push(t[i]);
}
else{
if(!st2.empty() && t[i]=='#'){
st2.pop();
}
else if(t[i]=='#' && st2.empty()){
continue;
}
else{
st2.push(t[i]);
}
}
}
if(st1.empty() && st2.empty()){
return "";
}
while(!st1.empty()){
if(st1.top()!= st2.top()){
return false;
}
else{
st1.pop();
st2.pop();
}
}
return true;
}
};
I wouldn't use a stack<char> since the natural representation is a string, and you're not using any functionality of the stack's ability to expand or shrink in the front (other than the end where you can just say return a == b). string has push_back and pop_back methods as well.
For small input (like the ones guaranteed for this challenge problem), I'd recommend constructing the two "editors" and comparing with ==:
class Solution {
public:
bool backspaceCompare(string s, string t) {
return backspace(s) == backspace(t);
}
private:
string backspace(const string &s) {
string editor = "";
string::const_iterator commandItr = s.cbegin();
while(commandItr != s.cend())
if(*commandItr == '#' && !editor.empty()) {
editor.pop_back();
++commandItr;
} else if(*commandItr != '#')
editor.push_back(*commandItr++);
else
++commandItr;
return editor;
}
};
However, they did challenge the coder to use O(1) memory. Here is an example of that:
class Solution {
public:
bool backspaceCompare(string s, string t) {
int left = s.size() - 1;
int right = t.size() - 1;
while(true) {
left = backspace(s, left);
right = backspace(t, right);
if (left == -1 && right == -1)
return true;
if (left == -1 && right != -1 || right == -1 && left != -1)
return false;
if(s[left--] != t[right--])
return false;
}
}
private:
// Returns first index from back that indexes to a non-deleted character
int backspace(string const &s, int startingIndex) {
if(startingIndex == -1)
return -1;
if(s[startingIndex] != '#')
return startingIndex;
unsigned backspaceCount = 0;
while(true) {
while(startingIndex != -1 && s[startingIndex] == '#') {
++backspaceCount;
--startingIndex;
}
while (startingIndex != -1 && backspaceCount && s[startingIndex] != '#') {
--startingIndex;
--backspaceCount;
}
if (startingIndex == -1)
return -1;
else if(s[startingIndex] != '#' && !backspaceCount)
return startingIndex;
}
}
};

g++ saying function doesn't exist even when including the proper header

So I am working on some homework for my uni and need to convert a string to a float. For whatever reason g++ is complaining that the 'stof' function doesn't exist. Although I have included the required header. Here is my code, the error is on the line that says
holder = stof(x.substr(0, end_of_num));
#include <iostream>
#include <string>
#include <list>
using namespace std;
float process_func(string x);
bool isPartOfNum(char x);
int main() {
string x;
while (true) {
cout << "input a string" << endl;
getline(cin, x);
cout << process_func(x);
}
return 0;
}
float process_func(string x) {
int end_of_num =0;// used to find last index from num
int negMult = 1; //used to multiply value at end if there was a negative
bool onNum = false; //used to
list <float> numList;
list <char> operList;
if ((x.at(0) < 48 || x.at(0) > 57) && x.at(0) != '-') //check if start of string doesnt have a number or negative symbol
return -1;
if (x.at(0) != '-')
negMult = -1;
float holder;// temp holder for floats
int i = 0;
while (i<x.length()) {
if (isPartOfNum(x.at(i))) {
end_of_num++;
onNum = true;
}
else if (onNum) {
holder = stof(x.substr(0, end_of_num));
numList.push_back(holder); //adds num as float to list
x.erase(0, end_of_num + 1); //+1 removes the space after the number before the operator
end_of_num = 0;
onNum = false;
}
if (x.at(i) == '+' || x.at(i) == '-' || x.at(i) == '*' || x.at(i) == '/') {
operList.push_back(x.at(i));
}
} //at this point both lists should be full of all needed pieces of info
int answer = 0;
int temp;
bool firstOper=true; // used to hold first operation
while (numList.size() >=2) { //requires at least 2 entries for last operation
while (!operList.empty()) {
temp = numList.front();
numList.pop_front();
if (operList.front() == '+') {
if (firstOper) {
answer = temp + numList.front();
numList.pop_front();
firstOper = false;
}
else {
answer += temp;
}
}
else if (operList.front() == '-') {
if (firstOper) {
answer = temp - numList.front();
numList.pop_front();
firstOper = false;
}
else {
answer -= temp;
}
}
else if (operList.front() == '*') {
if (firstOper) {
answer = temp * numList.front();
numList.pop_front();
firstOper = false;
}
else {
answer *= temp;
}
}
else if (operList.front() == '/') {
if (firstOper) {
answer = temp / numList.front();
numList.pop_front();
firstOper = false;
}
else {
answer /= temp;
}
}
operList.pop_front();
}
}
return answer;
}
bool isPartOfNum(char x) {
if ((x >= 48 && x <= 57) || (x == '-' || x == '.'))
return true;
return false;
}
Solved by compiling using c++ 11

C++: Value of pointer changes "randomly"

I'm creating a function that creates a map from an image with a maze in it.
It takes the image, goes to every pixel and decides if it has to create a node there. One rule is, that when it finds a white pixel at one of the borders it will either be the start or the end node. To tell my pathfinding function where to start, I push the node into a vector(like all other nodes, too) and save the address of that node in a (double)pointer. My problem is, at the end of the loop, the variables in this node change their values(a bool variable might get the value 133) I actually never modify most of the members in this loop. I really have no idea why this is the case...
For examle:
After assigning the node to the pointer:
Completed: false
DistanceTo: 4294967295
PreviousNode: 0x0
XPos: 3
YPos: 0
m_vConnections: <0 Elements>
After function finished:
Completed: 8
DistanceTo: 32674
PreviousNode: SomeAddress
XPos: 3
YPos: 0
m_vConnections: <0 Elements>
The node at SomeAddress actually has completely screwed values, too, but I suspect that the address just changed and it now interprets the data found there as a node.
Sometimes m_vConnections becomes "inaccesseble" which results in sigsegvs when I try to connect something to it.
My function:
bool CreateGraph(const sf::Image &mMaze, std::vector<dijkstra::CNode> *vGraph, dijkstra::CNode **mStart, dijkstra::CNode **mEnd, SMazeCol mColors)
{
*mStart = 0;
unsigned short nExits = 0;
//Get Maze Colours
sf::Color mWallColor = mColors.Wall;
sf::Color mPathColor = mColors.Path;
//Create nodes
for(unsigned int y = 0; y < mMaze.getSize().y; ++y)
{
for(unsigned int x = 0; x < mMaze.getSize().x; ++x)
{
if(mMaze.getPixel(x, y) == mPathColor) //Current pixel is a path
{
bool bTop = false;
bool bBottom = false;
unsigned short nNeighbours = 0;
//Check surroundings of pixel
if(y != 0 && mMaze.getPixel(x, y - 1) == mPathColor)
{
bTop = true;
++nNeighbours;
}
if(y != mMaze.getSize().y - 1 && mMaze.getPixel(x, y + 1) == mPathColor)
{
bBottom = true;
++nNeighbours;
}
if(x != 0 && mMaze.getPixel(x - 1, y) == mPathColor)
{
++nNeighbours;
}
if(x != mMaze.getSize().x - 1 && mMaze.getPixel(x + 1, y) == mPathColor)
{
++nNeighbours;
}
//Decide if a node has to be created at that pixel
if(x == 0 || y == 0 || x == mMaze.getSize().x - 1 || y == mMaze.getSize().y - 1)
{
dijkstra::CNode mNode;
mNode.XPos = x;
mNode.YPos = y;
vGraph->push_back(mNode);
if(*mStart == 0)
{
*mStart = &vGraph->back();
++nExits;
}
else
{
*mEnd = &vGraph->back();
++nExits;
}
}
else if(nNeighbours == 2 && bTop != bBottom)
{
dijkstra::CNode mNode;
mNode.XPos = x;
mNode.YPos = y;
vGraph->push_back(mNode);
}
else if(nNeighbours > 2)
{
dijkstra::CNode mNode;
mNode.XPos = x;
mNode.YPos = y;
vGraph->push_back(mNode);
}
}
}
}
if(nExits != 2)
return false;
The CNode class:
struct SConnection
{
SConnection(CNode *To, unsigned int Distance);
CNode *To;
unsigned int Distance;
};
class CNode
{
public:
CNode();
std::vector<SConnection> Connections()const;
bool AddConnection(CNode *mTo, unsigned int nDistance);
bool AddConnection(const SConnection &mConnection);
bool RemoveConnection(CNode *mTo);
bool operator > (const CNode &rhs)const;
bool operator < (const CNode &rhs)const;
bool operator == (const CNode &rhs)const;
CNode* Addr();
bool Completed;
unsigned int DistanceTo;
CNode *PreviousNode;
unsigned int XPos, YPos;
private:
std::vector<SConnection> m_vConnections;
};
Implementation:
SConnection::SConnection(CNode *To, unsigned int Distance)
{
this->Distance = Distance;
this->To = To;
}
CNode::CNode()
:Completed(false), DistanceTo(std::numeric_limits<unsigned int>::max()), PreviousNode(0)
{
}
std::vector<SConnection> CNode::Connections() const
{
return m_vConnections;
}
bool CNode::AddConnection(CNode *mTo, unsigned int nDistance)
{
if(mTo == 0)
return false;
if(mTo == this)
return false;
for(auto &it : m_vConnections)
{
if(it.To == mTo)
return false;
}
m_vConnections.push_back({mTo, nDistance});
mTo->m_vConnections.push_back({this, nDistance});
return true;
}
bool CNode::AddConnection(const SConnection &mConnection)
{
return (AddConnection(mConnection.To, mConnection.Distance));
}
bool CNode::RemoveConnection(CNode *mTo)
{
for(auto it = m_vConnections.begin(); it != m_vConnections.end(); ++it)
{
if(it->To == mTo)
{
m_vConnections.erase(it);
for(auto it2 = mTo->m_vConnections.begin(); it2 != m_vConnections.end(); ++it2)
{
if(it2->To == this)
mTo->m_vConnections.erase(it2);
}
}
}
return false;
}
bool CNode::operator >(const CNode &rhs)const
{
return DistanceTo > rhs.DistanceTo;
}
bool CNode::operator <(const CNode &rhs) const
{
return DistanceTo < rhs.DistanceTo;
}
bool CNode::operator ==(const CNode &rhs)const
{
return DistanceTo == rhs.DistanceTo;
}
CNode *CNode::Addr()
{
return this;
}
Your main problem is here:
dijkstra::CNode mNode;
//...
vGraph->push_back(mNode);
if(*mStart == 0)
{
*mStart = &vGraph->back();
++nExits;
}
else
{
*mEnd = &vGraph->back();
++nExits;
}
}
else if(nNeighbours == 2 && bTop != bBottom)
{
dijkstra::CNode mNode;
//...
vGraph->push_back(mNode);
}
else if(nNeighbours > 2)
{
dijkstra::CNode mNode;
//...
vGraph->push_back(mNode);
}
Local variables are not placed in global heap, and can be forgotten by programm soon after the code block where they were created is finished.
The better way to improve your code is to rewrite function declaration as
bool CreateGraph(const sf::Image &mMaze, std::vector<dijkstra::CNode*> *vGraph, dijkstra::CNode **mStart, dijkstra::CNode **mEnd, SMazeCol mColors)
And inside function change all:
dijkstra::CNode mNode
vGraph->push_back(mNode);
to
std::shared_ptr<dijkstra::CNode> mNode =
std::shared_ptr<dijkstra::CNode>(new dijkstra::CNode(X, Y));
vGraph->push_back(mNode.get());

Lookup function not working

I'm trying to have an algorithm that makes a DFA for a tic tac toe game. With the code I have right now, there are repeating states. I made a lookup function to see if the state already before adding it and add the already made state to a the parent state's vector of children.
I have tried implementing it, but I'm still getting the same number of nodes that I was getting before I implemented it meaning its never finding another state that with the same 'position' array and it is suppose to. I don't see what I'm doing wrong. It never returns anything.
UPDATE: I do know that it is returning to soon and not going through all the elements, but I don't know how to make it go through all the states and make it stop returning too soon.
UPDATE 2.0: So I've changed where my lookup is, it is now in my Main.cpp file. I also changed how it goes through, but it still isn't returning correctly.
Any ideas? Here is my code:
States.cpp
#include "States.hpp"
State::State(){
final = false;
reject = false;
draw = false;
for (int i = 0; i < 9; i++)
_position[i] = 2;
firstPlayerMove = true;
_children = new vector<State *> ();
};
void State::setStateChildren(State *s){
_children->push_back(s);
}
vector<State*> *State::getChildren(){
return _children;
}
void State::setFirstMove(bool b){
firstPlayerMove = b;
}
bool State::firstMove(){
return firstPlayerMove;
}
void State::setPosition(int p[]){
for (int i = 0; i < 9; i++){
_position[i] = p[i];
}
}
int *State::position(){
return _position;
}
bool State::isFinal(){
return final;
}
bool State::isReject(){
return reject;
}
Main.cpp
#include <iostream>
#include <vector>
#include "States.hpp"
using namespace std;
void dependents(State *root, State *state, bool first);
int size (State *s);
bool win(int p[], int symbol);
bool draw(int p[]);
void CreateDFA(State *root, State *state, int n){
if (n == 0 || state == nullptr)
return;
if (state->isFinal() || state->isReject() || state->isDraw())
return;
dependents(root, state, state->firstMove());
for (vector<State*>::iterator iter = state->getChildren()->begin(); iter != state->getChildren()->end(); iter++){
CreateDFA(root, *iter, n - 1);
}
}
void dependents(State *root, State *state, bool first){
int symbol;
if (first)
symbol = 1;
else
symbol = 0;
int count = 0;
while (count < 9){
if (state->position()[count] == 2 && state->position()[count] != 1 && state->position()[count] != 0){
int check[9];
for(int i = 0; i < 9; i++)
check[i] = state->position()[i];
check[count] = symbol;
State *child = root->find(root, check);
if (child == nullptr){
child = new State();
child->setPosition(state->position());
child->setFirstMove(!(state->firstMove()));
child->position()[count] = symbol;
child->setFinal(win(child->position(), 1));
child->setReject(win(child->position(), 0));
child->setDraw(draw(child->position()));
}
state->setStateChildren(child);
}
count++;
}
}
bool win(int p[], int symbol){
if(p[0] == symbol && p[1] == symbol && p[2] == symbol)
return true;
if(p[0] == symbol && p[4] == symbol && p[8] == symbol)
return true;
if(p[0] == symbol && p[6] == symbol && p[3] == symbol)
return true;
if(p[1] == symbol && p[4] == symbol && p[7] == symbol)
return true;
if(p[2] == symbol && p[4] == symbol && p[6] == symbol)
return true;
if(p[2] == symbol && p[5] == symbol && p[8] == symbol)
return true;
if(p[3] == symbol && p[4] == symbol && p[5] == symbol)
return true;
if(p[6] == symbol && p[7] == symbol && p[8] == symbol)
return true;
return false;
}
bool draw(int p[]){
if(p[0] != 2 && p[1] != 2 && p[2] != 2 && p[3] != 2 && p[4] != 2 && p[5] != 2 && p[6] != 2 && p[7] != 2 && p[8] != 2){
cout << "Set Draw" << endl;
return true;
}
return false;
}
int size (State *s){
if (s == nullptr)
return 0;
int count = 0;
for(vector<State*>::iterator iter = s->getChildren()->begin(); iter != s->getChildren()->end(); iter++)
count = size(*iter) + count;
return count + 1;
}
bool check(int p[], int a[]){
for(int i = 0; i < 9; i++)
if (p[i] != a[i])
return false;
return true;
}
State *find(State * root, int p[]){
if (root->isFinal() || root->isReject() || root->isDraw())
return nullptr;
State * s = nullptr;
for (vector<State*>::iterator iter = root->getChildren()->begin(); iter != root->getChildren()->end(); iter++){
if(check((*iter)->position(), p)){
s = new State (**iter);
break;
}
else
s = find((*iter), p);
}
return s;
}

Why I am getting zero output for all the values in array?

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.