Binary search for insert char string. Where is the bug? - c++

I have array of strings. I must find one char string in array of strings by binary search algoritm. If there is this one string then function must return position and return true otherwise this function must return position for insert string in array and false.
I have somewhere bug, but I dont know where ((
Example:
bool Binary_search ( char * arr_strings[], int & position, const char * search_string )
{
int start = 0 ;
int end = 10 - 1; // arr_strings [10]
int for_compare;
int middle;
while ( start <= end )
{
middle = ( start + end ) / 2;
for_compare = strcmp ( arr_strings[middle], search_string );
if ( for_compare > 0 )
{
start = middle + 1;
}
else if ( for_compare < 0 )
{
end = middle - 1;
}
else
{
// if search_string is found in array, then function return position in array of strings and return true
position = middle;
return true;
}
}
// if search_string is not found in array, then function must return position for insert string and return false
position = middle;
return false;
}

I think maybe it should be:
if ( for_compare > 0 )
{
end = middle - 1;
}
else if ( for_compare < 0 )
{
start = middle + 1;
}

The issue is that your insertion position is not right.
You should do something like the following:
bool Binary_search ( char * arr_strings[], const char * search_string )
{ //^^^you are not doing recursive, so you don't need position as parameter
int start = 0 ;
int end = 10 - 1; // arr_strings [10]
int for_compare;
int middle;
int position = -1;
while ( start <= end )
{
middle = ( start + end ) / 2;
for_compare = strcmp ( arr_strings[middle], search_string );
if ( for_compare > 0 )
{ //^^^here should switch the order
end = middle - 1;
}
else if ( for_compare < 0 )
{
start = middle + 1;
}
else
{
position = middle;
return true;
}
}
if (position == -1)
{
if(strcmp(arr_strings[middle],search_string) <0 )
{
position = middle + 1;
}else
{
position = middle;
}
}
return position;
}

Related

Binary searching using const pointer

We should implement a function that uses binary search to check if a value key is in the array and give either true or false.
My goes like this:
bool binary_search(const int* begin, const int * end, int key){
if(begin < end){
int mid = (end-begin)/2;
if(mid == key){
return true;
}else if (key < mid){
int h = mid-1;
end = &h;
binary_search(begin, end, key);
}else if (mid < key){
int i = mid+1;
begin = &i;
binary_search(begin, end, key);
}
}else{
return false;
}
}
but it wouldn't give any output but instead it gives me the error.
warning: control reaches end of non-void function [-Wreturn-type]
I don't really understand what I have to do here so can someone explain me what is going wrong here?
In case of these if else statements
}else if (key < mid){
int h = mid-1;
end = &h;
binary_search(begin, end, key);
}else if (mid < key){
int i = mid+1;
begin = &i;
binary_search(begin, end, key);
}
the function returns nothing. That is these code blocks do not have return statements.
Moreover the function does not make sense because for example in these statements
int mid = (end-begin)/2;
if(mid == key){
there are compared key with an index of the array instead of comparing key with the value of the element in the array with index mid.
Or these statements
int h = mid-1;
end = &h;
also do not make sense because the variable end will store an address of the local variable h.
The function can be implemented the following way as it is shown in this demonstrative program.
#include <iostream>
#include <iomanip>
bool binary_search( const int *begin, const int *end, int key )
{
if ( begin < end )
{
const int *mid = begin + ( end - begin ) / 2;
if ( *mid < key ) return binary_search( ++mid, end, key );
else if ( key < *mid ) return binary_search( begin, mid, key );
else return true;
}
else
{
return false;
}
}
int main()
{
int a[] = { 1, 3, 5 };
const size_t N = sizeof( a ) / sizeof( *a );
for ( size_t i = 0; i <= a[N-1] + 1; i++ )
{
std::cout << i << " is present in the array - "
<< std::boolalpha << binary_search( a, a + N, i )
<< std::endl;
}
return 0;
}
Its output is
0 is present in the array - false
1 is present in the array - true
2 is present in the array - false
3 is present in the array - true
4 is present in the array - false
5 is present in the array - true
6 is present in the array - false
You should return in all the possible branches.
Change
binary_search(begin, end, key);
to
return binary_search(begin, end, key);
to return the result from the recursive invocation.

bad_alloc from libc.so.6 C++

I'm running a C++ program under gdb into a Debian 7 64bit machine 4gb RAM and i encountered a Bad_alloc problem.
Try running it under gdb this is the backtrace
Program received signal SIGABRT, Aborted.
0x00007ffff72e5475 in raise () from /lib/x86_64-linux-gnu/libc.so.6
(gdb) bt
#0 0x00007ffff72e5475 in raise () from /lib/x86_64-linux-gnu/libc.so.6
#1 0x00007ffff72e86f0 in abort () from /lib/x86_64-linux-gnu/libc.so.6
#2 0x00007ffff7b3b89d in __gnu_cxx::__verbose_terminate_handler() ()
from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#3 0x00007ffff7b39996 in ?? () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#4 0x00007ffff7b399c3 in std::terminate() ()
from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#5 0x00007ffff7b39bee in __cxa_throw ()
from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#6 0x00007ffff7b3a0dd in operator new(unsigned long) ()
from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#7 0x000000000040bfdb in allocate (__n=67108864, this=)
at /usr/include/c++/4.7/ext/new_allocator.h:94
#8 _M_allocate (__n=, this=)
at /usr/include/c++/4.7/bits/stl_vector.h:169
#9 std::vector >::_M_insert_aux (
this=this#entry=0x1f50c68, __position=..., __position#entry=..., __x=...)
at /usr/include/c++/4.7/bits/vector.tcc:343
#10 0x00000000004201eb in push_back (__x=..., this=0x1f50c68)
at /usr/include/c++/4.7/bits/stl_vector.h:893
#11 RDFCFTree::closedExtensionExplore (this=this#entry=0x21349950,
frequency=..., outFile=..., database=..., occList=..., frequent2Tree=...,
headIndex=..., threshold=#0x7fffffffd818: 6, checked=..., closed=...,
maximal=...) at RDFCFTree.cpp:1280
#12 0x000000000041ffd0 in RDFCFTree::closedExtensionExplore (
this=this#entry=0x1284a10, frequency=..., outFile=..., database=...,
occList=..., frequent2Tree=..., headIndex=...,
threshold=#0x7fffffffd818: 6, checked=..., closed=..., maximal=...)
at RDFCFTree.cpp:1302
#13 0x000000000041ffd0 in RDFCFTree::closedExtensionExplore (
this=this#entry=0x737a20, frequency=..., outFile=..., database=...,
occList=..., frequent2Tree=..., headIndex=...,
threshold=#0x7fffffffd818: 6, checked=..., closed=..., maximal=...)
at RDFCFTree.cpp:1302
#14 0x000000000041ffd0 in RDFCFTree::closedExtensionExplore (
this=this#entry=0x67bbd0, frequency=..., outFile=..., database=...,
occList=..., frequent2Tree=..., headIndex=...,
threshold=#0x7fffffffd818: 6, checked=..., closed=..., maximal=...)
at RDFCFTree.cpp:1302
#15 0x000000000041ffd0 in RDFCFTree::closedExtensionExplore (this=0x6f0ac0,
frequency=..., outFile=..., database=..., occList=..., frequent2Tree=...,
headIndex=..., threshold=#0x7fffffffd818: 6, checked=..., closed=...,
maximal=...) at RDFCFTree.cpp:1302
#16 0x0000000000405252 in RFrequentTreeList::extensionExploreList4 (
this=0x7fffffffd8c0, database=..., outFile=..., frequency=...,
threshold=#0x7fffffffd818: 6, checked=..., closed=..., maximal=...)
at RFrequentTreeList.cpp:248
#17 0x0000000000401fd0 in main (argc=, argv=)
at CMTreeMiner.cpp:112
This is the constructor of RDFCFTree:
RDFCFTree::RDFCFTree(const RDFCFTree& parent,
short newEdgeLabel, short newVertexLabel, short position)
{
/******************************************************************
idea: copy the tree structure of the parent, plus one new leg
Note: use deep copy and preserve the original order of link list
at the end, recompute the DFCS and automorphisms
******************************************************************/
vCount = parent.vCount + 1;
tid = parent.tid;
adj.resize(vCount + 1);
TnodeLink t1, t2, t3;
for ( short i = 1; i <= vCount - 1; i++ ) //copy the parent part here
{
t1 = parent.adj[i];
if ( t1 == 0 ) //unlike to happen for a tree
{
adj[i] = 0;
continue;
}
else
{
t2 = new Tnode(*t1);
adj[i] = t2;
while ( t1->next != 0 )
{
t1 = t1->next;
t3 = new Tnode(*t1);
t2->next = t3;
t2 = t3;
}
}
}
vertexLabel = parent.vertexLabel;
vertexLabel.push_back(newVertexLabel);
degree = parent.degree;
degree.push_back(0);
level = parent.level;
level.push_back(level[position]+1);
insertEdge(Edge(position,vCount,newEdgeLabel));
automorphism.resize(vCount+1);
computeDFCS();
computeAutomorphism();
}
This is the closedExtensionExplore function:
void RDFCFTree::closedExtensionExplore( vector<long>&frequency,
ostream & outFile,
const vector<ptrRFreeTree>& database,
const vector<Occurrence> & occList,
const vector< vector<short> > & frequent2Tree,
const vector<long> & headIndex,
const long & threshold,
vector<long> & checked,
vector<long> & closed,
vector<long> & maximal)
{
/******************************************************************
step0: output this tree
******************************************************************/
checked[vCount]++;
TnodeLink t;
/******************************************************************
step1: using occurrence-match pruning
******************************************************************/
/******************************************************************
step1.1: initialize the parent from the first occurrence
******************************************************************/
short parentVertex, parentEdge;
bool sameParent = true;
if ( occList[0].nodeIndex[0] == 1 ) //if the first occurrence's root
//is the root of the transaction
sameParent = false;
else
{
t = database[occList[0].tid]->adj[occList[0].nodeIndex[0]];
while ( t->next != 0 ) t = t->next;
parentEdge = t->eLabel;
parentVertex = database[occList[0].tid]->vertexLabel[t->v];
}
/******************************************************************
step1.2: use other occurrences to compute the intersections of parents
******************************************************************/
for ( long s = 1; s < occList.size(); s++ )
{
short tempEdge, tempVertex;
if ( occList[s].nodeIndex[0] == 1 ) //if the occurrence's root
//is the root of the transaction
sameParent = false;
else
{
t = database[occList[s].tid]->adj[occList[s].nodeIndex[0]];
while ( t->next != 0 ) t = t->next;
tempEdge = t->eLabel;
tempVertex = database[occList[s].tid]->vertexLabel[t->v];
if ( tempEdge != parentEdge || tempVertex != parentVertex )
sameParent = false;
}
if ( sameParent == false ) break;
}
//parent-pruning
if ( sameParent == true ) return;
/******************************************************************
step1.3: find the locations where a new leg can grow
******************************************************************/
vector<short> positionToExplore;
if ( vCount != 1 ) //be careful! For a single-vertex tree, adj[j] = empty
{
short j = 1;
while ( level[j] == 1 || degree[j] > 1 )
{
positionToExplore.push_back(j);
j = adj[j]->v;
}
positionToExplore.push_back(j);
}
else
positionToExplore.push_back(1);
/******************************************************************
step1.4: compute the range of labels for each vertex
******************************************************************/
vector<short> vertexRange(vCount + 1, MAX_VERTEX + 1);
vector<short> edgeRange(vCount + 1, MAX_EDGE + 1);
for ( short j = 0; j < positionToExplore.size(); j++ )
{
short i = positionToExplore[j];
possibleLegs(i, edgeRange[i], vertexRange[i]);
}
/******************************************************************
step1.5: initialize the list of legs from the first occurrence
******************************************************************/
vector<short> legTriple(3); //vertex index, leg edge label, leg vertex label
vector<vector<short> > commonLegs;
set<short> neighbors; //
set<short>::iterator pos;
for ( short i = 1; i <= vCount; i++ )
{
neighbors.clear();
t = adj[i];
while ( t != 0 ) //insert index of all neighbors of the position i
{
neighbors.insert(occList[0].nodeIndex[t->v - 1]);//inconsistency on index
t = t->next;
}
t = database[occList[0].tid]->adj[occList[0].nodeIndex[i-1]];
while ( t != 0 )
{
if ( occList[0].nodeIndex[i-1] < t->v )
{
pos = neighbors.find( t->v );
if ( pos == neighbors.end() ) //if the vertex hasn't been used
{
legTriple[0] = i;
legTriple[1] = t->eLabel;
legTriple[2] = database[occList[0].tid]->vertexLabel[t->v];
commonLegs.push_back(legTriple);
}
}
t = t->next;
}//end of while ( t != 0 )
}
/******************************************************************
step1.6: use other occurrences to compute the intersections of legs
******************************************************************/
for ( long s = 1; s < occList.size(); s++ )
{
vector<bool> isFetched(vCount + 1, false);
vector<vector<short> > tupleLegs(0);
vector<short> legEVPair(2);
vector<vector<short> >::iterator pos1;
for ( pos1 = commonLegs.begin(); pos1 != commonLegs.end(); )
{
vector<short> thisTriple = *pos1; //get the next commonLeg
//debug
//cout << commonLegs.size() << endl;
//cout << thisTriple[0] << ' ' << thisTriple[1] << ' ' << thisTriple[2] << endl;
short i = thisTriple[0]; //the index of vertex
//assuming the indices in the commonLegs are non-decreasing
if ( !isFetched[i] ) //fetch all neighbors of the vertex in the
//corresponding database transaction
{
neighbors.clear();
tupleLegs.resize(0);
t = adj[i];
while ( t != 0 ) //insert index of all neighbors of the position i
{
neighbors.insert(occList[s].nodeIndex[t->v - 1]);//inconsistency on index
t = t->next;
}
t = database[occList[s].tid]->adj[occList[s].nodeIndex[i-1]];
while ( t != 0 )
{
if ( occList[s].nodeIndex[i-1] < t->v )
{
pos = neighbors.find( t->v );
if ( pos == neighbors.end() ) //if the vertex hasn't been used
{
legEVPair[0] = t->eLabel;
legEVPair[1] = database[occList[s].tid]->vertexLabel[t->v];
tupleLegs.push_back(legEVPair);
}
}
t = t->next;
}
isFetched[i] = true;
}
bool isFound = false;
for ( short k = 0; k < tupleLegs.size(); k++ )
{
if ( thisTriple[1] == tupleLegs[k][0] && thisTriple[2] == tupleLegs[k][1] )
{
isFound = true;
break;
}
}
if ( !isFound )
{
pos1 = commonLegs.erase(pos1);
}
else
{
++pos1;
}
}
if ( commonLegs.size() == 0 ) break;
}
if ( commonLegs.size() != 0 )
{
set<short> positionSet;
for ( short i = 0; i < positionToExplore.size(); i++ )
positionSet.insert(positionToExplore[i]);
for ( short i = 0; i < commonLegs.size(); i++ )
{
pos = positionSet.find(commonLegs[i][0]);
if ( pos == positionSet.end() ) //not on the rightmost path
{
return;
}
else
{
short j = commonLegs[i][0];
if ( (commonLegs[i][1] < edgeRange[j]) ||
((commonLegs[i][1] == edgeRange[j]) && (commonLegs[i][2] < vertexRange[j])) )
return;
}
}
}
bool isClosed = true;
bool isMaximal = true;
/******************************************************************
step2: check if this tree is closed
******************************************************************/
while ( true )
{
/******************************************************************
step2.1: if from the previous step, there are common legs, then not closed
******************************************************************/
if ( commonLegs.size() != 0 )
{
isClosed = false;
isMaximal = false;
break;
}
/******************************************************************
step2.2: get the list of parents of the first tid
******************************************************************/
vector< vector<short> > candidateParent;
vector<short> parentPair(2,0); //parentEdge, then parentVertex
sameParent = true;
long m = 0;
long n = 0;
long tempTid = occList[0].tid;
while ( m < occList.size() && occList[m].tid == tempTid )
{
if ( occList[m].nodeIndex[0] != 1 )
//if the first occurrence's root
//is not the root of the transaction
{
t = database[occList[m].tid]->adj[occList[m].nodeIndex[0]];
while ( t->next != 0 ) t = t->next;
parentPair[0] = t->eLabel;
parentPair[1] = database[occList[m].tid]->vertexLabel[t->v];
candidateParent.push_back(parentPair);
}
m++;
}
//now candidateParent holds all possible parents
/******************************************************************
step2.3: use other transactions to compute the intersections of parents
******************************************************************/
if ( candidateParent.size() == 0 )
{
sameParent = false;
}
else
{
while ( m < occList.size() && candidateParent.size() != 0 )
{
n = m;
short tempEdge, tempVertex;
while ( n < occList.size() && occList[n].tid == occList[m].tid )
n++;
n--;
vector < vector<short> >::iterator pos1;
for ( pos1 = candidateParent.begin(); pos1 != candidateParent.end(); )
{
bool tempFlag = false;
for ( long s = m; s <= n; s++ )
{
if ( occList[s].nodeIndex[0] != 1 )
{
t = database[occList[s].tid]->adj[occList[s].nodeIndex[0]];
while ( t->next != 0 ) t = t->next;
tempEdge = t->eLabel;
tempVertex = database[occList[s].tid]->vertexLabel[t->v];
if ( tempEdge == (*pos1)[0] && tempVertex == (*pos1)[1] )
{
tempFlag = true;
break; //break the for loop: for ( s = m; ... )
}
}
}
if ( tempFlag == true ) ++pos1;
else pos1 = candidateParent.erase(pos1);
}
m = n+1;
}//end of while ( m < ... )
}
//parent-closed-checking
if ( candidateParent.size() == 0 )
sameParent = false;
if ( sameParent == true )
{
isClosed = false;
isMaximal = false;
break;
}
/******************************************************************
step2.4: get the list of legs of the first tid
******************************************************************/
commonLegs.clear();
m = 0;
n = 0;
tempTid = occList[0].tid;
while ( n < occList.size() && occList[n].tid == tempTid )
n++;
n--;
for ( short i = 1; i <= vCount; i++ )
{
for ( long s = m; s <= n; s++ )
{
neighbors.clear();
t = adj[i];
while ( t != 0 ) //insert index of all neighbors of the position i
{
neighbors.insert(occList[s].nodeIndex[t->v - 1]);//inconsistency on index
t = t->next;
}
t = database[occList[s].tid]->adj[occList[s].nodeIndex[i-1]];
while ( t != 0 )
{
if ( occList[s].nodeIndex[i-1] < t->v )
{
pos = neighbors.find( t->v );
if ( pos == neighbors.end() ) //if the vertex hasn't been used
{
legTriple[0] = i;
legTriple[1] = t->eLabel;
legTriple[2] = database[occList[s].tid]->vertexLabel[t->v];
commonLegs.push_back(legTriple);
}
}
t = t->next;
}//end of while ( t != 0 )
}//end of for ( long s = m; ... )
}
//now commonLegs stores all possible new legs
/******************************************************************
step2.5: using other transactions to prune commonLegs
******************************************************************/
m = n+1; //next tid
while ( m < occList.size() && commonLegs.size() != 0 )
{
n = m+1;
while ( n < occList.size() && occList[n].tid == occList[m].tid )
n++;
n--; //now from m to n are the occurrences sharing the same tid
vector<bool> isFetched(vCount + 1, false);
vector<vector<short> > tupleLegs(0);
vector<short> legEVPair(2);
vector<vector<short> >::iterator pos1;
for ( pos1 = commonLegs.begin(); pos1 != commonLegs.end(); )
{
vector<short> thisTriple = *pos1; //get the next commonLeg
short i = thisTriple[0]; //the index of vertex
//assuming the indices in the commonLegs are non-decreasing
if ( !isFetched[i] ) //fetch all neighbors of the vertex in the
//corresponding database transaction
{
tupleLegs.resize(0);
for ( long s = m; s <= n; s++ )
{
neighbors.clear();
t = adj[i];
while ( t != 0 ) //insert index of all neighbors of the position i
{
neighbors.insert(occList[s].nodeIndex[t->v - 1]);//inconsistency on index
t = t->next;
}
t = database[occList[s].tid]->adj[occList[s].nodeIndex[i-1]];
while ( t != 0 )
{
if ( occList[s].nodeIndex[i-1] < t->v )
{
pos = neighbors.find( t->v );
if ( pos == neighbors.end() ) //if the vertex hasn't been used
{
legEVPair[0] = t->eLabel;
legEVPair[1] = database[occList[s].tid]->vertexLabel[t->v];
tupleLegs.push_back(legEVPair);
}
}
t = t->next;
}
}//end of for ( long s = m; ... )
isFetched[i] = true;
}
bool isFound = false;
for ( short k = 0; k < tupleLegs.size(); k++ )
{
if ( thisTriple[1] == tupleLegs[k][0] && thisTriple[2] == tupleLegs[k][1] )
{
isFound = true;
break;
}
}
if ( !isFound )
{
pos1 = commonLegs.erase(pos1);
}
else
{
++pos1;
}
}
if ( commonLegs.size() == 0 ) break;
m = n+1;
}//end of while ( m < ... )
if ( commonLegs.size() != 0 )
{
isClosed = false;
isMaximal = false;
break;
}
break;
}//end of while at the very beginning of step2
if ( isClosed == true ) closed[vCount]++;
/******************************************************************
step3: main loop, for each position, explore
******************************************************************/
for ( short j = 0; j < positionToExplore.size(); j++ )
{
short i = positionToExplore[j];
//step3_1: get the range of valid legs
short minEdge = edgeRange[i];
short minVertex = vertexRange[i];
//if there is no possible leg at this position
if ( minEdge > MAX_EDGE ) continue; //continue the for loop
//if there is no frequent 2-tree starting from this vertex label
if ( headIndex[vertexLabel[i] - MIN_VERTEX] == 0 ) continue;
//step3_2: get the possible frequent legs
vector<bool> isFrequent( (MAX_EDGE - MIN_EDGE + 1)
*(MAX_VERTEX - MIN_VERTEX + 1), false);
for (short j = headIndex[vertexLabel[i] - MIN_VERTEX];
(j < frequent2Tree.size() && frequent2Tree[j][0] == vertexLabel[i]); j++ )
isFrequent[( frequent2Tree[j][1] - MIN_EDGE ) * ( MAX_VERTEX - MIN_VERTEX + 1 )
+ ( frequent2Tree[j][2] - MIN_VERTEX )] = true;
//step2_3: explore each potential leg
Occurrence tempOcc;
vector<SupportNode> potential((MAX_EDGE - MIN_EDGE + 1)
*(MAX_VERTEX - MIN_VERTEX + 1));
for ( long s = 0; s < occList.size(); s++ )
{
neighbors.clear();
t = adj[i];
while ( t != 0 ) //insert index of all neighbors of the position i
{
neighbors.insert(occList[s].nodeIndex[t->v - 1]);//inconsistency on index
t = t->next;
}
t = database[occList[s].tid]->adj[occList[s].nodeIndex[i-1]];
while ( t != 0 )
{
if ( occList[s].nodeIndex[i-1] < t->v )
{
pos = neighbors.find( t->v );
if ( pos == neighbors.end() ) //if the vertex hasn't been used
{
short tempE = t->eLabel;
short tempV = database[occList[s].tid]->vertexLabel[t->v];
short location = ( tempE - MIN_EDGE ) * ( MAX_VERTEX - MIN_VERTEX + 1 )
+ ( tempV - MIN_VERTEX );
if ( ((tempE > minEdge) || (tempE == minEdge && tempV >= minVertex)) &&
isFrequent[location] ) //if the leg is potentially frequent
{
tempOcc = occList[s];
tempOcc.nodeIndex.push_back(t->v);
**potential[location].occList.push_back(tempOcc);**
if ( tempOcc.tid != potential[location].lastTid )
{
potential[location].lastTid = tempOcc.tid;
potential[location].support++;
}
}
}
}
t = t->next;
}//end of while ( t != 0 )
}//end of for ( s = 0; ...)
for ( long s = 0; s < potential.size(); s++ )
{
if ( potential[s].support >= threshold )
{
isMaximal = false; //this tree cannot be maximal
short tempE = MIN_EDGE + (short)(floor(s/(MAX_VERTEX - MIN_VERTEX + 1)));
short tempV = MIN_VERTEX + (s % (MAX_VERTEX - MIN_VERTEX + 1));
RDFCFTree *pbfcf = new RDFCFTree(*this,tempE,tempV,i);
pbfcf->closedExtensionExplore(frequency, outFile, database,potential[s].occList,
frequent2Tree,headIndex,threshold, checked, closed, maximal);
delete pbfcf;
}
}
////test
//cout << "leg position is: " << i << " vertex label is: " << vertexLabel[i] << endl;
//cout << "min edge and min vertex are: " << minEdge << ' ' << minVertex << endl;
//for ( j = 0; j < isFrequent.size(); j++ )
// cout << isFrequent[j] << ' ';
//cout << endl;
//cout << endl;
}//end of for(short j = ...)
/******************************************************************
step4: check if this tree is maximal
******************************************************************/
/******************************************************************
step4.1: if determined from the previous step not maximal
******************************************************************/
if ( isClosed == false || isMaximal == false) return;
/******************************************************************
step4.2: check the frequent parents
******************************************************************/
vector<long> tempVector(MAX_VERTEX-MIN_VERTEX+1,0);
vector < vector <long> > countingMatrix(MAX_EDGE-MIN_EDGE+1,tempVector);
long m = 0;
long n = 0;
while ( m < occList.size() )
{
n = m+1;
while ( n < occList.size() && occList[n].tid == occList[m].tid )
n++;
n--;
set<pair<short,short> > parentEVPairs;
short tempEdge, tempVertex;
for ( long s = m; s <= n; s++ )
{
if ( occList[s].nodeIndex[0] != 1 )
//if the first occurrence's root
//is not the root of the transaction
{
t = database[occList[s].tid]->adj[occList[s].nodeIndex[0]];
while ( t->next != 0 ) t = t->next;
tempEdge = t->eLabel;
tempVertex = database[occList[s].tid]->vertexLabel[t->v];
parentEVPairs.insert(make_pair(tempEdge,tempVertex));
}
}
set<pair<short,short> >::iterator pos2;
for ( pos2 = parentEVPairs.begin(); pos2 != parentEVPairs.end(); ++pos2 )
countingMatrix[pos2->first - MIN_EDGE][pos2->second - MIN_VERTEX]++;
m = n+1;
}//end of while ( m < ... )
bool tempFlag = false;
for ( short i = 0; i < MAX_EDGE-MIN_EDGE+1; i++ )
{
if ( tempFlag == false )
{
for ( short j = 0; j < MAX_VERTEX - MIN_VERTEX+1; j++ )
{
if ( countingMatrix[i][j] >= threshold )
{
tempFlag = true;
break;
}
}
}
else
break;
}
if ( tempFlag == true ) //not maximal
{
isMaximal = false;
return;
}
/******************************************************************
step4.3: check the frequent new legs, at any place
******************************************************************/
for ( short i = 1; i <= vCount; i++ )
{
vector<long> tempVector2(MAX_VERTEX-MIN_VERTEX+1,0);
vector < vector <long> > countingMatrix2(MAX_EDGE-MIN_EDGE+1,tempVector2);
long m = 0;
long n = 0;
while ( m < occList.size() )
{
n = m+1;
while ( n < occList.size() && occList[n].tid == occList[m].tid )
n++;
n--;
set<pair<short,short> > legEVPairs;
short tempEdge2, tempVertex2;
for ( long s = m; s <= n; s++ )
{
neighbors.clear();
t = adj[i];
while ( t != 0 ) //insert index of all neighbors of the position i
{
neighbors.insert(occList[s].nodeIndex[t->v - 1]);//inconsistency on index
t = t->next;
}
t = database[occList[s].tid]->adj[occList[s].nodeIndex[i-1]];
while ( t != 0 )
{
if ( occList[s].nodeIndex[i-1] < t->v )
{
pos = neighbors.find( t->v );
if ( pos == neighbors.end() ) //if the vertex hasn't been used
{
tempEdge2 = t->eLabel;
tempVertex2 = database[occList[s].tid]->vertexLabel[t->v];
legEVPairs.insert(make_pair(tempEdge2,tempVertex2));
}
}
t = t->next;
}
}//end of for ( long s = m; ... )
set<pair<short,short> >::iterator pos2;
for ( pos2 = legEVPairs.begin(); pos2 != legEVPairs.end(); ++pos2 )
countingMatrix2[pos2->first - MIN_EDGE][pos2->second - MIN_VERTEX]++;
m = n+1;
}//end of while ( m < ... )
bool tempFlag2 = false;
for ( short k = 0; k < MAX_EDGE-MIN_EDGE+1; k++ )
{
if ( tempFlag2 == false )
{
for ( short j = 0; j < MAX_VERTEX - MIN_VERTEX+1; j++ )
{
if ( countingMatrix2[k][j] >= threshold )
{
tempFlag2 = true;
break;
}
}
}
else
break;
}
if ( tempFlag2 == true ) //not maximal
{
isMaximal = false;
return;
}
}//end of for ( short i ... )
if ( isMaximal == true ) maximal[vCount]++;
//cout << *this;
//cout << "support is: " << occList.size() << endl << endl;
/*
}
how can i understand which causes this problem? which variable?
Thank you so much
You appear to be trying to create a vector with 67,108,864 elements. That fails because the resulting allocation request is unreasonably large.
i'll try increasing stack/heap limit with "ulimit -s unlimited"
That is unlikely to help (it will not make allocation request any smaller).
Are you expecting your vector to be this large? If not, you need to look for a bug in your algorithm.
Update:
how do you see the length of the vector?
You can see that in the GDB output:
#7 0x000000000040bfdb in allocate (__n=67108864, this=)
yes it is possible that the array becomes so large because it's a mining algorithm. what can i do?
I can't tell what is the type of the vector you are push_backing into (you appear to have screwed up cut/paste, or edited the GDB backtrace, and didn't tell us which line is line 1280). Chances are, the element size is quite large. You may have to store pointers to elements in the vector, instead of elements themselves.

Segmentation Fault in Vectors

So, I'm doing the famous "The Blocks Problem" from UVa Online Judge.
My approach is quite stupid, and that's because I wanted to play with vectors. So, I got vectors for pointers to each blocks in piles, and those vectors are stored in a vector called collection.
In order to find all the blocks, I have a vector called blockCollection, where pointers to all the blocks are stored inside.
The code has passed the samples provided. I will try to edit and provide comments later.
Full Source:
#include <iostream>
#include <vector>
struct Block
{
int id;
std::vector<Block*>* where;
};
int positionInVector(Block* b);
int main(int argc, const char * argv[])
{
std::vector<std::vector<Block*>*> collection;
std::vector<Block*> blockCollection;
std::string command = "", command2 = "";
int blockCount = 0, k = 0, A = 0, B = 0;
while ( std::cin >> blockCount )
{
std::vector<Block*>* vectors = new std::vector<Block*>[blockCount];
Block* blocks = new Block[blockCount];
for ( k = 0 ; k < blockCount ; ++ k)
{
blocks[k].id = k;
blocks[k].where = &vectors[k];
vectors[k].push_back(&blocks[k]);
blockCollection.push_back(&blocks[k]);
collection.push_back(&vectors[k]);
}
std::cin >> std::ws;
while ( std::cin >> command )
{
if ( command == "quit" ) break;
std::cin >> A >> command2 >> B;
Block* blockA = blockCollection[A];
Block* blockB = blockCollection[B];
std::vector<Block*>* vectorA = blockA -> where;
std::vector<Block*>* vectorB = blockB -> where;
//exception handle
if ( A > blockCount || B > blockCount ) continue;
if ( A == B ) continue;
if ( vectorA == vectorB ) continue;
if ( command == "move" )
{
//move anything on top of A to its original position
int positionOfBlockAInVectorA = positionInVector(blockA);
for ( int i = positionOfBlockAInVectorA + 1 ; i < vectorA -> size() ; ++ i )
{
Block* blockToBeMoved = *(vectorA -> begin() + i);
std::vector<Block*>* destinationVector = collection[blockToBeMoved -> id];
blockToBeMoved -> where = destinationVector;
destinationVector -> push_back(blockToBeMoved);
}
vectorA -> erase(vectorA -> begin() + positionOfBlockAInVectorA + 1, vectorA -> end());
}
if ( command2 == "onto" )
{
//move anything on top of B to its original position
int positionOfBlockBInVectorB = positionInVector(blockB);
for ( int i = positionOfBlockBInVectorB + 1 ; i < vectorB -> size() ; ++ i )
{
Block* blockToBeMoved = *(vectorB -> begin() + i);
std::vector<Block*>* destinationVector = collection[blockToBeMoved -> id];
blockToBeMoved -> where = destinationVector;
destinationVector -> push_back(blockToBeMoved);
}
if (positionOfBlockBInVectorB + 1 > vectorB -> size()) vectorA -> erase(vectorB -> begin() + positionOfBlockBInVectorB + 1, vectorB -> end());
}
if ( command == "move" )
{
//move block a to the pile containing block b
vectorA -> pop_back();
blockA -> where = vectorB;
vectorB -> push_back(blockA);
}
else
{
//move block a and those on top of it to the pile containing block b
std::vector<Block*> temperaryVector;
int positionOfBlockAInVectorA = positionInVector(blockA);
for ( int i = (int)vectorA -> size() - 1 ; i >= positionOfBlockAInVectorA ; -- i )
{
temperaryVector.push_back(vectorA -> at(i));
vectorA -> erase(vectorA -> begin() + i);
}
for ( int i = (int)temperaryVector.size() - 1 ; i >= 0 ; -- i )
{
temperaryVector[i] -> where = vectorB;
vectorB -> push_back(temperaryVector[i]);
}
}
}
for ( k = 0 ; k < blockCount ; ++ k )
{
std::vector<Block*>* vector = collection[k];
std::cout << k << ":";
if ( !vector -> empty() )
{
for ( int i = 0 ; i < vector -> size() ; ++ i )
{
std::cout << " " << vector -> at(i) -> id;
}
}
std::cout << std::endl;
}
delete [] blocks;
delete [] vectors;
}
return 0;
}
int positionInVector(Block* block)
{
std::vector<Block*> vector = *block -> where;
for ( int i = 0 ; i < vector.size() ; ++ i )
{
if ( vector[i] == block ) return i;
}
return -1;
}
Thanks!
For this to work:
A = (int)command[5] - 48;
B = (int)command[12] - 48;
we are need to ensure that string is 5/12 characters long, and that there is a digit in those positions. The code should add checks for the length of input and validity of the digits in those places.
Every time you add or delete a Block to your blockCollection, every pointer you hold to any Block in the collection may be invalidated.
I think that's all I need to say initially...

How to calculate bit transitions using bitset < >

I am new to C++. I want to calculate the no of transitions from 0 to 0, 0 to 1, 1 to 0 and 1 to 1 in a 9 bit sequence. I have written the following code;
int main {
srand((unsigned)time(0));
unsigned int x;
for (int i=0:i<=512;i++) // loop-1
{
x=rand()%512;
bitset<9>bitseq(x);
for(int j=0;j<=bitseq.size();j++) // loop-2
{
bool a= bitseq.test(j);
bool b= bitseq.test(j+1)
if ((a==0)&(b==0)==0)
{
transition0_0 = transition0_0 + 1; // transition from 0 to 0
}
else if ((a==0)&(b==1)==0)
{
transition0_1 = transition0_1 + 1;
else if ((a==1)&(b==0)==0)
{
transition1_0 = transition1_0 + 1;
else
{
transition1_1 = transition1_1 + 1;
cout<<transition0_0<<" "<<transition0_1<<endl;
cout<<transition1_0<<" "<<transition1_1<<endl;
}
}
Somebody please guide me on the following
how to save the last bit value in loop-2 to check the transition from last bit of the last bitset output to the 1st bit of the next bitset output?
If this does not work, How I can save it in vector and use iterators to check the transitions?
First of all, the loop index j is running past the end of the bitset. Indices go from 0 to bitseq.size()-1 (inclusive). If you're going to test j and j+1 the largest value j can take is bitseq.size()-2.
Second, the ==0 part that appears in your ifs is strange, you should just use
if( (a==0)&&(b==0) )
Notice the use of two &&. While a single & works for this code, I think it's better to use the operator that correctly conveys your intentions.
And then to answer your question, you can keep a "last bit" variable that is initially set to a sentinel value (indicating you're seeing the first bitseq just now) and compare it to bitseq[0] before the start of loop 2. Here's a modified version of your code that should do what you ask.
int main {
srand((unsigned)time(0));
unsigned int x;
int transition0_0 = 0,
transition0_1 = 0,
transition1_0 = 0,
transition1_1 = 0;
int prev = -1;
for (int i=0:i<=512;i++) // loop-1
{
x=rand()%512;
bitset<9> bitseq(x);
if( prev != -1 ) // don't check this on the first iteration
{
bool cur = bitseq.test(0);
if( !prev && !cur )
++transition0_0;
else if( !prev && cur )
++transition0_1;
else if( prev && !cur )
++transition1_0;
else
++transition1_1;
}
for(int j=0;j+1<bitseq.size();j++) // loop-2
{
bool a= bitseq.test(j);
bool b= bitseq.test(j+1)
if ((a==0)&&(b==0))
{
transition0_0 = transition0_0 + 1; // transition from 0 to 0
}
else if ((a==0)&&(b==1))
{
transition0_1 = transition0_1 + 1;
}
else if ((a==1)&&(b==0))
{
transition1_0 = transition1_0 + 1;
}
else
{
++transition1_1 = transition1_1 + 1;
}
} // for-2
prev = bitseq.test(bitseq.size()-1); // update prev for the next iteration
cout<<transition0_0<<" "<<transition0_1<<endl;
cout<<transition1_0<<" "<<transition1_1<<endl;
} // for-1
} // main
Would something like this be better for you? Use an array of 4 ints where [0] = 0->0, [1] = 0->1, [2] = 1->0, [3] = 1->1.
int main {
int nTransition[] = { 0,0,0,0 };
bool a,b;
unsigned int x;
int j;
srand ((unsigned)time(0));
for (int i = 0: i < 512; i++) {
x = rand () % 512;
bitset<9> bitseq(x);
if (i == 0) {
a = bitseq.test (0);
j = 1;
} else
j = 0;
for (; j < bitseq.size (); j++) {
b = bitseq.test(j);
int nPos = (a) ? ((b) ? 3 : 2) : ((b) ? 1 : 0);
nTransition[nPos]++;
a = b;
}
}
}

Is these C++ codes optimized for adding 2 positive big integer?

I wrote a program to calculate (adding) 2 positive big integer using vector to store the numbers.
#include <cstdlib>
#include <cstdio> // sd sprintf()
#include <iostream>
#include <vector>// sd vector
typedef short TYPE;// alias
void input();
void makeArray();
void display(const std::vector<TYPE> Ar);
TYPE convertChar2T( char * ch);
void add();
static std::string num1;//store big integer as string
static std::string num2;
static std::vector<TYPE> Arr1;//store as vector
static std::vector<TYPE> Arr2;
static std::vector<TYPE> result;
int main(int argc, char** argv) {
input();
makeArray();
display(Arr1);
display(Arr2);
add();
display(result);
return 0;
}
//input 2 big integer number
void input(){
std::cout << "Enter 1st number : " ;
if (! std::getline(std::cin , num1) )
std::cerr << "Not OK\n";
std::cout << "Enter 2nd number : ";
if (! std::getline(std::cin , num2) )
std::cerr << "Not OK\n";
}
//grab into 2 arrays
void makeArray(){
for (std::size_t i = 0; i < num1.size(); i++){
char temp1[2] = { num1[i], '\0'}; //use array-of-char as it need '\0'
Arr1.push_back( convertChar2T(temp1) ); //push what is converted
}
for (std::size_t i = 0; i < num2.size(); i++){
char temp2[2] = { num2[i], '\0'};
Arr2.push_back( convertChar2T(temp2) );
}
}
//convert char -> TYPE by using sscanf()
TYPE convertChar2T( char * ch){
TYPE numb ;
sscanf( ch, "%d", &numb );//NGUOC LAI SPRINTF
return numb;
}
//display array
void display(const std::vector<TYPE> Ar){
for (std::size_t i = 0; i < Ar.size(); i++)
std::cout << Ar.at(i) << '\t';
std::cout << '\n';
}
void add(){
std::size_t i = Arr1.size(); // NEVER COMES TO ZERO ( 1 AT LEAST )
std::size_t j = Arr2.size();
//check original one and later one
//3 cases : 1 - original one , not yet processed
// 2 - original # one, not yet processed
// -1 - original # one or one, processed
//NOTE: at first only value 1 or 2 ( not process )
short check_one[2] = {
( i == 1 ) ? 1 : 2,
( j == 1 ) ? 1 : 2,
};
bool boost = 0;
bool Arr1_isgood = true;// whether count to 1 or not
bool Arr2_isgood = true;// good -> not yet 1
short temp_result = 0;//temporary result to push into vector
while ( Arr1_isgood || Arr2_isgood ){// while not all comes to 1
// i == j : 2 cases
// 1st: both 1 now - 3 cases
// 1.1 #1+not process original and processed
// 1.2 processed and #1+not processed
// 1.3 both 1 original + not processed
// 2nd: both # 1
if ( i == j ) {
if ( check_one[0] == 2 && check_one[1] == -1 ){//#1+not process original and processed
temp_result = Arr1[i-1] + boost;
check_one[0] == -1;
}
else if ( check_one[0] == -1 && check_one[1] == 2 ){//processed and #1+not processed
temp_result = Arr2[j-1] + boost;
check_one[1] = -1;
}
else//both 1 original + not processed OR both # 1
temp_result = Arr1[i-1] + Arr2[j-1] + boost;
//check result >= 10 or < 10
if ( temp_result >= 10 ){
temp_result = temp_result - 10 ;
boost = 1;
}
else
boost = 0;
//result.begin() return iterator at beginning
result.insert( result.begin() ,temp_result );
//update info
if ( i == j && i == 1){ // NOTE : NEU SD i==j==1 -> sai (vi luon true)
Arr1_isgood = Arr2_isgood = false;
continue;
}
else if ( i == j && i != 1){ // i == j # 1
i--;
j--;
}
}
if (i != j){
//check to set flag ( if one of two die )
if ( i == 1 && j > 1 )
Arr1_isgood = false;
else if ( i > 1 && j == 1 )
Arr2_isgood = false;
// i die && j live OR vice versa
if ( (!Arr1_isgood && Arr2_isgood) ||
(Arr1_isgood && !Arr2_isgood ) ){
if (!Arr1_isgood && Arr2_isgood ){ //1st case
if ( check_one[0] == 1 || check_one[0] == 2){//not yet processed as SET FLAG ABOVE first
temp_result = Arr1[i-1] + Arr2[j-1] + boost;
check_one[0] = -1 ;
}
else
temp_result = Arr2[j-1] + boost;
j--;
}
else if ( Arr1_isgood && !Arr2_isgood ){ //2nd case
if ( check_one[1] == 1 || check_one[1] == 2 ){//not yet processed as SET FLAG ABOVE first
temp_result = Arr1[i-1] + Arr2[j-1] + boost;
check_one[1] = -1 ;
}
else
temp_result = Arr1[i-1] + boost;
i--;
}
}
else {// both is good
temp_result = Arr1[i-1] + Arr2[j-1] + boost;
i--;
j--;
}
//check result >= 10 or < 10
if (temp_result >= 10) {
temp_result -= 10;
boost = 1;
} else
boost = 0;
result.insert( result.begin() ,temp_result );
}
}
//insert boost (if any exists)
if (boost == 1)
result.insert( result.begin(), boost);
}
I'm torn between the use of "Arr1_isgood" bool variable and the check_one variable, it seems that they can be combined into one variable ? I tried to do it and it takes a lot of time without correct result.
Can the digit be store in some kind of smaller data structure rather than "short" type ? as "short" takes more than needed bits.
Another thing is : it seems that std::size_t only reach up to 4 billion in size, as when size_t reach 1, I decreased it several times and it comes to 4 billion ? Isn't it?
I wonder if these codes somehow can be optimized more?
If you want to manipulate big integers, you should use a big-integer library, e.g. GMP.
In your machine has 32-bit ints, suppose you represent each number (unsigned) as an array of 31-bit signed ints, starting from the least significant.
Then maybe you could do something like this:
// do c = a + b
int a[n], b[n], c[n];
int carry = 0;
for (i = 0; i < n; i++){
// do the addition with carry
c[i] = a[i] + b[i] + carry;
// if the addition carried into the sign bit
carry = (c[i] < 0);
// detect it and remove it from the sum
if (carry){
c[i] &= 0x7fffffff;
}
}
Then you could figure out how to handle negatives.