This is pacific question. The implementation of the class LargeInt will use a dynamic physical structure to store the individual digits of an integer, and will provide some basic I/O and arithmetic operations that can be performed on integers.
In particular, the class should include:
A default constructor
An operator function to overload the operator +
An operator function to overload the operator ==
An operator function to overload the operator <<
An operator function to overload the operator >>
Note 1: since the LargeInt class does not contain pointers, there is no need for a copy constructor or a destructor.
#include "targetver.h"
using namespace std;
class LargeInt
{
private:
char datain[200];
int databit[200];
int len;
int overflow;
LargeInt(char *x, int inlen)
{
int i = 0;
int j = inlen - 1;
len = inlen;
overflow = 0;
for (i = 0; i < 200; i++)
{
databit[i] = 0;
datain[i] = '\0';
}
for (i = 0; i < len; i++)
{
datain[i] = x[j];
j--;
}
}
~LargeInt();
void GetDataBit()
{
int i = 0;
for (i; i < len; i++)
databit[i] = datain[i] - 48;
}
public:
LargeInt& operator+(LargeInt& data);
bool operator==(LargeInt& data);
LargeInt& operator>>(int x);
LargeInt& operator<<(int x);
};
bool LargeInt::operator==(LargeInt& data)
{
if (this->len != data.len)
return false;
else
{
for (int i = 0; i < 200; i++)
{
if (this->databit[i] == data.databit[i])
continue;
else
return false;
}
return true;
}
}
LargeInt& LargeInt::operator+(LargeInt& data)
{
LargeInt t("0", 0);
int addlen;
if (this->len > data.len)
addlen = this->len;
else
addlen = data.len;
for (int i = 0; i < addlen; i--)
{
t.databit[i] = (data.databit[i] + this->databit[i] + t.overflow) % 10;
if ((data.databit[i] + this->databit[i] + t.overflow) >= 10)
t.overflow = 1;
}
t.len = addlen;
for (int i = 0; i < addlen; i++)
{
t.datain[i] = t.databit[i] + 48;
}
return t;
}
when I build it, it has a error like this
Warning 1 warning C4172: returning address of local variable or temporary.
LargeInt& LargeInt::operator+(LargeInt& data)
remove the & and your warning should go away. Right now the return is referencing a variable t, which is local to the function which has gone out of scope by the time the calling function catches the return.
Related
This is a project for my object oriented programming class. I need to introduce the followings: overloading + to sum two polynomials, overloading * to multiply a polynomial with a scalar or to multiply it with another polynomial, overloading [] to return coeficient on a specific position, method for adding , deleting a coeficient and evaluating polynom in a certain point (f(x)).
1.Everything is working besides the destructor. The destructor that should be used (delete [] coef) of Polynomial will break (Heap Coruption) if i use cout << A + B and i do not know why.
What i use right now is a workaround but it will not delete coef[0]. That's the point where it breaks. If you can help me somehow i will be gratefull. Can you understand what caused it?
2.I need to have one more overloaded operator, " / ". It should make division between two polynomials and I do not know how to implement it. I tried to search for it but i couldn't understand any algorithm. Any advice or algorithm explanation would be great, because i really do not know from where to start and i need to finish it until tommorrow morning.
3.If you have any advice on coding or efficienty will also be great ( project requirement: do not use STL ).
Thank you!
Polynomial.h:
#pragma once
#include <iostream>
using std::cout;
using std::cin;
using std::endl;
using std::ostream;
using std::istream;
class Polynomial
{
unsigned int deg;
double *coef;
public:
Polynomial() : deg(1), coef(new double[1]) {}
Polynomial(double [], int);
Polynomial(Polynomial&);
Polynomial& operator = (const Polynomial&);
~Polynomial();
friend ostream &operator <<(ostream&, const Polynomial&);
friend istream &operator >>(istream&, Polynomial&);
Polynomial operator + (const Polynomial) ;
double operator[] (unsigned int) const;
Polynomial operator * (int) const;
Polynomial operator * (const Polynomial obj) const;
unsigned int getDeg() { return this->deg; };
double eval(int);
void addCoef(double, int);
void delCoef(int);
};
inline Polynomial::Polynomial(double coefficients[], int number) : deg(number), coef(new double[number])
{
for (int i = 0; i < deg; i++) {
coef[i] = coefficients[i];
}
}
inline Polynomial::Polynomial(Polynomial &ob) {
this->deg = ob.deg;
this->coef = new double[deg];
for (int i = 0; i <= deg; i++)
{
this->coef[i] = ob.coef[i];
}
}
inline Polynomial::~Polynomial() {
for (int i = this->deg; i > 0; i--)
this->delCoef(i);
this->coef[0] = 0; //If i write it like this delete [] coef; it breaks.
this->deg = 0; //with HeapCoruption detected
}
Polynomial.cpp:
Polynomial& Polynomial::operator = (const Polynomial& obj)
{
if (this != &obj) //Testing to avoid situations like A = A;
{
this->deg = obj.deg;
for (int i = 0; i <= obj.deg; i++)
this->coef[i] = obj.coef[i];
}
return *this;
}
istream& operator >> (istream& in, Polynomial& obj)
{
in >> obj.deg;
cout << endl;
obj.coef = new double[obj.deg];
for (int i = 0; i <= obj.deg; i++)
{
in >> obj.coef[i];
}
return in;
}
ostream& operator << (ostream& out, const Polynomial& obj)
{
out << obj.deg << endl;
for (int i = 0; i <= obj.deg; i++)
{
if (obj.coef[i] != 0)
{
if (obj.coef[i] < 0)
out << '(' << obj.coef[i] << ')';
else
out << obj.coef[i];
if (i > 1)
out << "*x^" << i;
if (i == 1)
out << "*x";
if (i != obj.deg)
out << " + ";
}
}
out << endl <<endl;
return out;
}
Polynomial Polynomial::operator+ (const Polynomial obj)
{
Polynomial aux;
if (obj.deg >= deg)
{
aux.deg = obj.deg;
aux.coef = new double[obj.deg];
for (int i = 0; i <= deg; i++)
aux.coef[i] = obj.coef[i] + coef[i];
for (int i = deg + 1; i <= obj.deg; i++)
aux.coef[i] = obj.coef[i];
}
else // obj.deg < this->deg
{
aux.deg = deg;
aux.coef = new double[deg];
for (int i = 0; i <= obj.deg; i++)
{
aux.coef[i] = obj.coef[i] + coef[i];
}
for (int i = obj.deg + 1; i <= deg; i++)
{
aux.coef[i] = coef[i];
}
}
return aux;
}
double Polynomial::operator[] (unsigned int pos) const
{
if (pos > this->deg) {
throw std::out_of_range("Index bigger than polynomial length");
}
return this->coef[pos];
}
Polynomial Polynomial::operator * (const int scalar) const
{
Polynomial aux;
aux.deg = this->deg;
aux.coef = new double[aux.deg];
for (int i = 0; i <= aux.deg; i++)
aux.coef[i] = this->coef[i] * scalar;
return aux;
}
Polynomial Polynomial::operator * (const Polynomial obj) const
{
Polynomial aux;
aux.deg = obj.deg + this->deg;
aux.coef = new double[aux.getDeg()];
for (int i = 0; i <= aux.getDeg(); i++)
aux.addCoef(0, i);
for (int i = 0; i <= this->deg; i++)
for (int j = 0; j <= obj.deg; j++)
aux.coef[i+j] += (this->coef[i]) * obj.coef[j];
return aux;
}
double Polynomial::eval(int x) {
double sum = 0;
for (int i = 0; i <= this->deg; i++)
{
if (i == 0)
sum += this->coef[0];
else
{
int aux = i;
int xaux = x;
aux--;
while (aux != 0)
{
xaux *= x;
aux--;
}
sum += this->coef[i] * xaux;
}
}
return sum;
}
void Polynomial::addCoef(double NewCoef, int pos)
{
if (pos < 0)
return;
if (pos > this->deg)
{
double *newCoef = new double[pos];
for (int i = 0; i <= this->deg; i++)
newCoef[i] = this->coef[i];
for (int i = this->deg + 1; i < pos; i++)
newCoef[i] = 0;
newCoef[pos] = NewCoef;
this->coef = newCoef;
this->deg = pos;
return;
}
else
{
this->coef[pos] = NewCoef;
}
}
void Polynomial::delCoef(int pos)
{
if (pos > this->deg || pos < 0 )
return;
if (pos == this->deg)
{
this->coef[pos] = 0;
int degNoua = pos - 1;
while (this->coef[pos] == 0 && pos != 0)
pos--;
if (pos == 0 && this->coef[pos] == 0)
{
delete this->coef;
this->deg = 0;
}
else
{
this->deg = pos;
double *aux = new double[pos];
for (int i = 0; i <= pos; i++)
aux[i] = this->coef[i];
this->coef = aux;
}
}
else
{
this->coef[pos] = 0;
}
}
Hi I need help creating a < operator and Im not sure how.
#include "biguint.h"
#include <string>
#include <cstdlib>
#include <iostream>
biguint::biguint()
{
for(size_t i = 0; i < CAPACITY; i++){
data_[i]=0;
}
}
biguint::biguint(const std::string &s){
int templeng = s.length();
for(size_t i = 0; i < templeng; i++){
data_[i] = s[templeng -i - 1] -'0';
}
for(size_t i = templeng; i < CAPACITY; i++){
data_[i]=0;
}
}
unsigned short biguint::operator [](std::size_t pos) const{
unsigned short i = 0;
if(pos >= 0 && pos < CAPACITY){
i = data_[pos];
}
return i;
}
std::ostream& operator <<(std::ostream& out, const biguint& b)
{
for (int i = biguint::CAPACITY; i > 0; i--) {
out<<b[i-1];
}
return out;
}
void biguint::operator += (const biguint & b){
int k = 0;
int temp = 0;
for (size_t i = 0; i < CAPACITY; i++) {
temp = data_[i]+b.data_[i];
if(temp >= 10){
data_[i] = temp-10;
data_[i+1]+=1;
}
else{
data_[i]=temp;
}
}
}
biguint operator + (const biguint & lhs, const biguint & rhs)
{
int temp;
bool remainder = false;
std::string result = "";
std::string reverse = "";
if(lhs.CAPACITY != rhs.CAPACITY)
{
return biguint("0");
}
for(int i =0; i < (int)lhs.CAPACITY;i++)
{
temp = lhs[i]+rhs[i];
if(remainder)
{
temp++;
remainder = false;
}
if(temp<10)
{
result = result + std::to_string(temp);
}
else {
result += std::to_string(temp - 10);
remainder = true;
}
}
for (int i = result.size() - 1; i >= 0; i--) {
reverse += result[i];
}
return biguint(reverse);
}
int biguint::compare(const biguint & b) const
{
return this->toStdString().compare(b.toStdString());
}
std::string biguint::toStdString() const
{
bool start = false;
std::string result = "";
for (int i = (int) this->CAPACITY - 1; i >= 0; i--) {
if (this->data_[i] == 0 && !start) {
if (this->CAPACITY == 1)
result += std::to_string(this->data_[i]);
continue;
}
else {
start = true;
result += std::to_string(this->data_[i]);
}
}
return result;
}
bool operator < (const biguint & lhs, const biguint & rhs)
{
}
This my .cpp file Im kind of lost on how to create < operator. I have created the +,+=, and two string but I'm unsure of how to create the <. Im not sure how to access those numbers for example biguint one("233") how would i access that number
Tl;dr: Try to compare digit by digit while handling mismatched length cases.
Say your given any 2 numbers:
num1 = 12345
num2 = 57632
The intuitive way for you to determine that which is bigger:
Compare them starting from the most significant digit(eg. here 5 > 1)
When equal compare the next significant digit(eg. if the numbers were 92 and 93, you would have compared 2 < 3 to get your answer.
The only difference is here individual digits are stored in an array.
P.S. Your compare seems to do a lexicographic compare - Is that really what you want?
When I run my code i get a segmentation fault for calling the default constructor, but not every time I call it. It faults when I try to dynamically allocate new memory after overloading the + operator. I know seg faults happen with misuse of pointers but I call the def. constructor prior in the code and it works.
here is a git repo with main and header if needed:
#include <iostream>
#include "proj1-5-MyString.h"
#include <cmath>
using namespace std;
MyString::MyString() {
capacity = 10;
size = 0;
data = new char[capacity];
data[size] = '\0';
}
//Constructor
MyString::MyString(const char *input) {
this->capacity = 10;
this->size = 0;
this->data = new char[this->capacity];
for (int count = 0; input[count] != '\0'; count++) {
if (count >= this->capacity) {
this->capacity *= 2;
char *temp = new char[this->capacity];
for (int i = 0; i < this->size; i++) {
temp[i] = this->data[i];
}
delete[] this->data;
this->data = temp;
delete[] temp;
}
this->data[count] = input[count];
this->size = count + 1;
}
while ((double) this->size < 0.25 * ((double) (this->capacity))) {
this->capacity = (int)floor(this->capacity / 2);
}
this->data[this->size + 1] = '\0';
}
//Constructor with an initialization character string
MyString::~MyString() {
delete[] this->data;
data = NULL;
}
//Destructor
MyString::MyString(const MyString &that) {
this->data = new char[this->capacity];
this->capacity = that.capacity;
this->size = that.size;
for(int i = 0; i < size; i++){
this->data[i] = that.data[i];
}
while(this->size < 0.25 * (double)(this->capacity)){
this->capacity = (int)((double)that.capacity / 2.0);
}
}
//Copy constructor
MyString &MyString::operator=(const MyString &input) {
if (this->data != input.data) {
delete[] this->data;
this->capacity = input.capacity;
this->size = input.size;
int charCount = 0;
for ( charCount; charCount < input.size; charCount++) {
if (charCount >= this->capacity) {
this->capacity *= 2;
char *temp = new char[this->capacity];
for (int j = 0; j < charCount; j++) {
temp[j] = this->data[j];
}
delete[] this->data;
this->data = temp;
delete[] temp;
}
this->data[charCount] = input.data[charCount];
this->size = charCount + 1;
}
}
return *this;
}
//Overloaded assignment operator, make a copy of MyString object
bool MyString::operator==(const MyString &otherString) const {
int i = 0;
bool same = true;
if (this->size == otherString.size) {
while (i < otherString.size) {
if (this->data[i] == otherString.data[i]) {
same = i <= size;
} else {
same = false;
}
i++;
}
} else {
same = false;
}
return same;
}
//overloaded equivalence relational operator
char &MyString::operator[](int val) {
return this->data[val];
}
//overloaded [ ] should return a char by reference
void MyString::operator+=(const MyString &otherStr) {
*this = *this + otherStr;
}
//overloaded += operator, use to concatenate two MyStrings
MyString MyString::operator+(const MyString &otherStr) const {
//SEGFAULT HERE
MyString doubleString;
cout << doubleString.capacity << endl;
while (doubleString.capacity < (this->size + otherStr.size)) {
doubleString.capacity *= 2;
}
for (int i = 0; i < max(this->size, otherStr.size); i++) {
doubleString.data[i] = this->data[i];
doubleString.data[i + this->size] = otherStr.data[i];
}
doubleString.size = this->size + otherStr.size;
return doubleString;
}
//Create a new MyString object that is the concatenation of two MyString
//objects
void MyString::getline(istream &in, char delimit) {
delimit = '\n';
int size = 10;
char buffer[size];
int charNum = 0;
while (in.get(buffer[charNum++])) {
if (buffer[charNum - 1] == delimit) {
break;
}
if (charNum >= size) {
char *temp = new char[size * 2];
for (int j = 0; j < size; j++) {
temp[j] = data[j];
}
delete[] data;
data = temp;
delete[] temp;
}
}
}
//reads an entire line from a istream. Lines are terminated with delimit
//which is newline ā\nā by default
int MyString::length() const {
return this->size;
}
//return the length of the string
ostream &operator<<(ostream &out, MyString &stringWord) {
for (int i = 0; i < stringWord.size; i++) {
out << stringWord.data[i];
}
return out;
}
//overloaded insertion operator
For instance, if you have this code:
MyString s0 = "ABC";
MyString s1 = "DEF";
auto s2 = s0 + s1;
The first problem is in the constructor of MyString. Your strings are not \0 terminated.
This can be fixed quite easiely though:
MyString::MyString(const char *input)
{
this->capacity = 10;
this->size = 0;
//this->data = new char[this->capacity]; //<- Old
this->data = new char[this->capacity](); //<- New
There are multiple places where you don't initialize the allocated char array. Please check your code and do so. Either via the char() constructor or various other ways (std::fill, memset, ...).
Please remember to debug your own code before posting a question. You can spot this in the debugger pretty easiely.
So I am trying to figure out how to create a function that Returns an Array of all integers that are in common with self and ary and returns an empty Array if there are no intersections. This is what I have so far:
IntArray* findIntersections(IntArray &ary) {
int length1 = ary.getLength(); // Getting the length of &ary.
int length2 = getLength([//Right here, there's something to do with "this" because I've created a mArray already and defined it, but I'm not sure how to re-call it here.]); // Getting the length of self.
int length4 = 0; // Because anarchy
if (length1 > length2){ // An if statement to match length4 with the longest array.
length4 = length2;
} else {
length4 = length1;
}
IntArray* newArray; // New IntArray on the heap.
newArray = new* int[length4];
int k = 0;
for (int j = 0; j < length1; j++){ // Two for loops getting the iterator on the same page.
for (int i = 0; i < length2; i++){
if (ary.get(j) == [//The this from earlier, whatever it is][i]){ // Checking to see if digits match each other.
newArray[k] = (ary[j]); // Writing the digit into the NewArray.
k++; // Adding one to the k count to progress the the iterator.
}
}
}
return newArray;
}
In the end, there I know there's gonna be three arrays. The one being passed in, the one being created and passing out, and then that this reference which I honestly don't even know what it is. I'm thinking it's an mArray I created earlier, but I'm not exactly sure. Any help on this would be absolutely fantastic!
Also, here's my .hpp file:
class IntArray {
private:
int *mArray;
int mSize;
public:
IntArray(int *array, int size);
int get(int index);
int getLength();
int indexOf(int value);
bool remove(int index);
IntArray* findIntersections(IntArray &ary);
bool isSubsequence(IntArray &ary);
~IntArray();
};
And my .cpp file:
#include "IntArray.hpp"
IntArray::IntArray(int *array, int size) {
int *newArray = new int [size];
for (int i = 0; i < size; i++){
newArray[i] = array[i];
}
}
int IntArray::get(int index) {
return mArray[index];
}
IntArray::~IntArray() {
delete[] mArray;
}
int IntArray::getLength() {
return mSize;
}
int getLength(int *array){
int length = (sizeof(array)/sizeof(array[0]));
return length;
}
int indexOf(int *array, int value){
int length = getLength(array);
for (int i = 0; i < length; i++){
if (value == array[i]){
return i;
}
}
return -1;
}
bool remove(int *array, int index){
int length = getLength(array);
if (0 <= index && index < length){
for (int i = index + 1; i < length; ++i){
array[i - 1] = array[i];
}
for (int i = 0; i < length; i++)
return true;
} else {
return false;
}
}
IntArray* findIntersections(IntArray &ary) {
int length1 = ary.getLength(); // Getting the length of &ary.
int length2 = getLength([//Right here, there's something to do with "this" because I've created a mArray already and defined it, but I'm not sure how to re-call it here.]); // Getting the length of self.
int length4 = 0; // Because anarchy
if (length1 > length2){ // An if statement to match length4 with the longest array.
length4 = length2;
} else {
length4 = length1;
}
IntArray* newArray; // New IntArray on the heap.
newArray = new* int[length4];
int k = 0;
for (int j = 0; j < length1; j++){ // Two for loops getting the iterator on the same page.
for (int i = 0; i < length2; i++){
if (ary.get(j) == [//The this from earlier, whatever it is][i]){ // Checking to see if digits match each other.
newArray[k] = (ary[j]); // Writing the digit into the NewArray.
k++; // Adding one to the k count to progress the the iterator.
}
}
}
return newArray;
}
bool isSubsequence(int *array) {
int length = getLength(array);
for (int i = 0; i < length - 1; i++) {
if (array[i] != array[i + 1])
return false;
}
return true;
}
Your implementation of findIntersection is not defined as a member function, you have defined it as a global function. The member function declaration named findIntersection is not defined. In short: you forgot IntArray:: before the function name
So far I've got an add, subtract and print function as well as a constructor that initializes to zero the array. For some reason the operations(+ and -) made alot of sense to me(i think) so I kind of got ahead of my self and am not too sure how to initialize a big integer, could I get some help with a function such as
void assign(const bigint & A) or something like that? Also if there is something already wrong with my code please tell me. Thanks
const int size=30; //just to make things easier, will change to something big later
class bigint
{
int digits[size];
public:
// initializes to zero
bigint()
{
for (int i = 0; i < size; i++)
digits[i] = 0;
}
// prints a big int
void print()
{
bigint B;
for (int i = size - 1; i >= 0; i--)
{
int dig = B.digits[i];
if (dig != 0)
std::cout << dig;
}
}
// subtracts a bigint(B) from another(A)
void subtract(bigint & A, bigint & B)
{
for (int i = 0, borrow = 0; i < size; i++)
{
if (borrow = ((A.digits[i] -= B.digits[i] + borrow) < 0))
{
A.digits[i] += 10;
}
}
}
// adds a bigint(A) to another(B)
void add(bigint & A, bigint & B)
{
for (int i = 0, carry = 0; i < size; i++)
{
if (carry = ((A.digits[i] += B.digits[i] + carry) < 9))
{
A.digits[i] -= 10;
}
}
}
};