using tostring within a class. C++ - c++

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;
}

Related

How to calculate the smallest number possible based on digits (0-9) not used in a user inputted integer?

I am trying to write a code that will accept an integer input and then calculate the smallest number possible using digits not found in the inputted integer. The possible digits would be 0-9, however, 0 can not be the leading value in the output.
For example, if the user enters:
6789
the the program would output:
102345
How can I solve this?
The lowest number possible from any set of digits (ignoring, for now, the issue of the zero) comprises those digits in order; thus, from the digits 2, 1, 6 and 3, the lowest number is 1236.
So, we can start of with a list of all digits, in order, then run through the digits in the given input number (after we have converted that to a string), removing each of those digits from our list (if it's still in it). If we end up with a list whose first element is zero, we simply swap that with the second digit.
Here's a possible implementation:
#include <iostream>
#include <string>
#include <algorithm>
int main()
{
std::string numbs = "0123456789";
int input;
std::cout << "Enter a number: ";
std::cin >> input;
std::string check = std::to_string(input); // Convert our input to a string
for (auto digit : check) { // Remove each digit in that from our list...
size_t p;
if ((p = numbs.find(digit)) != std::string::npos) numbs.erase(p, 1);
}
// A basic error check that at least one digit remains ...
if (numbs.length() == 0) {
std::cout << "No digit left with which to make a number!\n";
return 1;
}
// Swap first two digits if first is zero and there is at least one other ...
if (numbs[0] == '0' && numbs.length() > 1) std::swap(numbs[0], numbs[1]);
int answer = std::stoi(numbs);
std::cout << answer << std::endl;
return 0;
}
In this example, I have used the std::string container class from the Standard Library; in many ways, that acts like an array of characters; however, if you want to use actual arrays, you could readily adapt the shown code to use them.
Yet another implementation. Same algorithm as from Adrian . . .
#include <iostream>
#include <string>
#include <algorithm>
#include <cctype>
int main() {
// Basic string
std::string allDigits{ "0123456789" };
// Get input. Digits only
if (std::string input{}; std::getline(std::cin, input) and std::all_of(input.begin(), input.end(), std::isdigit)) {
// Erase from the allDigits string the characters that are in the input string
std::erase_if(allDigits, [&](const char d) { return std::any_of(input.begin(), input.end(), [d](const char c) { return c == d; }); });
// Take care of leading 0
if ((allDigits.length() > 1) and allDigits.front() == '0') std::swap(allDigits[0], allDigits[1]);
// Show result
std::cout << allDigits << '\n';
}
else std::cerr << "\n*** Error: Invalid input\n\n";
}

Adding to very large numbers using stack

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;
}

Convert argv[1] into an int and it's digits into an array

I've been trying to create a program in C++ that tries to accomplish this pseudocode:
get argv[1] into int
get int’s digits into array[int length]
for int i = array length; i >= 0;
gen random number into check
if check == array[i]
i
say Number i was check
end if
And I think the part I'm really struggling with is the
get argv[1] into int
get int’s digits into array[int length]
part. In my full code there isn't even an attempt because nothing I've tried works. The error I get the most is that the code compiles, but everytime it tries to cout << "Number 1:" << number I just get Number 1: 0 no matter the actual number I enter. And when 0 == 0 the code doesn't even notice.
My broken propably convention-breaking code follows:
#include <iostream>
#include <string>
int main (int argc, char **argv) {
if (argc == 1 || argc == 3) {
std::cout << "Argument count does not match (one argument expected)\n";
return(-1);
}
std::cout << "Input: " << argv[1] << "\n";
const char* text = argv[1];
int number = atoi(text);
int check = rand() % 10;
std::cout << "Check 1: " << check << "\nNumber 1: " << number << "\n";
if (check == array[i]) {
i++;
std::cout << "Success! Number " << i << " was " << check << ".\n";
}
}
}
TL;DR: My "sort of" number cracker doesn't want to put argv1 into an int with the int's digits being later put into an array.
Feel free to make me feel stupid. Hope the question isn't too specific. I'll expand on details as asked.
EDIT: This is an earlier attempt at conversion:
int array[];
for (int i = strlen(text); i >= 0; i--) {
array[i] = number % 10;
number /= 10;
}
EDIT2: So many responses, no solutions. Thank you for trying to explain this newbie so many things at once. BTW: Git
The earlier attempt is almost good: it's just that you have to actually allocate space for the array, like this:
int array[strlen(text)];
if your compiler supports variable-length arrays as an extension, and
std::vector<int> array;
array.resize(strlen(text));
if you want to stick with standard C++ and follow some good practices.
However, if you want to be tricky, you don't even need to convert the argument to a number:
if (argv[1][i] == check % 10 + '0')
does the trick too. All in all, the complete program would look like this:
#include <iostream>
#include <cstdlib>
int main(int argc, char *argv[])
{
int check = std::rand();
std::cout << check << std::endl;
char *p = argv[1] + strlen(argv[1]);
while (p - argv[1] >= 0) {
if (*--p == '0' + check % 10)
std::cout << "guessed " << p - argv[1] << "th digit" << std::endl;
check /= 10;
}
return 0;
}
Your code is relatively close to being right. You are struggling with the declaration of the array (you must specify the size for it). 32-bit int cannot have more than ten digits, so declaring
int array[10];
should be sufficient.
Before converting the number to an array of digits, check if it is negative, and flip its sign if it is negative:
if (number < 0) {
number = -number;
}
Otherwise, your number%10 trick is not going to work.
When you do the conversion, count how many digits you have. Put the result in actualCount variable: chances are that you are not going to use up all the digits in your array, so
int check = rand() % 10; // 10 is the max, not the actual digit count
should be
int check = rand() % actualCount;
Your argument checking also needs improvement: think what would happen if the user passes five parameters? If you expect exactly one argument, you should write
if (argc != 2) {
std::cout << "Argument count does not match (one argument expected)\n";
return(-1);
}
In order to extract only one digit at a time from a number you have a couple of choices.
For convenience you can use a std::string, inserting the original string (argv[1]) in it, then extracting one char at a time:
#include <string>
...
// put the input in a string
std::string text = argv[1];
for (unsigned i = 0; i < text.size(); i++)
{
// extract only one char, a digit
char ch = text.at(i);
// convert that char in a number
int n = ::atoi(& ch);
// use n
...
}
If you don't want to use std::string, you can always use a c-like array (argv[1] itself):
#include <cstring>
...
for (unsigned i = 0; i < strlen(argv[1]); i++)
{
// extract only one char, a digit
char digit = argv[1][i];
// convert that char in a number
int num = ::atoi(& digit);
// use n
...
}

How do I reverse the output of a program?

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;

Brute Force Character Generation in C++

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.