thanks for visiting my question! Currently, when I run this code (an implementation of the Set data structure in c++), the memory address of each element in the set is printed instead of the values in the set. To help with debugging, here's my code:
#include <iostream>
#include <algorithm>
#include <string>
#include <vector>
#include <cassert>
#define PB push_back
typedef std::vector<int> vint;
class SetBase
{
public:
SetBase() {}
~SetBase() {}
void insert(int x)
{
if (!this->isInSet(x))
{
this->set.PB(x);
}
}
int size()
{
return this->set.size();
}
bool empty()
{
return this->size() == 0;
}
int operator[](int index)
{
if (index >= 0 && index < this->size())
{
return this->set[index];
}
else
{
return -1;
}
}
bool find(int target)
{
sort(this->set.begin(), this->set.end());
int low = 0, high = this->size();
while (low <= high)
{
long long mid = low + (high - low) / 2;
long long guess = this->set[mid];
if (guess == target)
return true;
else if (guess < target)
low = mid + 1;
else
high = mid - 1;
}
return false;
}
int count(int target)
{
int counter = 0;
for (int i = 0; i < this->set.size(); i++)
{
if (this->set[i] == target)
counter++;
}
return counter;
}
bool operator=(SetBase &other)
{
if (other.size() != this->size())
return false;
for (int i = 0; i < other.size(); i++)
{
if (other[i] != this->set[i])
return false;
}
return true;
}
private:
vint set;
bool isInSet(int target)
{
for (int i = 0; i < this->size(); i++)
{
if (set[i] == target)
{
return true;
}
}
return false;
}
};
class Set : public SetBase
{
public:
void set_union(Set *set1, Set *set2, Set &back_insertor)
{
for (int i = 0; i < set1->size(); i++)
{
if (this->isInSet(back_insertor, i))
{
back_insertor.insert(i);
}
}
}
void set_difference(Set set1, Set set2, Set &back_insertor)
{
// set_difference = set1 - set2
}
void set_intersection(Set set1, Set set2, Set &back_insertor)
{
// set_difference = set1 U set2
for (int i = 0; i < set1.size(); i++)
{
for (int j = 0; j < set2.size(); j++)
{
if (set1[i] == set2[j])
{
back_insertor.insert(set1[i]);
}
}
}
}
void printSet(Set *in)
{
for (int i = 0; i < in->size(); i++)
{
std::cout << &in[i] << "\n";
}
}
private:
bool isInSet(SetBase set1, int target)
{
for (int i = 0; i < set1.size(); i++)
{
if (target == set1[i])
{
return true;
}
}
return false;
}
};
int main()
{
Set *set_1 = new Set();
Set *set_2 = new Set();
Set *back = new Set();
for (int i = 1; i <= 10; i++)
set_1->insert(i);
for (int i = 1; i <= 10; i++)
set_2->insert(i);
set_2->insert(11);
set_1->set_union(set_1, set_2, *back);
set_1->printSet(set_1);
delete set_1;
delete set_2;
delete back;
}
When running the set_1->printSet(set_1); line, here's what I get:
0x7fb498c05a20
0x7fb498c05a38
0x7fb498c05a50
0x7fb498c05a68
0x7fb498c05a80
0x7fb498c05a98
0x7fb498c05ab0
0x7fb498c05ac8
0x7fb498c05ae0
0x7fb498c05af8
Even though this works, I would like to print out the values (integer) instead. Any help would be appreciated! Thanks! :)
Inside printSet(), you use &in[i] to print each element.
The & operator returns the address of the object you are referencing. So, instead of getting the value, you are getting its address. You should remove it, eg:
void printSet(Set *in)
{
for (int i = 0; i < in->size(); i++)
{
std::cout << (*in)[i] << "\n";
}
}
Related
I want to find the largest palindrome in an integer array. I tried making my own algorithm and not looking at the online ones. But this is not working. I tried doing debugging but couldn't get it to work.
Sample input:
"1367611342142412431113424823782"
Output: 113421424124311
void palindrome()
{
int max = 0;
int len;
int start;
int end;
int st=0,en=0;
bool palin = false;
for(int i=0;i<size;i++)
{
for(int j=size-1; j>=0;j--)
{
if(array[i] == array[j])
{
start = i;
end = j;
while(j==i+1 || j+1 == i || j == i )
{
if(array[i] == array[j])
{
i++;
j--;
palin = true;
}
else
{
palin = false;
break;
}
}
i= start;
j= end;
}
if(palin == true)
{
len = end - start;
if(len>max)
{
cout<<" "<<st<<" "<<en<<endl;
st=i;
en =j;
max = len;
}
}
}
}
cout<<endl;
cout<<st<<" "<<en<<endl;
ofstream file("output.txt");
for(int i=st;i<=en;i++)
{
file<<array[i];
}
}
There is solution
#include <iostream>
#include <string>
struct Result
{
int fromIndex, toIndex;
Result(int fromIndex, int toIndex){
this->fromIndex = fromIndex;
this->toIndex = toIndex;
}
int length(){
return toIndex - fromIndex;
}
};
bool isPalindrome(std::string &s, int left, int right){
while(left <= right){
if(s[left] != s[right]){
return false;
}
left ++;
right --;
}
return true;
}
std::string solve(std::string &s){
int startIndex = 0;
int toIndex = s.size() - 1;
Result result(0,0);
while(true){
if(isPalindrome(s, startIndex, toIndex)){
if(result.length() < (toIndex - startIndex)){
result.fromIndex = startIndex;
result.toIndex = toIndex;
}
}
toIndex --;
if(toIndex <= startIndex){
toIndex = s.size() - 1;
startIndex++;
}
if(startIndex == s.size() - 1){
break;
}
}
std::string str = "";
for (int i = result.fromIndex; i <= result.toIndex; ++i)
{
str += s[i];
}
return str;
}
int main()
{
std::string s = "1367611342142412431113424823782";
std::string result = solve(s);
std::cout << "Longest palindrome is: "<< result;
return 0;
}
You need to think in more structural way. Split your task in to sub-tasks first. In this case there are to sub-tasks:
1. go over all possible combinations
2. check if this combination is a palindrome.
Each task is another function - this way it is easier to think, read code and debug.
(In case you want to write it to file - it is a third task!)
Here is the code for the "go over all possible combinations". I guess you will find yourself how to check a single array if it is a palindrome.
#include <iostream>
using namespace std;
bool isPalindrome(int* arr, int size);
bool findLargestPalindrome(int* arr, int size);
int main()
{
int arr[] = { 1,3,6,7,6,1,1,3,4,2,1,4,2,4,1,2,4,3,1,1,1,3,4,2,4,8,2,3,7,8,2 };
int arrSize = 31;
findLargestPalindrome(arr, arrSize);
}
bool findLargestPalindrome(int* arr, int size)
{
for (int testSize = size; testSize > 0; testSize--)
{
int startIndex = 0;
while (testSize + startIndex <= size)
{
int* arrayToTest = &(arr[startIndex]);
if (isPalindrome(arr, testSize))
{
//TODO: you found it - do with it whatever you want
return true;
}
startIndex++;
}
}
return false;
}
bool isPalindrome(int* arr, int size)
{
//TODO: your code for single palindrome
return false;
}
I'm working on a coding assignment for a C++ class. When I run my program I seem to be dealing with a memory leakage issue, which is weird since I am NOT explicitly allocating any memory in my code. I ran the program under gdb, and it seems as though the program crashes when running the destructor for a Deck object. I tried stepping through the code, but I when I do so I end up in a host of .h files related to vectors. Then suddenly, it stops. I tried going to a TA for some help, but they seem to be as perplexed as I am on the issue.
# include <stdlib.h>
# include <time.h>
# include <iostream>
# include <vector>
# include <stdio.h>
using namespace std;
//function signatures
float bustProbability (const int);
class Deck
{
public:
//data members
vector <int> cardArray;
vector <int> wasteCards;
//constructor
Deck();
//methods
void shuffleDeck();
void populateDeckWithCards();
void removeCopyCards();
int dealCard();
int remainingCards();
void showCards();
};
void Deck::removeCopyCards() {
for (unsigned int i = 0; i < wasteCards.size(); i++) {
bool removedCopy = false;
for (unsigned int j = 0; j < cardArray.size() && removedCopy == false; j++) {
if (cardArray[j] == wasteCards[i]) {
cardArray.erase (cardArray.begin() + j - 1);
removedCopy = true;
}
}
}
}
int Deck::dealCard() {
if (remainingCards() > 0) {
int tmp = cardArray.back();
wasteCards.push_back(tmp);
cardArray.pop_back();
return tmp;
}
else {
populateDeckWithCards();
removeCopyCards();
shuffleDeck();
//shuffle method
int tmp = cardArray.back();
cardArray.pop_back();
return tmp;
}
}
void Deck::populateDeckWithCards() {
//populate regular cards into array
for (int i = 2; i <= 10; i++) {
for (int j = 0; j < 4; j++) {
cardArray.push_back(i);
}
}
//populate J, Q, K into array
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 4; j++) {
cardArray.push_back(10);
}
}
//populating array with Aces... treating them as special case '100'
for (int i = 0; i < 4; i++) {
cardArray.push_back(100);
}
return;
}
void Deck::showCards() {
for (unsigned int i = 0; i < cardArray.size(); i++) {
cout << cardArray[i] << endl;
}
}
Deck::Deck() {
wasteCards.clear();
cardArray.clear();
populateDeckWithCards();
shuffleDeck();
}
void Deck::shuffleDeck() {
int n = cardArray.size();
for(int a = n-1; a > 0; a--) {
int min = 0;
int max = a;
int j = min + rand() / (RAND_MAX / (max-min + 1) + 1);
int tmp = cardArray[a];
cardArray[a] = cardArray[j];
cardArray[j] = tmp;
}
return;
}
int Deck::remainingCards() {
return cardArray.size();
}
class Player {
public:
//data members
vector <int> playerHand;
//constructor
Player();
//methods
bool isBust();
int count();
void hit(Deck&);
void stand();
bool muckHand();
void showHand();
};
Player::Player() {
playerHand.clear();
}
void Player::showHand() {
for (unsigned int i = 0; i < playerHand.size(); i++) {
cout << playerHand[i] << endl;
}
return;
}
int Player::count() {
int handCount = 0;
for (unsigned int i = 0; i < playerHand.size(); i++) {
if (playerHand[i] != 100)
handCount += playerHand[i];
else {
if (playerHand[i] == 100) {
if ((handCount) > 11) {
handCount += 1;
}
else
handCount += 10;
}
}
}
return handCount;
}
bool Player::isBust() {
if (count() > 21)
return true;
else
return false;
}
void Player::hit(Deck& d) {
playerHand.push_back(d.dealCard());
}
void Player::stand() {
return;
}
bool Player::muckHand() {
playerHand.clear();
return true;
}
float bustProbability (const int threshHold) {
int threshHoldReached = 0;
Deck myDeck;
Player myPlayer;
Player dealer;
for (int i = 0; i < 10000; i++) {
myPlayer.hit(myDeck);
dealer.hit(myDeck);
myPlayer.hit(myDeck);
dealer.hit(myDeck);
while (myPlayer.count() < threshHold) {
myPlayer.hit(myDeck);
}
if (!(myPlayer.isBust())) {
++threshHoldReached;
}
myDeck.wasteCards.clear();
myPlayer.muckHand();
dealer.muckHand();
}
float bustFraction = float(threshHoldReached)/float(10000);
return bustFraction;
}
int main () {
cout << "blackjack simulation" << endl;
srand((unsigned int)time(NULL));
cout << bustProbability(19);
return 0;
}
I'm incredibly sorry for just posting my code, but I've spend 4 days on this issue, and I can't even begin to figure out what the problem is.
There is at least the line
cardArray.erase (cardArray.begin() + j - 1);
which seems to be dubious in case of j = 0
The question is described above. Basically, the input is vector<stack<int>>& piles and n, output is the max value for all n coins from any of the piles.
The only solution I can think of is to use backtracking for each pile, i.e. piles[0] is chosen i coins, then recursively call functions on piles[1...m-1] and n - i. And record max value for all possible combinations. I feel like this can be solved by dynamic-programming, however, due the constrain n, it's hard for me to build a dp equation.
Any better solution than backtracking?
There are m piles. Every pile p offers n+1 contributions of
(label, gain, cost):
for i from 0 upto n have ("pile {p}, {i} taken", sum of top i values, i).
The sum of costs must be equal (or less when negative numbers) to n, gain maximal.
The rest is up to the algorithm: whether you sort descending by ((double)gain)/cost or whatever.
This is definately nHr combination.
I would use some code like this.. p = number of piles, n = coins taken.
calc_sum is a function to record maximum value.
nHr h(p, n);
while(h.next()) {
for(int i=0; i<h.size(); i++) take_coins_from_a_pile(h[i]);
calc_sum();
}
And this is nHr library of my own.
#pragma once
#include <exception>
class NRexception : public std::exception
{
public:
virtual const char* what() const throw() {
return "Combination : N, R should be positive integer!!";
}
};
class Combination
{
public:
Combination(int n, int r);
virtual ~Combination() { delete [] ar;}
int& operator[](unsigned i) {return ar[i];}
bool next();
int size() {return r;}
static int factorial(int n);
protected:
int* ar;
int n, r;
};
class nCr : public Combination
{
public:
nCr(int n, int r);
bool next();
int count() const;
};
class nTr : public Combination
{
public:
nTr(int n, int r);
bool next();
int count() const;
};
class nHr : public nTr
{
public:
nHr(int n, int r) : nTr(n,r) {}
bool next();
int count() const;
};
class nPr : public Combination
{
public:
nPr(int n, int r);
virtual ~nPr() {delete [] on;}
bool next();
void rewind();
int count() const;
private:
bool* on;
void inc_ar(int i);
};
#include "combi.h"
#include <set>
#include<cmath>
Combination::Combination(int n, int r)
{
//if(n < 1 || r < 1) throw NRexception();
ar = new int[r];
this->n = n;
this->r = r;
}
int Combination::factorial(int n)
{
return n == 1 ? n : n * factorial(n-1);
}
int nPr::count() const
{
return factorial(n)/factorial(n-r);
}
int nCr::count() const
{
return factorial(n)/factorial(n-r)/factorial(r);
}
int nTr::count() const
{
return pow(n, r);
}
int nHr::count() const
{
return factorial(n+r-1)/factorial(n-1)/factorial(r);
}
nCr::nCr(int n, int r) : Combination(n, r)
{
if(r == 0) return;
for(int i=0; i<r-1; i++) ar[i] = i + 1;
ar[r-1] = r-1;
}
nTr::nTr(int n, int r) : Combination(n, r)
{
for(int i=0; i<r-1; i++) ar[i] = 1;
ar[r-1] = 0;
}
bool nCr::next()
{
if(r == 0) return false;
ar[r-1]++;
int i = r-1;
while(ar[i] == n-r+2+i) {
if(--i == -1) return false;
ar[i]++;
}
while(i < r-1) ar[i+1] = ar[i++] + 1;
return true;
}
bool nTr::next()
{
ar[r-1]++;
int i = r-1;
while(ar[i] == n+1) {
ar[i] = 1;
if(--i == -1) return false;
ar[i]++;
}
return true;
}
bool nHr::next()
{
ar[r-1]++;
int i = r-1;
while(ar[i] == n+1) {
if(--i == -1) return false;
ar[i]++;
}
while(i < r-1) ar[i+1] = ar[i++];
return true;
}
nPr::nPr(int n, int r) : Combination(n, r)
{
on = new bool[n+2];
for(int i=0; i<n+2; i++) on[i] = false;
for(int i=0; i<r; i++) {
ar[i] = i + 1;
on[i] = true;
}
ar[r-1] = 0;
}
void nPr::rewind()
{
for(int i=0; i<r; i++) {
ar[i] = i + 1;
on[i] = true;
}
ar[r-1] = 0;
}
bool nPr::next()
{
inc_ar(r-1);
int i = r-1;
while(ar[i] == n+1) {
if(--i == -1) return false;
inc_ar(i);
}
while(i < r-1) {
ar[++i] = 0;
inc_ar(i);
}
return true;
}
void nPr::inc_ar(int i)
{
on[ar[i]] = false;
while(on[++ar[i]]);
if(ar[i] != n+1) on[ar[i]] = true;
}
Below is my program to build a min-heap using a 0 based array with standard logic from the book. I am using 2*i+1 for left child and 2*i+2 for right child since its a zero based array, still I am getting a wrong output. What am I missing?
#include <iostream>
#include <vector>
#include <algorithm>
using std::vector;
using std::cin;
using std::cout;
class HeapBuilder {
private:
vector<int> data_;
void WriteResponse() const {
for (int i = 0; i < data_.size(); ++i) {
cout << data_[i] << "\n";
}
}
void ReadData() {
int n;
cin >> n;
data_.resize(n);
for (int i = 0; i < n; ++i)
cin >> data_[i];
}
void MinHeapSort(int index)
{
int left = (2 * index) + 1;
int right = (2 * index) + 2;
int smallest;
if (left < data_.size() && data_[left] < data_[index])
smallest = left;
else
smallest = index;
if (right < data_.size() && data_[right] < data_[index])
smallest = right;
if (smallest != index)
{
swap(data_[smallest], data_[index]);
MinHeapSort(smallest);
}
}
void Heapify() {
for (int i = (data_.size() - 1) / 2; i >= 0; i--)
{
MinHeapSort(i);
}
}
public:
void Solve() {
ReadData();
Heapify();
WriteResponse();
}
};
int main() {
std::ios_base::sync_with_stdio(false);
HeapBuilder heap_builder;
heap_builder.Solve();
return 0;
}
Replaced if (right < data_.size() && data_[right] < data_[index]) with
if (right < data_.size() && data_[right] < data_[smallest])
That worked, silly mistake.
Here I have a bigint class that uses an array called SafeArray that I created in a different class(we couldnt use vectors) the set and get function calls are from the SafeArray class, get takes an int parameter for array position and set takes 2 int parameters(one for position and one for value) all methods in this class work fine except for my subtract and compare methods. What I really need to work is my subtraction method. Any help? Thanks
int size = 20; //just for testing, will increase later
class bigint
{
SafeArray<int> *arr;
public:
bigint()
{
arr = new SafeArray<int>;
for(int i =0;i < size; i++)
arr->set(i,0);
}
void print()
{
for(int i = 0;i <arr->get_size() ;i++)
{
cout << arr->get(i);
}
cout<<endl;
}
void assign(const bigint &A)
{
for(int i=0;i<arr->get_size();i++)
{
arr->set(i,A.arr->get(i));
}
}
void assign(int num)
{
for(int i = arr->get_size()- 1; i >= 0; i--)
{
arr->set(i,num%10);
num /=10;
}
}
void assign(string num)
{
long len = num.length();
int j=arr->get_size()-1;
for(long i=len-1;i>=0;i--)
{
arr->set(j,num[i]-48);
j--;
}
}
void add(const bigint &A)
{
int carry=0;
for(int i=size-1;i>=0;i--)
{
int result = arr->get(i)+A.arr->get(i)+carry;
arr->set(i,result%10);
carry=result/10;}
}
void subtract(const bigint &A) {
for(int i=0, borrow=0; i<size; ++i)
{ int result=((arr->get(i) - A.arr->get(i) + borrow));
if(borrow == result < 0) {
A.arr->set(i,result+=10);
} } }
void compare(const bigint & A)
{
//int comp;
//for(int i =0;i<size;i++)
if(arr->get(size-1)>A.arr->get(size-1))
cout<<0;
else
cout<<1;
}
};
int main()
{
bigint A,B,C,D;
A.assign(12345);
A.print();
cout<<endl;
C.assign("123456789000");
C.print();
cout<<endl;
B.add(C);
B.print();
//B.compare(A);
//B.subtract(A);
//B.print();
return 0;
}
I think it should look like this
void subtract(const bigint &A) {
int borrow = 0;
for(int i=size-1; i >= 0; --i)
{
int result=((arr->get(i) - A.arr->get(i) - borrow));
if(result < 0) {
arr->set(i, result + 10);
borrow = 1;
} else {
arr->set(i, result);
borrow = 0;
}
}
}
// equals A
bool equals(const bigint &A) {
for(int i=0; i < size; ++i) {
if(A.arr->get(i) != arr->get(i)) {
return false;
}
}
return true;
}
// less than A
bool lt(const bigint &A) {
for(int i=0; i < size; ++i) {
if(arr->get(i) != A.arr->get(i)) {
return arr->get(i) < A.arr->get(i);
}
}
}