I found this question in the book where it asks us to transfer an Int to a string. Without using stoi library
so for example if x = 10, s="10"
the code should handle negative numbers.
I found this solution in the book. I typed it in my compiler however it is giving the string of the first number only
so if x= 45, it is giving "4"
I do not understand this line s = '0' + x%10; to be able to fix the code.
why is he adding '0' to the string. What is the best solution.
here is the code: I added comments to the parts I understand
#include<iostream>
#include<string>
using namespace std;
void IntToString(int x);
int main()
{
int num;
cout << "Please enter a number" << endl;
cin >> num;
IntToString(num);
}
void IntToString(int x)
{
bool isNegative = false;
if(x < 0) //if its negative make boolean true
{
x = -x;
isNegative = true;
}
string s;
do
{
s = '0' + x%10; //modulus for getting the last number
x = x/10; //shorten the number
}while(x);
reverse(s.begin(), s.end()); //reverse the string since it starts from end
if(isNegative)
s = '-' + s;
cout << s << endl;
}
s = '0' + x%10;
will grabs the last digit from x%10 and add ASCII of 0 i.e. 48, giving the ASCII of desired last digit, which get copy assigned to string s using its assignment operator.
And btw, you need :
s += '0' + x%10;
~~ // += operator
The problem with the do ... while loop is that you just extract the last digit of the changed x only to replace it with the second last digit and so on, until you get the first digit of x stored in s.
There is no effect of reverse(s.begin(), s.end()) since s practically holds only one character.
Also, we add '0' to s because s initially stores the integer value of the number, and adding '0' converts it into its ASCII form.
Example:
void IntToString(int x)
{
bool isNegative = false;
if(x < 0)
{
x = -x;
isNegative = true;
}
string s;
do
{
//The below code appends the new number at the beginning of s.
s = ('0' + x%10) + s; //modulus for getting the last number
x = x/10; //shorten the number
}while(x);
if(isNegative)
main_string = '-' + main_string;
cout << main_string << endl;
}
Related
I want to write a program for reversing a number. For reversing a number like 2300 to 32 so that the ending zeros are not printed, I found this method:
#include<iostream>
using namespace std;
int main()
{
int l;
cin>>l;
bool leading = true;
while (l>0)
{
if ((l%10==0)&& (leading==true))
{
l /= 10;
leading = false; // prints 032 as output
continue;
}
// leading = false; this prints correct 32
cout<<l%10;
l /= 10;
}
return 0;
}
The instruction of assigning boolean leading false inside the if statement is not giving a valid answer, but I suppose assigning it false should give 32 as output whether we give it outside or inside if statement as its purpose is just to make it false once you get the last digit to be a non zero.
Please tell the reason of difference in outputs.
The reason for the difference in output is because when you make leading = false inside the if statement, you are making it false right after encountering the first zero. When you encounter the remaining zeroes, leading will be false and you will be printing it.
When you make leading = false outside the if statement, you are basically waiting till you encounter all zeroes before making it false.
If you are looking to reverse a number, this is the well known logic to do so:
int reverse(int n)
{
int r; //remainder
int rev = 0; //reversed number
while(n != 0)
{
r = n%10;
rev = rev*10 + r;
n /= 10;
}
return rev;
}
EDIT:
The above code snippet is fine if you just want to understand the logic to reverse a number. But if you want to implement the logic anywhere you have to make sure you handle integer overflow problems (the reversed number could be too big to be stored in an integer!!).
The following code will take care of integer overflow:
int reverse(int n)
{
int r; //remainder
int rev = 0; //reversed number
while(n != 0)
{
r = n%10;
if(INT_MAX/10 < rev)
{
cout << "Reversed number too big for an int.";
break;
}
else if(INT_MAX-r < rev*10)
{
cout << "Reversed number too big for an int.";
break;
}
rev = rev*10 + r;
n /= 10;
}
if(n != 0)
{
//could not reverse number
//take appropriate action
}
return rev;
}
First, rewrite without continue to make the flow clearer,
while (l > 0)
{
if ((l % 10 == 0) && (leading == true))
{
l /= 10;
leading = false; // prints 032 as output
}
else
{
// leading = false; this prints correct 32
cout << l % 10;
l /= 10;
}
}
and move the division common to both branches out of the conditional,
while (l > 0)
{
if ((l % 10 == 0) && (leading == true))
{
leading = false; // prints 032 as output
}
else
{
// leading = false; this prints correct 32
cout << l % 10;
}
l /= 10;
}
and now you see that the only difference between the two is the condition under which the assignment leading = false happens.
The correct version says, "If this digit is non-zero or a non-leading zero, remember that the next digit is not a leading zero, and print this digit. Then divide."
Your broken version says, "If this is a leading zero, the next digit is not a leading zero." which is pretty obviously not the case.
Just try this ,
#include <iostream>
using namespace std;
int main() {
int n, reversedNumber = 0, remainder;
cout << "Enter an integer: ";
cin >> n;
while(n != 0) {
remainder = n%10;
reversedNumber = reversedNumber*10 + remainder;
n /= 10;
}
cout << "Reversed Number = " << reversedNumber;
return 0;
}
Working for me...
When reversing digits of numbers or generally when working with digits and the actual
value does not matter then treating the number as an array of digits is simpler than working with the whole int. How to treat a number as an array of digits conveniently? std::string:
#include <iostream>
#include <string>
#include <sstream>
int reverse_number(int x) {
std::string xs = std::to_string(x);
std::string revx{ xs.rbegin(),xs.rend()};
std::stringstream ss{revx};
int result;
ss >> result;
return result;
}
int main() {
std::cout << reverse_number(123) << "\n";
std::cout << reverse_number(1230) << "\n";
}
std::to_string converts the int to a std::string. std::string revx{ xs.rbegin(),xs.rend()}; constructs the reversed string by using reverse iterators, and eventually a stringstream can be used to parse the number. Output of the above is:
321
321
So I'm thinking if I could use strings to check if a number is a palindrome, but I don't really know how strings, arrays and that stuff works and I'm not arriving at anything.
I've done this using math, but I wonder if it would be easier to use arrays or strings.
n = num;
while (num > 0)
{
dig = num % 10;
rev = rev * 10 + dig;
num = num / 10;
}
// If (n == rev) the number is a palindrome
this is the code made with math
So it works yeah, but I'm curious
It is much easier if you use correctly the index of the array in the loop:
// Num is the number to check
// Supposing we are using namespace std
string numString = to_string(num);
bool palindrome = true;
int index = 0;
while(index < numString.size() && palindrome){
palindrome = numString[index] == numString[numString.size() - index - 1];
index++;
}
if(palindrome)
cout << num << " is a palindrome \n"; // line break included
else
cout << num << " is not a palindrome \n"; // line break included
Use this code:-
//num is the Number to check
//Converting int to String
ostringstream ss;
ss<<num;
string snum = ss.str();
string fromfront="", fromback="";
fromfront = snum;
string character;
for(int i=snum.length();i>0;i--)
{
if(i>0)
character = snum.substr(i-1, 1);
fromback+=character;
}
if(fromfront==fromback)
cout<<endl<<"It is a palindrome.";
else
cout<<endl<<"It is not a palindrome.";
Can you please help me buy showing how to create substraction of two long numbers?
I found this code on the internet:
#include<iostream>
#include<string>
using namespace std;
int main(void)
{
// the two "numbers" to be added. Make them as long as you like.
string numStr1;
string numStr2;
cout << "Enter 1st number: "; cin >> numStr1;
cout << "Enter 2nd number: "; cin >> numStr2;
// keeping track of which string is longest using references
string& rLongStr = numStr1.length() > numStr2.length() ? numStr1 : numStr2;
string& rShortStr = numStr1.length() <= numStr2.length() ? numStr1 : numStr2;
// initialize the sum with the long string but with space for a final carry at the beginning
string numStrSum = '0' + rLongStr;// the '0' in case of a final carry
// must go through the strings backwards since the least
// significant digit is at the end, not the beginning.
string::reverse_iterator r_itShort, r_itSum;
r_itShort = rShortStr.rbegin();// point to last "digit" in the short string
r_itSum = numStrSum.rbegin();// same for sum string
// add the "digits" one by one from end to beginning of the short string
while( r_itShort != rShortStr.rend() )
{
*r_itSum += *r_itShort - '0';// "add" the digits
if( *r_itSum > '9' )// must carry a one to the next "digit"
{
*(r_itSum + 1) += 1;
*r_itSum -= 10;
}
++r_itShort;// move back 1 character
++r_itSum;// in each string
}
if( numStrSum.at(0) == '0' )// if 1st character is stiil '0'
numStrSum.erase(0,1);// erase it
// output result
cout << numStrSum;
cout << endl;
return 0;
}
So, I could not make substraction of this two numbers. I tried smt like that:
while( r_itShort != rShortStr.rend() )
{
*r_itSum -= *r_itShort + '0';
if( *r_itSum > '9' )
{
*(r_itSum + 1) -= 1;
*r_itSum += 10;
}
--r_itShort;
--r_itSum;
}
if( numStrSum.at(0) == '0' )
numStrSum.erase(0,1);
But it shows me the same. Can you please help me and tell what am I doing wrong?
Thank You!
You can both input and output float / double / integer types to the iostream with cin/cout so string parsing wouldn't be a problem. You can just get them as double type.
If you really want to get these numbers as strings, you could use atof to convert them to floats. Then simply calculate what you need and either use std::to_string or just print directly.
If i want an integer input, but if it contains any digits 2 or 3 in it, it will be rejected.
For example entering 23564 will be invalid.
I was thinking of using do-while loops to solve this, but how do I get it to read the individual digits.
Have a look here:
#include <iostream>
using namespace std;
int main() {
int n,num,flag;
do{
cout<<"Enter number";
cin>>n;
num = n;
flag = 0;
while(num>0)
{
if(num%10 == 2 || num%10 ==3)
{
flag = 1;
break;
}
num = num/10;
}
}while(flag==1);
return 0;
}
If you don't care much about performance, you can convert the integer into a string and look for the digits. This is slower than extracting the last digit and comparing it though.
std::string str = std::to_string(number);
auto found2 = str.find('2');
auto found3 = str.find('3');
//number is valid if it doesn't have a 2 or a 3
bool isValid = found2 == std::string::npos && found3 == std::string::npos;
You can get the last digit of a number with something like:
unsigned int number = 23456;
unsigned int digit = number % 10; // gives 6
You can further "shift" all digits right with:
number = number / 10; // gives 2345
In other words, yes, you can do it using the method you propose:
bool has2Or3(unsigned int number) {
// Do until no more digits left.
while (number != 0) {
// Get last digit, return true if 2 or 3.
int digit = number % 10;
if ((digit == 2) || (digit == 3)) {
return true;
}
// Prepare to get next digit.
number = number / 10;
}
// If NO digits were 2 or 3, return false.
return false;
}
Another way would be to simply convert it to a string and use the string functions to see if it contains a specific digit, something such as:
bool has2Or3(unsigned int number) {
// Get number as string (via string stream).
std::stringstream ss;
ss << number;
std::string s = ss.str();
// If contains 2, return true, else continue.
if (s.find("2") != std::string::npos)
return true;
// If contains 3, return true, else return false.
return (s.find("3") != std::string::npos);
}
Instead of reading the input directly into an integer type, read it into a std::string. Then it's simple to check for unwanted digits; if the string passes the test, convert it to an integer:
int get_value() {
std::string bad = "23";
std::string input = "2"; // start with bad input
while (std::find_first_of(input.begin(), input.end(),
bad.begin(), bad.end()) != input.end()) {
std::cout << "Gimme a number: ";
std::cin >> input;
}
return std::stoi(input);
}
This little exercise is meant to get a string from the user that could be decimal, hexadecimal, or octal. 1st I need to identify which kind of number the string is. 2nd I need to convert that number to int and display the number in its proper format, eg:
cout <<(dec,hex,oct, etc)<< number;
Here's what I came up with. I'd like a simpler, cleaner way to write this.
string number = "";
cin >> number;
string prefix = "dec";
char zero = '0';
char hex_prefix = 'x';
string temp = "";
int value = 0;
for(int i =0; i<number.size();++i)
{
if(number[0] == zero)//must be octal or hex
{
if (number[0] == zero && number[1] == hex_prefix ) //is hex
{
prefix = "hex";
for(int i = 0; i < (number.size() - 2); ++i)
{
temp[i] = number[i+2];
}
value = atoi(temp.c_str());
}
//... code continues to deal with octal and decimal
You are checking number[0] twice, that's the first most obvious problem.
The inner if already checks both number[0] and number[1], I don't see the point of the outer one.
The outermost loop is also hard to understand, do you expect non-hex data before the number, or what? Your question could be clearer on how the expected input string looks.
I think the cleanest would be to ignore this, and push it into existing (library) code that can parse integers in any base. In C I would recommend strtoul(), you can of course use that in C++ too.
You have two inner loop with same value integer this could be a conflict problem in your code. I suggest you look at the isdigit and islower methods in the c++ library and take advantage of those methods to accomplish your task. isdigit & islower
Good Luck
This is prints the number after deleting the hex prefix, otherwise return 0:
#include<iostream>
#include<cmath>
#include<stdlib.h>
using namespace std;
int main(){
string number = "";
cin >> number;
string prefix = "dec";
char zero = '0';
char hex_prefix = 'x';
string temp = "";
int value = 0;
if (number.size()>=2 && number[0] == zero && number[1] == hex_prefix ) //is hex
{
prefix = "hex";
for(int i = 0; i < (number.size() - 2); ++i)
{
temp[i] = number[i+2];
}
value = atoi(temp.c_str());
}
cout<<value;
return 0;
}
This partial solution that I found is as clean as possible, but it doesn't report the format of the integer:
int string_to_int(std::string str)
{
std::istringstream stream;
stream.unsetf(std::ios_base::dec);
int result;
if (stream >> result)
return result;
else
throw std::runtime_error("blah");
}
...
cout << string_to_int("55") << '\n'; // prints 55
cout << string_to_int("0x37") << '\n'; // prints 55
The point here is stream.unsetf(std::ios_base::dec) - it unsets the "decimal" flag that is set by default. This format flag tells iostreams to expect a decimal integer. If it is not set, iostreams expect the integer in any base.