print binary tree: incorrect leaves and spaces output - c++

I have a problem with the output of a binary tree. The code that I have designed for the print of a tree, in which the elements have a length of 1 character, and in my tree elements are words (at most 10 characters). Tell me pls what should I change in the code to the correct output of tree.
My code:
int maxHeight(Node *p) {
if (!p) return 0;
int leftHeight = maxHeight(p->left);
int rightHeight = maxHeight(p->right);
return (leftHeight > rightHeight) ? leftHeight + 1 : rightHeight + 1;
}
void printBranches(int branchLen, int nodeSpaceLen, int startLen, int nodesInThisLevel, const deque<Node*>& nodesQueue) {
deque<Node*>::const_iterator iter = nodesQueue.begin();
for (int i = 0; i < nodesInThisLevel / 2; i++) {
cout << ((i == 0) ? setw(startLen - 1) : setw(nodeSpaceLen - 2)) << "" << ((*iter++) ? "/" : " ");
cout << setw(2 * branchLen + 2) << "" << ((*iter++) ? "\\" : " ");
}
cout << endl;
}
void printNodes(int branchLen, int nodeSpaceLen, int startLen, int nodesInThisLevel, const deque<Node*>& nodesQueue) {
deque<Node*>::const_iterator iter = nodesQueue.begin();
for (int i = 0; i < nodesInThisLevel; i++, iter++) {
cout << ((i == 0) ? setw(startLen) : setw(nodeSpaceLen)) << "" << ((*iter && (*iter)->left) ? setfill('_') : setfill(' '));
cout << setw(branchLen + 2);
if (*iter)
cout << (*iter)->data << "(" << (*iter)->frequency << ")";
else
cout << "";
cout << ((*iter && (*iter)->right) ? setfill('_') : setfill(' ')) << setw(branchLen) << "" << setfill(' ');
}
cout << endl;
}
void printLeaves(int indentSpace, int level, int nodesInThisLevel, const deque<Node*>& nodesQueue) {
deque<Node*>::const_iterator iter = nodesQueue.begin();
for (int i = 0; i < nodesInThisLevel; i++, iter++) {
cout << ((i == 0) ? setw(indentSpace + 2) : setw(2 * level + 2));
if (*iter)
cout << (*iter)->data << "(" << (*iter)->frequency << ")";
else
cout << "";
}
cout << endl;
}
void printPretty(Node *root, int level, int indentSpace) {
int h = maxHeight(root);
int nodesInThisLevel = 1;
int branchLen = 2 * ((int)pow(2.0, h) - 1) - (3 - level)*(int)pow(2.0, h - 1);
int nodeSpaceLen = 2 + (level + 1)*(int)pow(2.0, h);
int startLen = branchLen + (3 - level) + indentSpace;
deque<Node*> nodesQueue;
nodesQueue.push_back(root);
for (int r = 1; r < h; r++) {
printBranches(branchLen, nodeSpaceLen, startLen, nodesInThisLevel, nodesQueue);
branchLen = branchLen / 2 - 1;
nodeSpaceLen = nodeSpaceLen / 2 + 1;
startLen = branchLen + (3 - level) + indentSpace;
printNodes(branchLen, nodeSpaceLen, startLen, nodesInThisLevel, nodesQueue);
for (int i = 0; i < nodesInThisLevel; i++) {
Node *currNode = nodesQueue.front();
nodesQueue.pop_front();
if (currNode) {
nodesQueue.push_back(currNode->left);
nodesQueue.push_back(currNode->right);
}
else {
nodesQueue.push_back(NULL);
nodesQueue.push_back(NULL);
}
}
nodesInThisLevel *= 2;
}
printBranches(branchLen, nodeSpaceLen, startLen, nodesInThisLevel, nodesQueue);
printLeaves(indentSpace, level, nodesInThisLevel, nodesQueue);
}
as you can see, chars "\" and leaves are shifted by 3 positions to the left
http://i.stack.imgur.com/ADdGZ.png

Related

Program containing threading in cpp is not executed completely

Code given below is not executed completely;
I have looked for everything on web but I don't know why it is working for starting numbers from nums (i.e. 1000 and sometimes 5000) and after that it starts execution but in between program terminates itself and stopes working.
#include <bits/stdc++.h>
// #include <iostream>
// #include <chrono>
// #include <vector>
#define UPPER_LIMIT 10
using namespace std;
using namespace std::chrono;
bool inTimeLimit = true;
bool isFinished = false;
bool isRunning = true;
class Timer {
public:
time_point<high_resolution_clock> start, end;
Timer() {
start = high_resolution_clock::now();
}
~Timer() {
end = high_resolution_clock::now();
auto durationTime = durationCounter();
cout << "\n\nTaken time Duration " << (unsigned long long)durationTime << " us; " << (unsigned long long)durationTime * 0.001 << "ms.";
}
float durationCounter() {
auto currTime = high_resolution_clock::now();
auto durationTime = duration_cast<microseconds>(currTime - start);
return durationTime.count();
}
};
void printVector(vector <int> v) {
cout << endl;
for (int x : v) {
cout << setw(3) << x << " ";
}
}
void printVectorToFile(ofstream &fout , vector <int> v, string msg) {
fout << "\n\n===================\n\n";
fout << msg << endl;
fout << endl;
for (int x : v) {
fout << setw(5) << x << " ";
}
fout << endl;
}
void swap (int *a, int *b) {
int temp = *a;
*a = *b;
*b = temp;
}
vector <int> randomArrayGenerator(int n) {
vector<int> v(n);
for (int i = 0; i < n; ++i)
v[i] = i + 1;
srand(time(0));
for (int i = 0; i < n; ++i)
{
int pos = rand() % n;
swap(&v[i], &v[pos]);
}
return v;
}
string sortingChecker(vector<int> v) {
for (int i = 0; i < (int)v.size() - 1; ++i)
{
if (v[i] > v[i + 1]) return "false";
}
return "true";
}
bool sortChecker(vector<int> v) {
for (int i = 0; i < (int)v.size() - 1; ++i)
{
if (v[i] > v[i + 1]) return false;
}
return true;
}
// Merge function
void merge(vector <int> &v, int begin, int middle, int end) {
vector <int> left, right;
for (int i = begin; i < middle + 1; ++i)
{
left.push_back(v[i]);
}
for (int i = middle + 1; i <= end; ++i)
{
right.push_back(v[i]);
}
int p1 = 0, p2 = 0, n1 = left.size(), n2 = right.size(), p = begin;
while ((p1 < n1 ) || (p2 < n2)) {
if ((p1 != n1 ) && ((p2 == n2) || left[p1] < right[p2]))
v[p++] = left[p1++];
else
v[p++] = right[p2++];
}
}
void mergeSortByIteration(vector <int> &v, bool &isTimeDelayed) {
int low = 0, high = v.size();
cout << "Thread ID: " << this_thread::get_id() << endl;
// n :for taking individual block of vector containing number of elements n=[1,2,4,8,..]
for (int n = 1; n < high; n *= 2) {
if (isTimeDelayed) return;
// taking block according to n and then sorting them by merge function
// n=1 => i=0,2,4,8,16
// n=2 => i=0,4,8
for (int i = 0; i < high; i += 2 * n) {
if (isTimeDelayed) return;
int begin = i;
int mid = i + n - 1;
int end = min(i + 2 * n - 1 , high - 1);
merge(v, begin, mid, end);
}
}
}
// Merge by recurision
void mergeSortByRecursion (vector <int> &v, int begin, int end, bool &isTimeDelayed) {
if (end <= begin || isTimeDelayed) return;
int middle = begin + (end - begin) / 2;
mergeSortByRecursion(v, begin, middle, isTimeDelayed);
mergeSortByRecursion(v, middle + 1, end, isTimeDelayed);
merge(v, begin, middle, end);
}
int main() {
int nums[] = {1000, 5000, 10000, 50000, 100000};
// int nums[] = {50000};
ofstream vectorOutput ;
vectorOutput.open("outputTexts\\prac1_resultedArrays.txt", ios::trunc);;
for (int n : nums)
// ``````` Merge by Iteration ````````
{
vector<int> num, arr = randomArrayGenerator(n);
cout << "\n=======";
cout << "\n\nMerge by Iteration:" << endl;
num = arr;
cout << "Array size: " << num.size() << endl;
bool isTimeOut = false, isSorted = false;
Timer timer;
std::thread worker(mergeSortByIteration, ref(num), ref(isTimeOut));
// mergeSortByIteration(num, isTimeOut);
// std::thread worker(mergeSortByRecursion, ref(num), 0, n - 1, ref(isTimeOut));
while ( ( ( timer.durationCounter() / 1000000 ) < 5) && (!isSorted ) ) {
// this_thread::sleep_for(seconds(1));
// cout << timer.durationCounter() << " ";
isSorted = sortChecker(num);
}
if ( ( ( ( timer.durationCounter() / 1000000 ) > 5) && (!isSorted ) ) )
{
isTimeOut = true;
cout << endl << "!!!!!Execution Terminated ---- Time Limit reached!!!!!!" << endl;
}
if (worker.joinable())
worker.join();
printVector(num);
cout << "\nCheck result for sorted Vector:" << (isSorted ? "true" : "false") << endl;
// printVectorToFile(vectorOutput, num, "Merge By Iteration for size:" + to_string(n) );
}
cout << "\n\ndone" << endl;
return 0;
}
can anyone help me out here?
If issue is not clear fill free to ask.

C++ full subtractor using hexadecimals

I have input such as:
10000000000000-1=
and
AAAAABBBBBCCCCCDDDDDEEEEEFFFFF-ABCDEF0123456789ABCDEF=
I need to convert the hexadecimal strings digit by digit into decimal and keep track if I need to borrow. I'm not sure how to adjust the value of operand 1 when a borrow occurs. Such as in the first line when you have to borrow 13 times.
Currently, I have
#include <iostream>
#include <fstream>
using namespace std;
string decimalToHex(int);
void subtraction(string, string)
int hexadecimalToDecimal(char hexVal);
int fullSubtractor(int tempOp1, int tempOp2)
int main()
{
ifstream myFile;
string l1, l2, l3, l4, l5, l6, l7, l8; //lines
string l1op1, l1op2, l2op1, l2op2, l3op1, l3op2, l4op1, l4op2, l5op1, l5op2, l6op1, l6op2, l7op1, l7op2, l8op1, l8op2; //parsed operators
myFile.open("data.txt");
if (myFile.is_open()) //check if file opened
{
cout << "File opened successfully. " << endl;
}
else
{
cerr << "File failed to open." << endl;
return 1;
}
while (!myFile.eof())
{
myFile >> l6 >> l7; //read in line by line
}
l6op1 = l6.substr(0, l6.find("-"));
l6op2 = l6.substr(l6.find("-") + 1);
l6op2 = l6op2.substr(0, l6op2.length() - 1);
std::string l6op2_zeros = std::string((l6op1.length()) - l6op2.length(), '0') + l6op2;
cout << l6; // << subtraction(l6op1, l6op2_zeros) << endl;
subtraction(l6op1, l6op2_zeros);
cout << endl;
l7op1 = l7.substr(0, l7.find("-"));
l7op2 = l7.substr(l7.find("-") + 1);
l7op2 = l7op2.substr(0, l7op2.length() - 1);
std::string l7op2_zeros = std::string((l7op1.length()) - l7op2.length(), '0') + l7op2; //appends zeros to front of second operand to make it same length as operand 1
cout << l7; // << subtraction(l7op1, l7op2) << endl;
subtraction(l7op1, l7op2_zeros);
cout << endl;
myFile.close();
return 0;
}
int fullSubtractor(int tempOp1, int tempOp2)
{
static int borrow;
int result = 0;
if ((tempOp1 < tempOp2) || ((tempOp1 == 0) && (borrow == 1)))
{
tempOp1 += 16;
result = tempOp1 - borrow - tempOp2;
borrow = 1;
}
else
{
result = tempOp1 - tempOp2;
borrow = 0;
}
return result;
}
void subtraction(string op1, string op2)
{
string result;
int tempDifference = 0, tempHex = 0;
int j = op2.length() - 1;
for (int i = op1.length() - 1; i >= 0; i--)
{
int temp1 = hexadecimalToDecimal(op1[i]);
int temp2 = hexadecimalToDecimal(op2[j]);
tempHex = fullSubtractor(temp1, temp2);
result = decimalToHex(tempHex) + result;
cout << result << " ";
j--;
}
cout << result << endl;
//return result;
}
int hexadecimalToDecimal(char hexVal)
{
int base = 1;
int dec_val = 0;
if (hexVal >= '0' && hexVal <= '9')
{
dec_val += (hexVal - 48) * base;
base *= 16;
}
else if (hexVal >= 'A' && hexVal <= 'F')
{
dec_val += (hexVal - 55) * base;
// incrementing base by power
base *= 16;
}
return dec_val;
}
string decimalToHex(int decNum)
{
stringstream ss;
ss << hex << decNum;
string hexNum(ss.str());
//cout << hexNum << endl;
return hexNum;
}

Recurrence in Math

Sorry this is my first time use stackoverflow.
I dont kow where is the mistake in my code.
Output that i want:
-1+3-5+7-9+11-13+15
RESULT : 8
But Output that is shown
-1+3-5+7-9+11-13+15
RESULT : 10
#include <iostream>
#include <math.h>
using namespace std;
int main()
{
int i, S, x, sign;
S = 0;
for (i = 1; i <= 8; i++) {
if ((pow(-1, i - 1) == 1) && (i > 1)) {
sign = -1;
}
if ((pow(-1, i - 1) != 1) && (i > 1)) {
sign = 1;
cout << "+";
}
if (i == 1) {
sign = 1;
cout << "-";
}
x = sign * (2 * i - 1);
cout << x;
S = S + x;
}
cout << "\n Result:" << S;
}
problem is in the if condition block where you check i==1
in that loop you are making sign=1 that should be sign=-1
How about improving the logic like following?
#include <iostream>
using namespace std;
int main()
{
int i;
bool sign = true; // signed/minus = true, non-signed/plus = false
int ans = 0;
for( i=1; i<=15; i=i+2){
if( sign == true){
cout << "-" << i;
ans = ans - i;
}
else {
cout << "+" << i;
ans = ans + i;
}
sign = !sign;
}
cout << endl << "RESULT : " << ans << endl;
return 0;
}
Try this code
#include <iostream>
#include <math.h>
using namespace std;
int main()
{
int i, S, x, sign;
S = 0;
for (i = 1; i <= 8; i++) {
if ((pow(-1, i - 1) == 1) && (i > 1)) {
sign = -1;
}
else
if ((pow(-1, i - 1) != 1) && (i > 1)) {
sign = 1;
// cout << "+";
}
//else
if (i == 1) {
sign = -1;
//cout << "-";
}
x = sign * (2 * i - 1);
cout <<"\n"<<x;
S = S + x;
//cout<<"S is \n"<<S;
}
cout << "\n Result:" << S;
}
You have put wrong sign when i==1
The problem is that you're starting the calculation with a positive sign (but you're lying to yourself by printing "-").
You can simplify the code and don't need to mess around with pow if you make the obervation that
pow(-1, k) == -1 * pow(-1, k-1)
Starting at pow(-1,0) (that is, 1), you can write:
int main(int argc, char* argv[])
{
int sign = 1; // sign will always hold pow(-1, i).
int sum = 0;
for (int i = 1; i <= 8; i++)
{
sign *= -1;
if (sign > 0) // Since sign starts at -1, we know that i > 1 here
{
std::cout << "+";
}
int term = sign * (2 * i - 1);
std::cout << term;
sum += term;
}
std::cout << " = " << sum << std::endl;
}

Why is there a Segmentation Fault from this vector code?

When I execute this code in Code::Blocks I get a segmentation fault. Why? I've used debug and haven't found why. Any help is useful.
The debugger showed it was from the vector push_back method, but specifically on the "this" pointer used in the copy constructor.
#include <iostream>
#include <vector>
#include <cstdlib>
#include <ctime>
#include <cmath>
const int MAX_COL = 7, MAX_ROW = 6;
const int NOPLAYER = 0, PLAYER1 = 1, PLAYER2 = 2;
const int NOTHING = 123;
int movesBeingStored = 0;
int movesCreated = 0;
class Move{
public:
Move() : row(-1), col(-1), plr(-1) {
//std::cout << "Placed #" << col << "," << row << std::endl;
++movesBeingStored;
++movesCreated;
std::cout << "+Now " << movesBeingStored << " move(s), Created " << movesCreated << std::endl;
};
Move(int r, int c, int p) : row(r), col(c), plr(p) {
++movesBeingStored;
++movesCreated;
std::cout << "+Now " << movesBeingStored << " move(s), Created " << movesCreated << std::endl;
};
~Move() {
--movesBeingStored;
std::cout << "-Now " << movesBeingStored << " move(s)" << std::endl;
};
int getRow() const { return row; }
int getCol() const { return col; }
int getPlayer() const { return plr; }
Move(const Move* other) {
++movesBeingStored;
++movesCreated;
std::cout << "+Now " << movesBeingStored << " move(s), Created " << movesCreated << std::endl;
col = other->getCol();
row = other->getRow();
plr = other->getPlayer();
}
Move(const Move& other) {
++movesBeingStored;
++movesCreated;
std::cout << "+Now " << movesBeingStored << " move(s), Created " << movesCreated << std::endl;
col = other.getCol(); //This line causes a segment fault
row = other.getRow();
plr = other.getPlayer();
}
bool operator== (const Move& other) const {
return (&other == this);
}
private:
int row, col, plr;
};
int board[MAX_COL * MAX_ROW];
std::vector<Move> moves;
bool isFull[MAX_COL];
int tops[MAX_COL];
int currentPlayer = PLAYER1;
int checkedCollumns = 0;
void randomize( void ) { srand(time(NULL)); }
void startBoard( void );
void placeMove(int col, int player);
void popMove();
int checkwin(int curPlayer);
int checkMove(int depth, int& bestCol, int curP, int checkP);
int randomInt(int min, int max);
void printMoves( void );
int main()
{
startBoard();
randomize();
int col = -1;
int pts = checkMove(2, col, PLAYER1, PLAYER1);
if(col == -1) {
std::cout << "No best move" << std::endl;
} else {
std::cout << "Best move: Col " << col << std::endl;
if(pts == NOTHING) {
std::cout << "Nothing happens" << std::endl;
} else {
std::cout << "Gives " << pts << " points" << std::endl;
}
}
}
void startBoard( void ) {
for(int i = 0; i < MAX_COL; ++i) {
isFull[i] = false;
tops[i] = 0;
}
for(int p = 0; p < MAX_COL * MAX_ROW; ++p) {
board[p] = NOPLAYER;
}
}
void placeMove(int col, int player) {
if(col < 0 || col >= MAX_COL)
return;
if(isFull[col])
return;
if(player != PLAYER1 && player != PLAYER2)
player = PLAYER1;
moves.push_back(Move(col, tops[col], player));
board[col + tops[col] * MAX_COL] = player;
++tops[col];
isFull[col] = (tops[col] == MAX_ROW);
}
void popMove() {
if(moves.empty())
return;
Move move = moves.back();
moves.pop_back();
int col = move.getCol(), row = move.getRow();
board[col + row * MAX_COL] = NOPLAYER;
tops[col] = row;
isFull[col] = (tops[col] == MAX_ROW);
}
int checkwin(int curPlayer) {
if(randomInt(0,5) != 1)
return NOTHING;
return randomInt(0,4);
}
int checkMove(int depth, int& bestCol, int curP, int checkP) {
int pts = NOTHING, col = -1, p = NOTHING, c = -1;
if(depth <= 0) {
if(moves.empty()) {
bestCol = -1;
return NOTHING;
}
Move move = moves.back();
bestCol = move.getCol();
pts = checkwin((move.getPlayer());
if(move.getPlayer() != checkP && pts != NOTHING)
pts = -pts;
return pts;
}
for(int i = 0; i < MAX_COL; ++i) {
std::cout << "C: " << checkedCollumns;
std::cout << "\tD: " << depth;
std::cout << "\tM: " << moves.size();
std::cout << std::endl;
if(isFull[i])
continue;
++checkedCollumns;
placeMove(i, curP);
p = checkMove(depth - 1, c, ((curP == PLAYER1)?PLAYER2:PLAYER1), checkP);
popMove();
if(p != NOTHING && checkP != curP)
p = -p;
if(col == -1) {
col = i;
pts = p;
continue;
}
if(pts == NOTHING && p != NOTHING && p >= 0) {
col = i;
pts = p;
continue;
}
if(pts != NOTHING && p != NOTHING && p > pts) {
col = i;
pts = p;
}
}
bestCol = col;
return pts;
}
int randomInt(int min, int max) {
double per = (double)(rand() % RAND_MAX) / RAND_MAX;
return min + (max - min) * per;
}
void printMoves( void ) {
std::cout << "M:";
if(moves.empty()) {
std::cout << " --\t" << moves.size();
return;
}
Move m;
for(unsigned int i = 0; i < moves.size(); ++i) {
m = moves.at(i);
std::cout << " {" << m.getCol() << "," << m.getRow() << "}";
}
std::cout << "\t" << moves.size();
}
A very trivial error, manifesting in a very obscure way. The segment fault is caused by the vector trying to construct an object at an invalid location. Why? Because of the following line in void popMove():
board[col + row * MAX_COL] = NOPLAYER;
This line has a buffer overflow caused by invalid coordinates (0, 6), which overwrites the internal memory pointer in moves. That's the problem, the solution is up to you.

Debugging a merge sort

void CensusData::mergeSort(int type) {
if(type == 0)
MERGE_SORT(type, 0, data.size());
}
void CensusData::MERGE_SORT(int type, int p, int r){
//int q;
//cout << "data size " << data.size() << endl;
std::cout << "MERGE_SORT START ///("<< p << ", " << r << ")" <<std::endl;
if(p < r)
{
int q = (p + r)/2;
MERGE_SORT(type, p, q);
MERGE_SORT(type, q + 1, r);
MERGE(type, p, q ,r);
}
}
void CensusData::MERGE(int type, int p, int q, int r){
if(type == 0)
{
std::cout << "MERGING" << std::endl;
//int n1;
//int n2;
int n1 = q - p + 1;
int n2 = r - q;
int L[n1 + 1];
int R[n2 + 1];
for(int i = 1; i < n1; i++)
{
cout << "filling Left Array" << endl;
L[i] = data[p + i - 1]->population;
}
for(int j = 1; j < n2; j++)
{
cout << "filling Right Array" << endl;
R[j] = data[q + j]->population;
}
int i = 1;
int j = 1;
for(int k = p; p < r; p++)
{
cout << "for loop: " << endl;
if(L[i] <= R[j])
{
cout << "TRUE" << endl;
data[k]->population = L[j];
i = i + 1;
}
/*else if(data[k]->population == R[j])
{
cout << "FALSE" << endl;
j = j + 1;
}*/
else
{
data[k]->population = R[j];
j = j + 1;
}
}
}
}
do not worry about type, it wont effect this program at all. basically i am trying to make a merge sort that will take a vector containing an integer, the vector looks like this:
class Record { // declaration of a Record
public:
std::string* city;
std::string* state;
int population;
Record(std::string&, std::string&, int);
~Record();
};
std::vector<Record*> data;
basically i have been trying to get it to actually sort, but it doesn't seem to work at all, i have even seen garbage in the program.
example input:
237 812826 68642
output:
4484540 812826 68642
Note: all of the rest of the program works fine (tested it with an insertion sort) only this part is not working.
Take a look at lecture 15 of the excellent Stanford Universities course Programming Abstractions. It covers all kinds of sorts including merge:
http://see.stanford.edu/see/lecturelist.aspx?coll=11f4f422-5670-4b4c-889c-008262e09e4e
You can even get the source code from SourceForge:
http://sourceforge.net/projects/progabstrlib/files/