What's making this program slow to process? (C++) - c++

#include <iostream>
#include <vector>
using namespace std;
int main()
{
vector< int > number;
bool numbersAreCorrect = false;
int input;
while( cin >> input )
number.push_back( input );
vector< int > unique_number( number.size(), 0 );
vector< int > repeated( number.size(), 1 );
for( int i = 0; i < number.size(); i++ )
{
for( int j = i + 1; j < number.size() + 1; j++ )
{
if( number[ i ] != 0 && number[ i ] == number[ j ] )
{
repeated[ i ]++;
unique_number[ i ] = number[ i ];
}
else
unique_number[ i ] = number[ i ];
if( j == number.size() )
{
for( int z = 0; z < number.size(); z++ )
{
if( number[ z ] == unique_number[ i ] )
number[ z ] = 0;
}
}
}
}
for( int i = 0; i < number.size(); i++ )
{
if( ( unique_number[ i ] != 0 && repeated[ i ] == 1 ) || ( unique_number[ i ] != 0 && repeated[ i ] % 2 != 0 ) )
{
numbersAreCorrect = false;
cout << unique_number[ i ] << endl;
break;
}
else if( repeated[ i ] == 1 )
numbersAreCorrect = true;
else if( repeated[ i ] % 2 != 0 )
{
numbersAreCorrect = false;
cout << repeated[ i ] << endl;
break;
}
else if( repeated[ i ] % 2 == 0 )
numbersAreCorrect = true;
}
if( numbersAreCorrect == true )
cout << "0" << endl;
return 0;
}
This program gets positive integers from user, checks if an integer is repeated 2k( even) times or 2k+1(odd) times. if latter is true, it prints the integer , else it prints 0; I used 20000 inputs and it takes more than 10 seconds to evaluate.. I need to know how to make it process faster.
for example this input results in "0" : 1 2 2 1
and this results in "3" : 1 2 2 1 3

How about you first sort the thing.
Then you only need to do a single for loop instead of two because to find all the repetitions you just count consecutive occurrences.
Failing that use a set or map. Again you'll drop to O(NlogN) instead of O(N^2).

Related

Wall destroying

There is a wall built from numbers. 0 means there is a hole and blocks can't sit on holes. Someone has a special gun that fires all blocks with a number in one shot.
So I have a matrix called wall and have to write a gun. I wrote the program, but I have a problem and I do not understand why it is happening. In my code
#include <iostream>
#include <cstdio>
using namespace std;
int createWall( int &height, int &length, int wall[][ 100 ], int shots )
{
int i;
int j;
cin >> height;
cin >> length;
cin >> shots;
for ( i = 0; i < height; i++ )
{
for ( j = 0; j < length; j++ )
{
cin >> wall[ i ][ j ];
}
}
return shots;
}
void wallNow( int height, int length, int wall[][ 100 ] )
{
int i;
int j;
for ( i = 0; i < height; i++ )
{
for ( j = 0; j < length; j++ )
{
cout << wall[ i ][ j ] << " ";
}
cout << "\n";
}
}
void destroyWall( int height, int length, int wall[][100], int shots )
{
int i;
int j;
int k;
int x;
int aimedBlocks;//number to be "destroyed"
//set all aimedBlocks to 0
for ( x = 0; x < shots; x++ )
{
cin >> aimedBlocks;
for ( i = 0; i < height; i++ )
{
for ( k = 0; k < length; k++ )
{
if ( wall[ i ][ k ] == aimedBlocks )
{
wall[ i ][ k ] = 0;
}
}
}
}
int counter;//I use this variable because at some point I have a 0 followed only by 0's
for ( i = 0; i < length; i++ )
{
j = height - 1;
counter = 0;
//if I find a 0 then I move all elements higher that it one step down
while ( counter < height )
{
if ( wall[ j ][ i ] == 0 )
{
for ( k = j; k > 0; k-- )
{
wall[ k ][ i ] = wall[ k - 1 ][ i ];
}
wall[ height - j - 1 ][ i ] = 0;
}
else
j--;//I don't always go up ene step because the "block" droped in place of 0 may be 0
counter++;
}
}
}
int main()
{
int height;
int length;
int wall[ 100 ][ 100 ];
int shots = 0;
shots = createWall( height, length, wall, shots );
destroyWall( height, length, wall, shots );
wallNow( height, length, wall );
}
I really do not understand why line wall[ height - j - 1 ][ i ] = 0; is working for the first 4 columns in the following example and it does not work for the last one.
Format input:
height length shots
wall_0_0 ... wall_0_length
... ... ...
wall_height ... wall_height_length
shot_0 ... shot_shots
Input:
4 5 3
3 5 4 5 1
2 1 1 5 3
1 1 5 5 1
5 5 1 4 3
1 5 1
Remove all values that matches with 1, 5, 1. And wall remains must drop into the bottom.
Output:
0 0 0 0 0
0 0 0 0 0
3 0 0 0 0
2 0 4 4 3
Expected:
0 0 0 0 0
0 0 0 0 0
3 0 0 0 3
2 0 4 4 3
Please help me solve this problem. I could not find it debugging the code.
Your algorithm is strange, I don't understand what you try to do.
A simple way to achieve your purpose is to iterate from the left to the right of your wall, then for each you iterate from the bottom to the top. Each time you get a 0, you search for a non zero value to the top and swap their if you found it.
Example (very basic could be improve):
for (size_t i = 0; i < length; i++) { // i is for iterate from left(0) to right(length - 1)
size_t j = height; // j is for iterate from bot(height - 1) to top(0)
while (j-- > 0) {
if (wall[j][i] == 0) {
size_t k = j; // k is for found a non zero value from j - 1 to the top(0)
while (k-- > 0) {
if (wall[k][i] != 0) {
wall[j][i] = wall[k][i];
wall[k][i] = 0;
break;
}
}
}
}
}
Note:
I use size_t because this is the type for index.
I recommend you to switch for std::vector and use iterator on it in C++.

iterator segmentation fault c++

I wrote a simple algorithm to display the nth prime. Simply put, it uses a vector of found primes to check if the next number is prime as well; if it is, it pushes it into the vector and repeats until the nth prime is found.
Unfortunately, I am getting a segmentation fault in the for loop nested in the while loop and I have no idea why. More specifically, the error occurs in the header of the for loop; I added a cerr << "Check " << z++ << endl; to the body of the for loop (and one before it altogether) to see where it occurred so I believe the error is related to the iterators.
The program is very small and I don't mind sharing it (if you have a use for it have at it) so here's the whole thing:
#include <iostream>
#include <iomanip>
#include <cstring>
#include <cmath>
#include <vector>
using std::cout;
using std::cerr;
using std::endl;
using std::vector;
int main( int argc, char* argv[] )
{
if( argc != 2 )
{
cerr << "USAGE: nthPrime n" << endl;
return 1;
}
vector< unsigned > primes;
vector< unsigned >::iterator it;
bool isPrime;
char *sffx = ( char ) 0;
unsigned n = atoi( argv[ 1 ] ),
x = 3,
max;
primes.push_back( 2 );
while( primes.size() != n )
{
isPrime = true;
max = ( unsigned )sqrt( x );
for( it = primes.begin(); *it <= max; ++it )
if( !( x % *it ) ) isPrime = false;
if( isPrime ) primes.push_back( x );
x += 2;
}
if( n == 1 ) strcpy( sffx, "st" );
else if( n == 2 ) strcpy( sffx, "nd" );
else if( n == 3 ) strcpy( sffx, "rd" );
else strcpy( sffx, "th" );
cout << "The " << n << sffx << " prime is " << primes.back() << endl;
return 0;
}
Here's the makefile too for convienience:
CCFLAGS = -Wall -std=c++11
nthPrime: nthPrime.o
g++ $(CCFLAGS) -o nthPrime nthPrime.o
nthPrime.o: nthPrime.cpp
g++ $(CCFLAGS) -c nthPrime.cpp
clean:
-rm *.o nthPrime
I have neglected to add any comments as I just wrote it an hour ago so please let me know if you would like me to.
Thanks in advance.
P.S. I have tried adding && it != primes.end() to the for loop but it shouldn't be required due to the properties of the algorithm and it didn't help anyway.
Some issues I can see:
1) using argv without checking
unsigned n = atoi( argv[ 1 ] ),
x = 3,
max;
2) This:
char *sffx = ( char ) 0;
Does not allocate space for this:
if( n == 1 ) strcpy( sffx, "st" );
else if( n == 2 ) strcpy( sffx, "nd" );
else if( n == 3 ) strcpy( sffx, "rd" );
else strcpy( sffx, "th" );
Ok thank you everyone for getting back to me so quickly! I thought I'd be waiting all day! The issue turned out to be the line char *sffx = ( char ) 0;. Changing it to char *sffx = new char[ 3 ]; fixed everything.
For anyone who may end up having a similar issue or just wants the program for whatever reason, here it is:
#include <iostream>
#include <iomanip>
#include <cstring>
#include <cmath>
#include <vector>
using std::cout;
using std::cerr;
using std::endl;
using std::vector;
int main( int argc, char* argv[] )
{
vector< unsigned > primes;
vector< unsigned >::iterator it;
bool isPrime;
char *sffx = new char[ 3 ];
unsigned n = atoi( argv[ 1 ] ),
x = 3,
max;
if( argc != 2 || n < 1)
{
cerr << "USAGE: nthPrime n>0" << endl;
return 1;
}
primes.push_back( 2 );
while( primes.size() < n )
{
isPrime = true;
max = ( unsigned )sqrt( x );
for( it = primes.begin(); *it <= max; ++it )
if( !( x % *it ) ) isPrime = false;
if( isPrime ) primes.push_back( x );
x += 2;
}
if( n % 10 == 1 && n % 100 != 11 ) strcpy( sffx, "st" );
else if( n % 10 == 2 && n % 100 != 12 ) strcpy( sffx, "nd" );
else if( n % 10 == 3 && n % 100 != 13 ) strcpy( sffx, "rd" );
else strcpy( sffx, "th" );
cout << "The " << n << sffx << " prime is " << primes.back() << endl;
return 0;
}
Enjoy and thank you all again!
P.S. the 86626th prime is a cool one I just ran into randomly to test the program at a high value; check it out!

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.

My C++ program does nothing

I am new to programming and especially C++ so I decided to re-write a java program I wrote to convert a number (for example 13) to words (thirteen), and it worked fine but I tried re-writing it in C++ and after compiling, starting the program, and entering the number it does nothing. I am sorry if thing like my variable's names are unusual.
This is the java program:
public class Say
{
//AAAARRRRRR!!!! Here be Arrrrrrays!
static String first[] =
{
"" , "One " , "Two " , "Three ", "Four ", "Five " , "Six " ,
"Seven " , "Eight " , "Nine " , "Ten " , "Eleven " , "Twelve " ,
"Thirteen " , "Fourteen " , "Fifteen " , "Sixteen " , "Seventeen " ,
"Eighteen " , "Nineteen "
};
static String second[] =
{
"" , "" , "Twenty " , "Thirty " , "Fourty " , "Fifty " ,
"Sixty ", "Seventy " , "Eighty " , "Ninety "
};
static String sections[] =
{
"" , "Hundred " , "Thousand " , "Million " , "Billion "
};
//Number stuff ho!
public static void main( String[] args )
{
String origin = ( args[0] );
int original = Integer.parseInt( origin );
int orlength = origin.length();
int remaindr = ( orlength % 3 );
int legroups;
if ( remaindr != 0 )
{
legroups = ( orlength / 3 + 1 );
}
else
{
legroups = ( orlength / 3 );
}
//Groups AAAARRR here matey!
int groupone = ( original % 1000 );
int grouptwo = ( ( ( original % 1000000 ) - groupone ) / 1000 );
int groupthr = ( ( ( original % 1000000000 ) - grouptwo ) / 1000000 );
//[Pirate themed comment on this being a loop]
boolean finished = false;
int takestep = 0;
while ( finished == false )
{
takestep ++;
int numinact;
if ( takestep == 1 )
{
numinact = groupthr;
}
else if ( takestep == 2 )
{
if ( groupthr != 0 )
{
System.out.print( sections[ 3 ] );
}
numinact = grouptwo;
}
else
{
if ( grouptwo != 0 )
{
System.out.print( sections[ 2 ] );
}
numinact = groupone;
finished = true;
}
if ( numinact > 99 )
{
int hundreds = ( ( numinact - ( numinact % 100 ) ) / 100 );
System.out.print( first [ hundreds ] + sections [ 1 ] );
numinact = ( numinact % 100 );
}
if ( numinact <= 19 )
{
System.out.print( first [ numinact ] );
}
else if ( numinact <= 29 )
{
int digitact = ( numinact - 20 );
System.out.print( second[ 2 ] + first[ digitact ] );
}
else if ( numinact <= 39 )
{
int digitact = ( numinact - 30 );
System.out.print( second[ 3 ] + first[ digitact ] );
}
else if ( numinact <= 49 )
{
int digitact = ( numinact - 40 );
System.out.print( second[ 4 ] + first[ digitact ] );
}
else if ( numinact <= 59 )
{
int digitact = ( numinact - 50 );
System.out.print( second[ 5 ] + first[ digitact ] );
}
else if ( numinact <= 69 )
{
int digitact = ( numinact - 60 );
System.out.print( second[ 6 ] + first[ digitact ] );
}
else if ( numinact <= 79 )
{
int digitact = ( numinact - 70 );
System.out.print( second[ 7 ] + first[ digitact ] );
}
else if ( numinact <= 89 )
{
int digitact = ( numinact - 80 );
System.out.print( second[ 8 ] + first[ digitact ] );
}
else if ( numinact <= 99 )
{
int digitact = ( numinact - 90 );
System.out.print( second[ 9 ] + first[ digitact ] );
}
}
//Yarrr! Debug be what this is!
//System.out.println( " original is " + original + ", orlength is " +
// orlength + ", remaindr is " + remaindr + ", legroups is " +
// legroups + ", groupone is " + groupone + ", grouptwo is " +
// grouptwo + ", groupthr is " + groupthr );
}
}
And this is the C++ re-write that does not work:
//C++ port of the Say.java program.
//I hope to extend to longer numbers in the future.
#include <iostream>
#include <string>
using namespace std;
static string digit [20] =
{
"" , "One " , "Two " , "Three ", "Four ", "Five " , "Six " , "Seven " ,
"Eight " , "Nine " , "Ten " , "Eleven " , "Twelve " , "Thirteen " ,
"Fourteen " , "Fifteen " , "Sixteen " , "Seventeen " , "Eighteen " ,
"Nineteen "
};
int main()
{
int original; //declare int
cout << "Enter your number: "; //Requests user input
cin >> original; //Recieves user input assigns value to previous variable
//Groups of 3 digits
int groupone = ( original % 1000 );
int grouptwo = ( ( original / 1000 ) % 1000);
int groupthr = ( original / 1000000 );
//Intense loop, almost direct from java version.
bool finished = false;
int takestep = 0;
while ( finished != true );
{
takestep ++;
int numinact;
if ( takestep == 1 )
{
numinact = groupthr;
}
else if ( takestep == 2 )
{
if ( groupthr != 0 )
{
cout << "Million ";
}
numinact = grouptwo;
}
else
{
if ( grouptwo != 0 )
{
cout << "Thousand ";
}
numinact = groupone;
finished = true;
}
if ( numinact > 99 )
{
int hundreds = ( ( numinact - (numinact % 100 ) ) / 100 );
cout << digit[ hundreds ] << "Hundred ";
numinact = ( numinact % 100 );
}
if ( numinact <= 19 )
{
cout << digit[ numinact ];
}
else if ( numinact <= 29 )
{
int digitact = ( numinact - 20 );
cout << "twenty " << digit[ digitact ];
}
else if ( numinact <= 39 )
{
int digitact = ( numinact - 30 );
cout << "thirty " << digit[ digitact ];
}
else if ( numinact <= 49 )
{
int digitact = ( numinact - 40 );
cout << "fourty " << digit[ digitact ];
}
else if ( numinact <= 59 )
{
int digitact = ( numinact - 50 );
cout << "fifty " << digit[ digitact ];
}
else if ( numinact <= 69 )
{
int digitact = ( numinact - 60 );
cout << "sixty " << digit[ digitact ];
}
else if ( numinact <= 79 )
{
int digitact = ( numinact - 70 );
cout << "seventy " << digit[ digitact ];
}
else if ( numinact <= 89 )
{
int digitact = ( numinact - 80 );
cout << "eighty " << digit[ digitact ];
}
else if ( numinact <= 99 )
{
int digitact = ( numinact - 90 );
cout << "ninety " << digit[ digitact ];
}
}
return 0;
}
What must I change to get it to run like the java program?
This does not do what you think it does:
bool finished = false;
while ( finished != true );
{
// blah blah blah
finished = true;
}
The semicolon at the end of that while line makes it an infinite loop followed by a block which you never reach (because of that infinite loop).
Remove the semicolon and you will get:
pax$ ./testprog
Enter your number: 1234
One Thousand Two Hundred thirty Four

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.