i am a novice to C++ , I was trying to write this program for adding two very large numbers using strings but the program is not working correctly and I can't get what's wrong with it , please help me with this.
#include<iostream>
#include<stack>
#include<string>
using namespace std;
int main() {
stack <char> a1;
stack<char> a2;
stack<int> result;
stack<int> temp;
int carry = 0;
string num1;
string num2;
cout << "Enter first number (both numbers should have equal digits)" << endl;
getline(cin, num1);
cout << "Enter second number" << endl;
getline(cin, num2);
for (int i = num1.size()-1; i >= 0; i--) {
a1.push(num1[i]);
a2.push(num2[i]);
}
while (!a1.empty() && !a2.empty()) {
int element = (int)a1.top() + (int)a2.top() + carry;
cout << element;
if (element > 10) {
element %= 10;
carry = 1;
}
result.push(element);
cout << result.top() << endl;
a1.pop();
a2.pop();
}
string abc;
while (!result.empty()) {
temp.push(result.top());
result.pop();
abc += temp.top();
}
cout << abc;
}
I know i have definitely made a logical mistake , but i can't get it , can anyone please guide me?
the following is the output am getting
I was thinking, why stacks should be used. My guess is that you did this, because the numbers must be processed from right to left.
Additionally, you have obiously a challenge with strings with a different length.
But both problems can be solved easily. Let us start with the different length strings.
If 2 strings have a different length, we can pad (fill in) the shorter string with leading `0's. How many leading '0s' do we need to add? Right, the delta of the lengths.
And for inserting characters in a string at a certain position, we have the function insert.
So, the code for that will look like this:
if (numberAsString1.length() < numberAsString2.length())
numberAsString1.insert(0, numberAsString2.length() - numberAsString2.length(), '0');
else
numberAsString2.insert(0, numberAsString1.length() - numberAsString2.length(), '0');
This is rather straightforward.
The result will always be 2 strings with equal length. With entering "1234" and "9", we will get: "1234" and "0009".
This makes the next task easier.
Now that we have 2 equal length strings, we can "add", like we learned in school.
We go from right to left, by starting with the highest possible index of a character in the string. This is always length-1.
For calculating the sum, we need first to subtract the ASCII code for '0' from the characters in the string, because the string contains not integer numbers, but characters. For example "123" consists of '1', '2', '3' and not of 1,2,3.
Suming up is then easy: digit + digit + carry.
The resulting digit is always the sum % 10. And the next carry is always sum / 10. Example 1: 3+5=8 8%10=8 8/10=0. Example 2: 9+8=17 17%10=7 17/10=1.
So, also this is rather simple.
After we worked on all digits of the strings, there maybe still a set carry. This we will then add to the string.
Adding digits will be done in any case using the instert function. Because we want to insert digits on the left side of the resulting string.
So, with working from right to left, using correct indices and the insert function, we do not have the need for a stack.
With a lot of input checking, the whole function would look like this:
#include <iostream>
#include <string>
#include <algorithm>
#include <cctype>
int main() {
// Give instruction to user
std::cout << "\nPlease enter 2 positive interger numbers:\n";
// Here we will store the user input
std::string numberAsString1{}, numberAsString2{};
// Get strings from user and check, if that worked
if (std::cin >> numberAsString1 >> numberAsString2) {
// Check if all characters in string 1 are digits
if (std::all_of(numberAsString1.begin(), numberAsString1.end(), std::isdigit)) {
// Check if all characters in string 2 are digits
if (std::all_of(numberAsString2.begin(), numberAsString2.end(), std::isdigit)) {
// ---------------------------------------------------------------------------------
// Here we will store the calculated result
std::string result{};
// Temporary helpers
unsigned int carry{};
// ---------------------------------------------------------------------------------
// Make strings equal length. Pad with leading '0' s
if (numberAsString1.length() < numberAsString2.length())
numberAsString1.insert(0, numberAsString2.length() - numberAsString2.length(), '0');
else
numberAsString2.insert(0, numberAsString1.length() - numberAsString2.length(), '0');
// ---------------------------------------------------------------------------------
// Iterate over all digits from right to left
for (int i = numberAsString1.length()-1; i >= 0; --i) {
// Calculate the sum
const int sum = numberAsString1[i]-'0' + numberAsString2[i] - '0' + carry;
// Get the carry bit in case of overflow
carry = sum / 10;
// Save the resulting digit
result.insert(0, 1, sum % 10 + '0');
}
// handle last carry bit
if (carry) result.insert(0, 1, '1');
// ---------------------------------------------------------------------------------
// Show result
std::cout << "\n\nSum: " << result << '\n';
}
else std::cerr << "\n\nError: number 1 contains illegal characters\n";
}
else std::cerr << "\n\nError: number 2 contains illegal characters\n";
}
else std::cerr << "\n\nError: Problem with input\n";
return 0;
}
Related
The point of this exercise was to create code that can compute very large sums by using an algorithm close to how you would do it by hand. My code seems to work just fine, except for one specific test case, which is 9223372036854775808 + 486127654835486515383218192. I'm not sure what is special about this specific test case for it to fail, because the code is totally capable of carrying over, as well as adding numbers that have two different amounts of digits...Help would be greatly appreciated.
Edit: The output for this case is +'2+-0+*.4058858552237994000
// Basic mechanism:
//reverse both strings
//reversing the strings works because ex. 12+12 is the same as 21+21=42->reverse->24
//add digits one by one to the end of the smaller string
//dividing each sum by 10 and attaching the remainder to the end of the result-> gets us the carry over value
// reverse the result.
//ex. 45+45 ->reverse = 54+54 -> do the tens place -> 0->carry over -> 4+4+1 -> result= 09 -> reverse -> 90.
#include <iostream>
#include <cstring>
using namespace std;
string strA;
string strB;
string ResStr = ""; // empty result string for storing the result
int carry =0;
int sum; //intermediary sum
int n1; //length of string 1
int n2; // length of string 2
int rem; // remainder
int main()
{
cout << "enter" << endl;
cin >> strA;
cout << "enter" << endl; // I didn't know how to write this program to use argv[1] and argv[2] so this was my solution
cin >> strB;
// turning the length of each string into an integer
int n1 = strA.length(), n2 = strB.length();
if (n1<n2){
swap(strA,strB);
}//for this part I have no idea why this has to be the case but it only works if this statement is here
// Reversing both of the strings so that the ones, tens, etc. positions line up (the computer reads from left to right but we want it to read from right to left)
reverse(strA.begin(), strA.end());
reverse(strB.begin(), strB.end());
for (int i=0; i<n2; i++)//start at 0, perform this operation until the amount of times reaches the value of n2
{
//get the sum of current digits
int sum = ((strA[i]-'0')+(strB[i]-'0')+carry);
int quotient=(sum/10);
int rem=(sum-10*quotient);
ResStr+=(rem+'0'); //this gets the remainder and adds it to the next row
// Calculate carry for next step. Thus works because carry is an integer type, so it will truncate the quotient to an integer, which is what we want
carry = sum/10;
}
// Add the remaining digits of the larger number
for (int i=n2; i<n1; i++) //start at n1, perform this operation until the amount of times reaches the value of n1
{
int sum = ((strA[i]-'0')+carry);
int quotient=(sum/10);
int rem=(sum-10*quotient);
ResStr+=(rem+'0');
carry = sum/10;
}
// Add remaining carry over value
if (carry)
ResStr+=(carry+'0');
// reverse the resulting string back, because we reversed it at the beginning
reverse(ResStr.begin(), ResStr.end());
cout << "The result is " << ResStr << endl;
return 0;
}
After a lot of experimentation, what made the difference for me was replacing n1 and n2 entirely with strA.length() and strB.length() respectively in the for loop declarations. I'm not entirely sure why this happens, so if anyone has an explanation- please forward it.
Anyway, here's my version of the code:
//Basic mechanism: reverse both strings
//reversing the strings works because ex. 12+12 is the same as 21+21=42->reverse->24 (for single-digit sums smaller than 10)
//add digits one by one to the end of the smaller string
//dividing each sum by 10 and attaching the remainder to the end of the result-> gets us the carry over value reverse the result (mod 10 arithetic)
//ex. 45+45 ->reverse = 54+54 -> do the tens place -> 0->carry over -> 4+4+1 -> result= 09 -> reverse -> 90.
//ex. 90+90 ->reverse = 09+09 -> do the tens place -> 0->carry over ->0+ 9+9 ->carry over->1+ result= 081 -> reverse -> 180.
#include <iostream>
using std::cin; using std::cout;
#include <cstring>
using std::string;
#include <algorithm>
using std::reverse;
string strA, strB, ResStr = "";
int carry = 0, sum;
int main() {
//get user input
cout << "Enter first number: "; cin >> strA;
cout << "Enter second number: "; cin >> strB; cout << "\n";
if (length_strA < length_strB){ swap(strA,strB); } //force stringA to be larger (or equal) in size
//Reversing both of the strings so that the ones, tens, etc. positions line up (the computer reads from left to right but we want it to read from right to left)
reverse(strA.begin(), strA.end()); cout << strA << "\n";
reverse(strB.begin(), strB.end()); cout << strB << "\n";
for (int i = 0; i < strB.length(); i++) {
sum = int(strA[i])-48 + int(strB[i])-48 + carry/10;
ResStr += char(sum % 10)+48;
carry = sum - sum%10;
}
// Add the remaining digits of the larger number
//start at strB.length, perform this operation until the amount of times reaches the value of strA.length
for (int i = strB.length(); i < strA.length(); i++) {
sum = int(strA[i])-48 + carry/10;;
ResStr += char(sum % 10)+48;
carry = sum - sum%10;
}
// Add remaining carry over value
if (carry != 0) { ResStr += char(carry)+48; }
// reverse the resulting string back, because we reversed it at the beginning
reverse(ResStr.begin(), ResStr.end());
//return user result
cout << "The result is: " << ResStr << "\n";
return 0; }
To answer why, it's because even once strB ended, it kept iterating through making a new sum in the first loop until strA ended. This meant it was reading null values for strB[i] and adding that to strA[i]+carry- which effectively shifted all the characters into the noisy-looking mess it was.
using tostring within a class.
#include <iostream>
#include <iomanip>
#include <string>
#include <cassert>
using namespace std;
Here is my class LargeInteger. Everything is correct in here Im quite sure.
class LargeInteger {
private:
int id;
int numDigits; // number of digits in LargeInt / size of alloc array
int* digits; // the digits of the LargeInt we are representing
public:
LargeInteger(int value);
~LargeInteger();
string tostring();
};
Constructor for class LargeInteger with a parameter int value.
LargeInteger::LargeInteger(int value)
{
// set this instance id
id = nextLargeIntegerId++;
numDigits = (int)log10((double)value) + 1;
// allocate an array of the right size
digits = new int[numDigits];
// iterate through the digits in value, putting them into our
// array of digits.
int digit;
for (int digitIndex = 0; digitIndex < numDigits; digitIndex++) {
// least significant digit
digit = value % 10;
digits[digitIndex] = digit;
// integer division to chop of least significant digit
value = value / 10;
}
}
Destructor
LargeInteger::~LargeInteger()
{
cout << " destructor entered, freeing my digits" << endl
<< " id = " << id << endl
//<< " value=" << tostring() // uncomment this after you implement tostring()
<< endl;
delete[] this->digits;
}
This is where I'm confused. What do I put here? I tried this but I dont know what to set intValue to in order to get the value I want.
string LargeInteger::tostring()
{
string intValue;
//intValue = ??
return intValue;
}
Main function
int main(int argc, char** argv)
{
// test constructors, destructors and tostring()
cout << "Testing Constructors, tostring() and destructor:" << endl;
cout << "-------------------------------------------------------------" << endl;
LargeInteger li1(3483);
cout << "li1 = " << li1.tostring() << endl;
return 0
}
Looking at the constructor, it appears, that the array of digits in your data structure is a sequence of decimal digits encoded as binary (value 0..9) in the reverse order.
So 1992 would be encoded as 2,9,9,1.
In order to make a digit printable, you need to add '0' to to it. You then need to iterate from end to begin and concatenate the printable version. Something like:
string LargeInteger::tostring()
{
string intValue;
for (int i=numDigits-1; i>=0; i--)
intValue += digits[i] + '0';
return intValue;
}
Online demo
Suggestion 1
Instead of storing the digits as an array of integers, you can very well use a string, since a string can contain any binary data including '\0'. This would avoid the memory allocation hassle.
If you go that way, you can also use iterators and algorithms and write your the same function as:
string LargeInteger::tostring()
{
string intValue(digits.size(),' ');
transform (digits.rbegin(), digits.rend(), intValue.begin(),
[](auto &x){ return x+'0'; }) ;
return intValue;
}
Online demo
Suggestion 2
Note that your constructor doesn't work with a negative number, since a log10() of a negative raises an exception.
This can be corrected with an absolute number:
numDigits = (int)log10(abs((double)value)) + 1;
However using modulo on a negative number gives a negative digit. This means that our tostring() would need to get changed to use the absolute value of each digit, and if any digit is negative, adding a negative sign at the beginning of the number (see online demo here).
A more convenient approach would be to have a sign flag at the class level (to say if the number is overall positive or negative), and change the constructor so to ensure that the digits are always positive.
You stored the digits array as reversed order of a integer number. Now in toString, just convert each digit to character in the reversed order and push it into a string result. Here is my solution
string LargeInteger::tostring()
{
string intValue;
//intValue = ??
for (int index = numDigits-1; index >= 0; index--)
{
intValue.push_back(digits[index]+'0');
}
return intValue;
}
I'm trying to write an algorithm for a larger project that will take two strings which are both large integers (only using 10 digit numbers for the sake of this demo) and add them together to produce a final string that accurately represents the sum of the two original strings. I realize there are potentially better ways to have gone about this from the beginning but I am supposed to specifically use strings of large integers as opposed to a long integer.
My thinking was to take the two original strings, reverse them so their ones position, tens position, and so on all line up properly for adding. Then one position at a time, convert the characters from the strings to single integers and add them together and then use that sum as the ones position or otherwise for the final string, which once completed will also be reversed back to the correct order of characters.
Where I'm running into trouble I think is in preparing for the event in which the two integers from the corresponding positions in their strings add to a sum greater than 9, and I would then have carry over some remainder to the next position. For example, if I had 7 and 5 in my ones positions that would add to 12, so I would keep the 2 and add 1 to the tens position once it looped back around for the tens position operation.
I'm not getting results that are in any way accurate and after spending a large amount of time stumbling over myself trying to rectify my algorithm, I am not sure what I need to do to fix this.
Hopefully my intended process is clear and someone will be able to point me in the right direction or correct some mistake I may have in my program.
Thanks in advance.
#include <iostream>
#include <cstdlib>
#include <string>
using namespace std;
int main()
{
string str1 = "1234567890", str2 = "2345678901"; //Two original strings of large integers
string rev_str1, rev_str2;
int int1 = 0, int2 = 0;
string final; //Final product string, sum of two original strings
int temp_int = 0, buffer_int, remainder = 0;
string temp_str = "", buffer_str;
char buffer[100] = {0};
cout << "str1 = " << str1 << endl;
cout << endl;
cout << "str2 = " << str2 << endl;
cout << endl;
rev_str1 = string(str1.rbegin(), str1.rend());
rev_str2 = string(str2.rbegin(), str2.rend());
for (int i = 0; i < 10; i++)
{
buffer_str = rev_str1.at(i);
int1 = atoi(buffer_str.c_str());
buffer_str = rev_str2.at(i);
int2 = atoi(buffer_str.c_str());
buffer_int += (int1 + int2 + remainder);
remainder = 0;
while (buffer_int > 9)
{
buffer_int -= 10;
remainder += 10;
}
temp_str = itoa(buffer_int, buffer, 10);
final += temp_str;
}
final = string(final.rbegin(), final.rend());
cout << "final = " << final << endl;
cout << endl;
}
Here's what I came up with. It is just for two summands; if you have more, you'll have to adapt things a bit, in particular with the carry, which can then be larger than 19, and the way the result string is allocated:
#include <iostream>
#include <string>
using namespace std;
int main()
{
// Two original strings of large integers
string str1 = "1234567890",
str2 = "2345678901234";
// Zero-padd str1 and str2 to the same length
size_t n = max(str1.size(), str2.size());
if (n > str1.size())
str1 = string(n-str1.size(), '0') + str1;
if (n > str2.size())
str2 = string(n-str2.size(), '0') + str2;
// Final product string, sum of two original strings.
// The sum of two integers has at most one digit more, for more inputs make
// below reverse_iterator a back_insert_iterator, then reverse the result
// and skip the removal of the padding.
string final(n+1, '0');
// The carry
char carry = 0;
// Iterators
string::const_reverse_iterator s1 = str1.rbegin(), e = str1.rend(),
s2 = str2.rbegin();
string::reverse_iterator f = final.rbegin();
// Conversion
for (; s1 != e; ++s1, ++s2, ++f)
{
// Bracketing to avoid overflow
char tmp = (*s1-'0')+(*s2-'0') + carry;
if (tmp > 9)
{
carry = 1;
tmp -= 10;
}
else
{
carry = 0;
}
*f = tmp + '0';
}
final[0] = carry + '0';
// Remove leading zeros from result
n = final.find_first_not_of("0");
if (n != string::npos)
{
final = final.substr(n);
}
cout << "str1 = " << str1 << endl
<< "str2 = " << str2 << endl
<< "final = " << final << endl;
}
Your problem is that you are carrying 10s instead of 1s. When you add 19 + 5, you get 4 in the units position and add an extra 1 in the 10s position. You wouldn't add an extra 10 in the 10s position.
You simply need to change this line: remainder += 10; to remainder += 1;.
Also, that while loop isn't necessary if you have more than two addends. As it is, when you are adding only two digits at a time, the largest addends you can have are 9 + 9, which carries only 1.
#include<iostream>
using namespace std;
main(){
int sum =0;
int a;
int reminder;
cout<<"Enter the Number :"<<endl;
cin>>a;
while(a>0){
reminder=a%10;
sum=r+sum;
a=a/10;`enter code here`
}
cout<<"Additon is :"<<sum<<endl;
}
I have to convert decimal numbers like 43.62 to binary. So i first wrote a basic program that converts 43 into binary. But I notice that my program prints out the binary number in reverse, so it prints 1 1 0 1 0 1 instead of 1 0 1 0 1 1. how can I fix this.
My Code:
#include <iostream>
using namespace std;
int main()
{
int number;
int remainder;
cout << "Enter a integer: ";
cin >> number;
while(number != 0)
{
remainder = number % 2;
cout << remainder << " ";
number /= 2;
}
int pause;
cin >> pause;
return 0;
}
Instead of sending each digit to cout, send them to an array. Then read the array out in reverse order. Or push them onto a stack, and then pop them back off the stack. Or...
Something of a sledgehammer to crack a nut, but here's a solution based on a recursive approach:
#include <iostream>
using namespace std;
void OutputDigit(int number)
{
if (number>0)
{
OutputDigit(number /= 2);
cout << number % 2 << " ";
}
}
int main()
{
OutputDigit(43);
return 0;
}
You can get the same output as you had before by simply moving the cout one line up!
Look at vector and think about how it could be useful to save the remainders instead of printing them right away.
Notice that you don't have to put things at the end of the vector. vector::insert lets you specify a position... could that be helpful?
Alternatively, the algorithm you created starts at the least significant digit. Is there a way to start from the most significant digit instead? If I have the number 42 (0101010), the most significant digit represents the 32s, and the 0 ahead of it represents the 64s. What happens if I subtract 32 from 42?
It would be easier to store the results and then print them backwards. Using recursion is also another possibility to do just that.
Most significant bit first:
const unsigned int BITS_PER_INT = CHAR_BIT * sizeof(int);
char bit_char = '0';
for (int i = BITS_PER_INT - 1;
i > 0;
--i)
{
bit_char = (value & (1 << i)) ? '1' : '0';
cout << bit_char << ' ';
}
cout << '\n';
cout.flush();
To print least significant bit first, change the direction of the for loop.
In C++, you can also use a bitset container to do this,
#include <bitset>
int i = 43;
std::bitset<sizeof(int)*CHAR_BIT> bin(i);
Just use string functions
string s ;
while(number != 0)
{
remainder = number % 2;
string c = remainder ? "1": "0";
s.insert(s.begin(),c.begin(),c.end());
number /= 2;
}
When you do such conversion by holding on to the remainder, the result will always be reverted. As suggested use bitwise &:
unsigned char bit = 0x80; // start from most significant bit
int number = 43;
while(bit)
{
if( bit & number ) // check if bit is on or off in your number
{
cout << "1";
}
else
{
cout << "0";
}
bit = bit >>1; // move to next bit
}
This example will start going through all your 8 bits of the number and check if the bit is on or off and print that accordingly.
Best option - Use C++ stringstream for formatting I/O
// Add the following headers
#include <sstream>
#include <algorithm>
// your function
stringstream ss;
// Use ss in your code instead of cout
string myString = ss.str();
std::reverse(myString.begin(),myString.end());
cout << myString;
So I'm trying to make a brute force string generator to match and compare strings in CUDA. Before I start trying to mess around with a language I don't know I wanted to get one working in C++. I currently have this code.
#include <iostream>
#include <string>
#include <cstdlib>
using namespace std;
int sLength = 0;
int count = 0;
int charReset = 0;
int stop = 0;
int maxValue = 0;
string inString = "";
static const char charSet[] = //define character set to draw from
"0123456789"
"!##$%^&*"
"abcdefghijklmnopqrstuvwxyz"
"ABCDEFGHIJKLMNOPQRSTUVWXYZ";
int stringLength = sizeof(charSet) - 1;
char genChars()
{
return charSet[count]; //Get character and send to genChars()
}
int main()
{
cout << "Length of string to match?" << endl;
cin >> sLength;
cout << "What string do you want to match?" << endl;
cin >> inString;
string sMatch(sLength, ' ');
while(true)
{
for (int y = 0; y < sLength; y++)
{
sMatch[y] = genChars(); //get the characters
cout << sMatch[y];
if (count == 74)
{
charReset + 1;
count = 0;
}
if (count == 2147000000)
{
count == 0;
maxValue++;
}
}
count++;
if (sMatch == inString) //check for string match
{
cout << endl;
cout << "It took " << count + (charReset * 74) + (maxValue*2147000000) << " randomly generated characters to match the strings." << endl;
cin >> stop;
}
cout << endl;
}
}
Now this code runs and compiles but it doesn't exactly do what I want it to. It will do 4 of the same character, EX. aaaa or 1111 and then go onto the next without incrementing like aaab or 1112. I've tried messing around with things like this
for (int x = 0; x < sLength; x++)
{
return charSet[count-sLength+x];
}
Which in my mind should work but to no avail.
You basically just need to increment a counter, than convert the count number to base (size of char array)
Here's an example which does normal numbers up to base 16.
http://www.daniweb.com/code/snippet217243.html
You should be able to replace
char NUMS[] = "0123456789ABCDEF";
with your set of characters and figure it out from there. This might not generate a large enough string using a uint, but you should be able to break it up into chunks from there.
Imagine your character array was "BAR", so you would want to convert to a base 3 number using your own symbols instead of 0 1 and 2.
What this does is perform a modulus to determine the character, then divide by the base until the number becomes zero. What you would do instead is repeat 'B' until your string length was reached instead of stopping when you hit zero.
Eg: A four character string generated from the number 13:
14%3 = 2, so it would push charSet[2] to the beginning of the empty string, "R";
Then it would divide by 3, which using integer math would = 4. 4%3 is again 1, so "A".
It would divide by 3 again, (1) 1%3 is 1, so "A".
It would divide by 3 again, (0) -- The example would stop here, but since we're generating a string we continue pushing 0 "B" until we reach 4 our 4 characters.
Final output: BAAR
For an approach which could generate much larger strings, you could use an array of ints the size of your string, (call it positions), initialize all the ints to zero and do something like this on each iteration:
i = 0;
positions[i]++;
while (positions[i] == base)
{
positions[i] = 0;
positions[++i]++;
}
Then you would go through the whole array, and build the string up using charSet[positions[i]] to determine what each character is.