Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
When making a class how would I differentiate the two different class variables. I want to add elements in two vectors together and get a new vector with the sum of the two different numbers. In the code below when making an instance of a class I have access to it's vector but what about the one in parameters? number_blocks being the vector variable in the class BigInt
BigInt BigInt::add(const BigInt& number){
int flag = 0;
int carry = 0;
int sum = 0;
const int LIMIT = 9;
int size = number.length();
for(int i = 0; i < size; i++){
sum = number_blocks[i]// + number_blocks_number[i];
if(flag == 1){
sum = sum + carry;
flag = 0;
}
if(sum > LIMIT){
carry = sum / 10;
sum = sum % 10;
flag = 1;
}
number_blocks.push_back(sum);
}
return BigInt();
}
The same way you do number.length()
number.number_blocks[i]
BTW: you have to push the carry at the end (if nonzero).
Note: please ask specific questions. "I want to access a member variable of an object". show a one liner example. nobody cares about the rest.
Issues that I see with your implementation of BigInt::add:
You are returning an default instance of BigInt in the line:
return BigInt();
It makes sense to me that you would return a BigInt that is the result of adding two BigInts.
You are not taking into account the BigInts of varying length. For example, adding 187 with 85.
You are ignoring the last carry. If you add 9 and 9, you need to carry the 1.
The logic for computing the sum and the carry can be simplified to:
sum = this->number_blocks[i] + number.number_blocks[i] + carry;
carry = sum / 10;
sum = sum % 10;
You don't the variables flag and LIMIT.
Here's an implementation that addresses those issues.
BigInt BigInt::add(const BigInt& number){
int carry = 0;
int sum = 0;
// Compute the minimum number of digits from both the numbers.
size_t size1 = this->length();
size_t size2 = number.length();
size_t size = size1 < size2 ? size1 : size2;
BigInt ret;
// Process the digits that are in both the the first number and the
// second number.
for(size_t i = 0; i < size; i++)
{
sum = this->number_blocks[i] + number.number_blocks[i] + carry;
carry = sum / 10;
sum = sum % 10;
ret.number_blocks.push_back(sum);
}
// If the first number has more digits than the second, deal with the
// remaining digits from the first number.
if ( size1 > size )
{
for(size_t i = size; i < size1; i++)
{
sum = this->number_blocks[i] + carry;
carry = sum / 10;
sum = sum % 10;
ret.number_blocks.push_back(sum);
}
}
// If the second number has more digits than the first, deal with the
// remaining digits from the second number.
else if ( size2 > size )
{
for(size_t i = size; i < size2; i++)
{
sum = number.number_blocks[i] + carry;
carry = sum / 10;
sum = sum % 10;
ret.number_blocks.push_back(sum);
}
}
// Deal with the last carry.
if ( carry > 0 )
{
ret.number_blocks.push_back(carry);
}
return ret;
}
Related
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 7 years ago.
Improve this question
Given an array, arr, of length n, find how many subsets of arr there are such that XOR(^) of those subsets is equal to a given number, ans.
I have this dp approach but is there a way to improve its time complexity. ans is always less than 1024.
Here ans is the no. such that XOR(^) of the subsets is equal to it.
arr[n] contains all the numbers
memset(dp, 0, sizeof(dp));
dp[0][0] = 1;
for(i = 1; i <= n; i++){
for(j = 0; j < 1024; j++) {
dp[i][j] = (dp[i-1][j] + dp[i-1][j^arr[i]]);
}
}
cout << (dp[n][ans]);
From user3386109's comment, building on top of your code:
/* Warning: Untested */
int counts[1024] = {0}, ways[1024];
for(int i = 1; i <= n; ++i) counts[ arr[i] ] += 1;
for(int i = 0; i <= 1024; ++i) {
const int z = counts[i];
// Look for overflow here
ways[i] = z == 0 ?
0 :
(int)(1U << (z-1));
}
memset(dp, 0, sizeof(dp));
dp[0][0] = 1;
for(i = 1; i <= 1024; i++){
for(j = 0; j < 1024; j++) {
// Check for overflow
const int howmany = ways[i] * dp[i-1][j];
dp[i][j] += howmany;
dp[i][j^i] += howmany;
}
}
cout << (dp[1024][ans]);
For calculating odd_ and even_, you can also use the following:
nc0+nc2+... =
nc1+nc3... =
2n-1
Because number of ways to select odd items = number of ways to reject odd items = number of ways to select even numbers
You can also optimize the space by keeping just 2 columns of dp arrays and reusing them as dp[i-2][x] are discarded.
The Idea behind dynamic programming is, to (1) never compute the same result twice and (2) only compute results at demand and not precompute the whole thing as you do it.
So there is a solution needed for solve(arr, n, ans) with ans < 1024, n < 1000000 and arr = array[n]. The idea of having dp[n][ans] holding the number of results is reasonable, so dp size is needed as dp = array[n+1][1024]. What we need is a way to distinguish between not yet computed results and available results. So memset(dp, -1, sizeof(dp)) and then as you already did dp[0][0] = 1
solve(arr, n, ans):
if (dp[n][ans] == -1)
if (n == 0) // and ans != 0 since that was initialized already
dp[n][ans] = 0
else
// combine results with current and without current array element
dp[n][ans] = solve(arr + 1, n - 1, ans) + solve(arr + 1, n - 1, ans XOR arr[0])
return dp[n][ans]
The advantage is, that your dp array is only partially computed on the way to your solution, so this might save some time.
Depending on the stack size and n, it might be necessary to translate this from a recursive to an iterative solution
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 7 years ago.
Improve this question
Given an array, arr, of length n, find how many subsets of arr there are such that XOR(^) of those subsets is equal to a given number, ans.
I have this dp approach but is there a way to improve its time complexity. ans is always less than 1024.
Here ans is the no. such that XOR(^) of the subsets is equal to it.
arr[n] contains all the numbers
memset(dp, 0, sizeof(dp));
dp[0][0] = 1;
for(i = 1; i <= n; i++){
for(j = 0; j < 1024; j++) {
dp[i][j] = (dp[i-1][j] + dp[i-1][j^arr[i]]);
}
}
cout << (dp[n][ans]);
From user3386109's comment, building on top of your code:
/* Warning: Untested */
int counts[1024] = {0}, ways[1024];
for(int i = 1; i <= n; ++i) counts[ arr[i] ] += 1;
for(int i = 0; i <= 1024; ++i) {
const int z = counts[i];
// Look for overflow here
ways[i] = z == 0 ?
0 :
(int)(1U << (z-1));
}
memset(dp, 0, sizeof(dp));
dp[0][0] = 1;
for(i = 1; i <= 1024; i++){
for(j = 0; j < 1024; j++) {
// Check for overflow
const int howmany = ways[i] * dp[i-1][j];
dp[i][j] += howmany;
dp[i][j^i] += howmany;
}
}
cout << (dp[1024][ans]);
For calculating odd_ and even_, you can also use the following:
nc0+nc2+... =
nc1+nc3... =
2n-1
Because number of ways to select odd items = number of ways to reject odd items = number of ways to select even numbers
You can also optimize the space by keeping just 2 columns of dp arrays and reusing them as dp[i-2][x] are discarded.
The Idea behind dynamic programming is, to (1) never compute the same result twice and (2) only compute results at demand and not precompute the whole thing as you do it.
So there is a solution needed for solve(arr, n, ans) with ans < 1024, n < 1000000 and arr = array[n]. The idea of having dp[n][ans] holding the number of results is reasonable, so dp size is needed as dp = array[n+1][1024]. What we need is a way to distinguish between not yet computed results and available results. So memset(dp, -1, sizeof(dp)) and then as you already did dp[0][0] = 1
solve(arr, n, ans):
if (dp[n][ans] == -1)
if (n == 0) // and ans != 0 since that was initialized already
dp[n][ans] = 0
else
// combine results with current and without current array element
dp[n][ans] = solve(arr + 1, n - 1, ans) + solve(arr + 1, n - 1, ans XOR arr[0])
return dp[n][ans]
The advantage is, that your dp array is only partially computed on the way to your solution, so this might save some time.
Depending on the stack size and n, it might be necessary to translate this from a recursive to an iterative solution
I am going to have an array that is 50 elements long. Each element will contain one digit to form a 50 digit number. What I want to do is multiply this 50 digit long array by another 50 digit long array. The way I thought of doing this was converting each number to form one string. Then produce an algorithm that would multiply line by line 20 digits at a time. Then once the last for loop breaks out of scope, I could reconstruct the new array, digit by digit from converting it from a string. Any alternate ideas before I attempt this, or is what I got what you would do too?
int n1[50], n2[50], out[51];
// n1 and n2 must be populated here
int carry = 0;
for (int cur = 49; cur >= 0; --cur) {
out[cur+1] = n1[cur] * n2[cur] + carry;
carry = out[cur+1] / 10;
out[cur+1] %= 10;
}
out[0] = carry;
I believe you could find the question at leetcode OJ named "Multiply Strings".
This is my solution. Just for reference. Wish this will help :)
class Solution {
public:
string multiply(string num1, string num2) {
int s1(num1.size()), s2(num2.size()), size(s1+s2);
vector<int> digit(size,0), carry(size,0); // digit: store current digit, carry: store carry digit
for(int i = 0; i < s1; ++i){
for(int j = 0; j < s2; ++j){
int mul = num1[s1-1-i]-'0';
int muled = num2[s2-1-j]-'0';
int tmp = mul*muled;
digit[size-1-i-j] += tmp%10; // accum
carry[size-1-i-j-1] += tmp/10; // accum
}
}
int carrFlag(0); // initial carry_flag
for(int i = size-1; i >= 0; --i){ // merge digit and carry
int sum = digit[i] + carry[i] + carrFlag;
ret.insert(ret.begin(),1,'0'+sum%10); // compose result string
carrFlag = sum/10; // update carry_flag
}
int pos(0);
while(ret[pos] == '0') ++pos; // get rid of extra 0's
if(pos>=size) return "0"; // edge case
return ret.substr(pos);
}
private:
string ret;
};
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
I am making a program that determines if a value is composite, Prime, or Unvisited. The program ignores the first two values because they are 0 and 1, and labels them as I for ignore. Instead of outputting numbers it outputs the letter representation. example: "0123456" would output "IIPPCPC". It need to determines all the values up to 1000. The program uses loops to go through the array and change the value to the correct letter that represents it. I am confused on what code I would use to loop through the array and change all the values that are set to P at the moment that are composite to C. The program is suppose to reloop through the code in steps until all the values have be set to the correct representation.
/*
/ Name: Ralph Lee Stone
/ Description: Uses an array to find all the prime numbers up to 1000.
/ Date: 11/13/2013
/ Project: RLStone3_HW_10
*/
#include <iostream>
using namespace std;
int main()
{
// Declares an array to print all prime numbers up to 1000.
char mychararray[1001];
// Set all array index values to 'U', which stands for unvisited.
for(int i = 0; i <= 1000; i++)
{
mychararray[i] = 'U';
}
// Set the first two elements of the array index 0 & 1 to 'I'. which stands for ignore.
mychararray[0] = 'I';
mychararray[1] = 'I';
//for ( int i = 0 ; i < 1001 ; i ++ )
// cout << mychararray[i] ;
//cout << mychararray;
//Skips the first two values, so that the first two values are skipped.
int i = 0;
while(mychararray[i] !='U')
i++;
// Changes the all the values that are set to U to P.
for(int i = 2; mychararray[i] >= mychararray[1001]; i++)
mychararray[i] = 'P';
//i++;
// Loops through the array again and changes all the values that are set to P that are composite to C.
// Outputs the array.
for ( int i = 0 ; i < 1001 ; i ++ )
cout << mychararray[i] ;
//Pauses the console window.
system("pause");
// returns the value 0.
return(0);
}
This looks a lot like homework, so I'll skip the details. What you want is called the sieve of eratosthenes and consists in takin the numbers you already know are primes and discard all their multiples from the rest of the array.
for (int i = 2; i < 1001; i++)
{
for (int j = 2; j <= (int) sqrt(i); j++)
{
if (i % j == 0)
{
mychararray[i] = 'C';
break;
}
}
}
^^ For every number in the array check if the number is divisible by any numbers from 2 up to the square root of the number
for (int i = 2; i < 1001; i++)
{
for (int j = 2; j * i < 1001; j++)
mychararray[j * i] = 'C';
}
^^ Sieve of Eratosthenes
For definition, 1 is prime, 2 is the only prime number, so, you can have something like this:
bool isPrime(unsigned int number) {
if (number == 1 || number == 2) {
return true;
}
if (number % 2 == 0) {
return false;
}
for (int i = 2; i < number / 2; i++) {
if (number % i == 0) {
return false;
}
}
return true;
}
Then, you iterate over you array:
char representation[SIZE];
for (int i = 0; i < SIZE; i++) {
representation[i] = isPrime(data[i]) ? 'P' : 'C';
}
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Division with really big numbers
I need to overload the / operator to work on two HugeInt objects which are defined simply as an array of 30 shorts. This is homework, btw, but I have been wracking my brain for days on this problem.
I have overloaded the * operator already:
HugeInt HugeInt::operator*(const HugeInt &op2){
HugeInt temp;
short placeProducts[hugeIntSize + 1][hugeIntSize] = {0};
short product;
int carry = 0;
int k, leftSize, rightSize, numOfSumRows;
leftSize = getDigitLength();
rightSize = op2.getDigitLength();
if(leftSize <= rightSize) {
numOfSumRows = leftSize;
for(int i = (hugeIntSize - 1), k = 0; k < numOfSumRows; i--, k++) {
for(int j = (hugeIntSize - 1); j >= k; j--) {
product = integer[i] * op2.integer[j] + carry;
if (product > 9) {
carry = product / 10;
product %= 10;
} else {
carry = 0;
}
placeProducts[k][j - k] = product;
}
}
} else {
numOfSumRows = rightSize;
for(int i = (hugeIntSize - 1), k = 0; k < numOfSumRows; i--, k++) {
for(int j = (hugeIntSize - 1); j >= k; j--) {
product = integer[j] * op2.integer[i] + carry;
if (product > 9) {
carry = product / 10;
product %= 10;
} else {
carry = 0;
}
placeProducts[k][j - k] = product;
}
}
}
sumProductsArray(placeProducts, numOfSumRows);
for(int i = 0; i < hugeIntSize; i++)
{
temp.integer[i] = placeProducts[hugeIntSize][i];
}
return temp;}
But how do I overload the / op? My main problem isn't with the C++ code or syntax, but with my algorithm to divide. When I multiply I am able to do it digit by digit. I store each product (aka 1's digit of bottom times every digit above, then 10's digit time every num above using my carry algorithm) in my 2d array. Every time I get new product it is offset to the left by n + 1, which "multiplies" it by the required power of 10. Then I just sum up all the columns.
I can't for the life of me figure out how to code the long division method. Since I'm dealing with two arrays it has to be digit by digit, and I suspect it might be as easy as reversing the multiplication algorithm. Nested loops and subtraction? I would need a variable for the quotient and reminder? Is there a better method? I just need to be pointed in the right direction.
In computational division of integers, there are a few interesting results:
numerator < denominator implies quotient = 0
numerator == denominator implies quotient = 1
numerator > denominator, long division would be needed to determine quotient.
The first two conditions can be satisfied with a for loop. You could overload the less-than and equals relational operator to encapsulate this behavior.
For the long division, you will need your multiplication operator as well as overloaded less-than and subtraction operators, and an append digit member function to perform the operation.
It's brute force, but should get the job done.