I am trying to put an integer in to string using the following code:
int x = 42;
string num;
bool negative = false;
if(x < 0)
{
negative = true;
x = x * -1;
}
while(x > 0)
{
num.push_back(x % 10);
x = x / 10;
}
But when I try to output the string, it comes up with the wired character. Could you please help what's happening in this code??
Edited:
ps. I want to do this in kind manual way. Means I don't want to use to_string
There would be weird characters, because when you push_back(), the integer is converted (or rather interpreted) into its corresponding ASCII character, and then pushed back into the string.
The way forward is to convert the integer to a character by adding a '0' to the integer value.
while(x > 0)
{
num.push_back((x % 10) + '0'); //Adding '0' converts the number into
//its corresponding ASCII value.
x = x / 10;
}
The reason to add a '0' to the integer?
The ASCII value of 0 is 48, 1 is 49, 2 is 50 and so on... Hence, what we basically do here is to add 48 (The ASCII value of 0) to the corresponding integer to make it equal to its ASCII equivalent. Incidentally, '0' is equal to 48 because it is the ASCII value of the 0 character.
Use std::to_string with string::append:
while (x > 0)
{
num.append(std::to_string(x % 10));
x = x / 10;
}
using push_back forces you to do more work.
To convert the integer you can use:
Character manipulation: shifting/adding the ASCII representation by '0', thereby making anint value into char value.
Type casting new_type(old_type), there are some additional types of casting.
To expand the length of a string you can use:
String member functions like: push_back(value), append(append).
Concatenation operator like: str += value;
A possible implementation is:
while(x > 0)
{
num+=((x % 10) + '0');
x = x / 10;
}
Related
This question already has answers here:
Why does subtracting '0' in C result in the number that the char is representing?
(8 answers)
Closed 1 year ago.
Given the following code.
this problem is Leet Code 415.
string addStrings(string num1, string num2) {
string res;
int sum = 0;
int i = num1.size() - 1;
int j = num2.size() - 1;
while(i >= 0 && j >= 0)
{
sum += (num1[i--] - '0') + (num2[j--] - '0'); // this problem point
res.push_back(char(sum%10 + '0'));
sum = sum/10;
}
while(i >= 0)
{
sum += (num1[i--] - '0');
res.push_back(char(sum%10 + '0'));
sum = sum/10;
}
while(j >= 0)
{
sum += (num2[j--] - '0');
res.push_back(char(sum%10 + '0'));
sum = sum/10;
}
if(sum > 0)
res.push_back(char(sum%10 + '0'));
reverse(res.begin(), res.end());
return res;
}
I don't understand the process converting string to int.
Why is it a int when I subtract '0' from string?
If it doesn't change int, how is it possible to operate on strings?
In c++ characters can be implicitly cast to integers using their ASCII codes. I don't really want to spoil the fun of solving the given problem so i'll just provide a hint here:
Given a single digit number '2' and '4' with an ASCII code of 50 and 52 (decimal) respectively, subtracting '0' with an ASCII code of 48 from both numbers, you get the actual numerical values of the characters (50-48 = 2) and so on.
Have fun coding!
So the way ascii works is that consecutive numbers are following each other. If a string of characters only contain digits, you can get those digits by subtracting the value '0' from them. In ascii '0' = 0x30, '1' = 0x31 etc..
In your code num[i--] - '0' just checks "how far" you are from '0' in the ascii table, giving the correct digit if it is indeed a digit.
Also you don't convert string to anything (at least on the specific line). You access an element, which is a char that is an integer type in c++.
I'm practicing a coding problem on "Check if the frequency of all the digits in a number is same"
#include<bits/stdc++.h>
using namespace std;
// returns true if the number
// passed as the argument
// is a balanced number.
bool isNumBalanced(int N)
{
string st = to_string(N);
bool isBalanced = true;
// frequency array to store
// the frequencies of all
// the digits of the number
int freq[10] = {0};
int i = 0;
int n = st.size();
for (i = 0; i < n; i++)
// store the frequency of
// the current digit
freq[st[i] - '0']++;
for (i = 0; i < 9; i++)
{
// if freq[i] is not
// equal to freq[i + 1] at
// any index 'i' then set
// isBalanced to false
if (freq[i] != freq[i + 1])
isBalanced = false;
}
// return true if
// the string is balanced
if (isBalanced)
return true;
else
return false;
}
// Driver code
int main()
{
int N = 1234567890;
bool flag = isNumBalanced(N);
if (flag)
cout << "YES";
else
cout << "NO";
}
but I can't understand this code:
// store the frequency of
// the current digit
freq[st[i] - '0']++;
How this part actually working and storing frequency?
And instead of this line, what else I can write?
st is a string and thus, a sequence of chars. st[i] is the ith char in this string.
Chars are actually positive integers between 0 and 256, so you can use them with mathematical operations, such as -. These integers are assigned to characters according to the ASCII alphabet. For example: The char 0 is assigned to 48 and the char 7 to 55 (Note: in the following, I use x to denote the character).
Their order makes it possible that mathematical operations are sensible as follows: The char 7 and the char 0 are exactly 7 numbers apart, so 0 + 7 = 48 + 7 = 55 = 7. So: 7 - 0 = 7.
So, you get the position in the freq array according to the number, i.e., the position 0 for 0 or position 7 for 7. The ++ operator increments that value in-place.
This line is several things condensed into one expression
freq[st[i] - '0']++;
The individual part are rather simple and in total it also isn't too difficult:
st[i] - '0' - character digits do not map 1 to 1 to integers. There is an offset. The integer value of '1' is 1 + '0', '2' is 2 + '0'. Hence to get the integer from the digit you need to subtract '0'.
freq[ ... ] - accesses the element of the array. Element at index i stores frequency of digit i.
()++ - increments that frequency by one.
Subtracting the '0' character from the single string character results in the actual number you're looking for. This gives you the number whose frequency you are tracking in your code. This works because of the way characters are stored as ASCII values. Check out the table below. Say that the integer value N that is passed in is 1221. The first value observed in this example is '1' which corresponds to an ASCII value of 49. The ASCII value of '0' is 48. Subtracting the two: 49 - 48 = 1. This allows you to access each integer value individually as part of the array that was the result of the transformation of an 'int' value into a string.
ASCII Table
The code of
for (i = 0; i < n; i++)
// store the frequency of
// the current digit
freq[st[i] - '0']++;
traverses the string and for each item, it subtracts '0', which has a value of 48, because character code 48 represents 0, character code 49 represents 1 and so on.
This code however is superfluos, wastes memory in storing a string and wastes time converting a number to a string. This is better:
bool isNumBalanced(int N)
{
//We create an array of 10 for each digit
int digits[10];
//Initialize the difits
for (int i = 0; i < 10; i++) digits[i] = 0;
//If the input is 0, then we have a trivial case
if (N == 0) return true;
//We loop the digits
do {
//N % 10 is the last digit
//We increment the frequency of that digit
digits[N % 10]++;
} while ((N /= 10) != 0); //We don't stop until we reach the trivial case, see above
//Using the transitivity of equality, we compare all values to the first
//We return false upon the first difference
for (int j = 1; j < 10; j++)
if (digits[0] != digits[j]) return false;
//Otherwise we return true
return true;
}
For those who don't understand it.
int arr[5]={0} // it stores 0 in all places
for(int i=0;i<5;i++){
arr[i]++;
} // Now the array is [1 1 1 1 1]
what happened here is first i=0 then arr[0]++ "here arr[0] value was 0, ++, it increment 0 to 1"
now arr[0] value is 1.
Now `
let
st="1221";
for (i = 0; i < 4; i++) {
freq[st[i] - '0']++;
for i=0, the freq location is : freq[49-48]++ = freq[1]++ means value of freq[1] is 1
for i=1, the freq location is : freq[50-48]++ = freq[2]++ means value of freq[2] is 1
for i=2, the freq location is : freq[50-48]++ = freq[2]++ means value of freq[2] is 2
for i=3, the freq location is : freq[49-48]++ = freq[1]++ means value of freq[1] is 2
ASCII value of '0' is 48
ASCII value of '1' is 49
ASCII value of '2'is 50
I have a string which will be exactly consist of numbers between 1-30 and one of 'R','T'or'M' char. Let me illustrate it by some examples.
string a="15T","1R","12M","24T","24M" ... // they are all valid for my string
Now I need to have a hash function which gives me a unique hash value for every input string. Since my input have a finite set I think it is possible.
Is there anyone who can tell what kind of hash function could I define ?
By the way, I'll create my hash table using vector therefore I guess size is not an important issue but I'll define 10000 as an upper bound. I mean I assume I can not have more than 10000 such a string
Thanks in advance.
Just have a large enough integer type and put the (maximal) three characters into the integer:
std::size_t hash(const char* s) {
std::size_t result = 0;
while(*s) {
result <<= 8;
result |= *s++;
}
return result;
}
You could define an algebraic function:
result = string[0] * 0x010000
+ string[1] * 0x000100
+ string[2];
Basically, each character fits into an uint8_t, which has a range of 256. So each column is a power of 256.
Yes, there are big gaps, but this insures a unique hash.
You could compress the gaps by using various "powers" for the different character columns.
Given "15T":
result = (string[0] - '0') * 10 // 10 == number of digits in the 2nd column
+ (string[1] - '0') * 3; // 3 == number of choices in 1st column.
switch (string[2])
{
case 'T' : result += 0; break;
case 'M' : result += 1; break;
case 'R' : result += 2; break;
}
It's a number / counting system where each column has a different number of digits.
Something along the line of:
unsigned myhash(const char * str)
{
int n = 0;
// Parse the number part
for ( ; *str >= '0' && *str <= '9'; ++str)
n = n * 10 + (*str - '0');
int c = *str == 'R' ? 0 :
*str == 'T' ? 1 :
*str == 'M' ? 2 :
3;
// Check for invalid strings
if ( c == 3 || n <= 0 || n > 30 || *(++str) != 0 )
{
// Some error or anything
// (Or replace the if condition with an assert)
throw std::runtime_error("Invalid string");
}
// Since 0 <= c < 3 and 0 <= (n-1) < 30
// There are only 90 possible values
return c * 30 + (n-1);
}
In my experience whenever you have to deal with something like this it is often better to do the opposite, that is work with integers and have a function to perform the opposite conversion if necessary.
You can rebuild the original string with:
int n = hash % 30 + 1;
int c = hash / 30; // 0 is 'R', 1 is 'T', 2 is 'M'
Is there any technique for finding the reverse when there are zeros at the end.
While following the algorithm of %10 technique the result is 52. And the 0's are missing.
I have got the reverse by just printing the reminders (with 0's). But I am not satisfied as I wish to display the answer as the value in a variable.
Kindly tell me is there any technique to store a value 005 to a variable and also to display 005 (please don't use String or Character or array).
Numbers are stored as binary 0 and 1 and so they always have leading 0's which are chopped off. e.g. a 64-bit integer has 64-bit bits, always and when it is printed these leading 0's are dropped.
You need to know how many leading zeros you want to keep and only use that many when you print. i.e. you can record how many leading zeros there were in a normal number without encoding it e.g. by adding a 1 at the start. i.e. 0052 is recorded as 10052 and you skip the first digit when you print.
If you need to store a single value you can do the following. I use do/while so that 0 becomes 10 and is printed as 0. The number 0 is the one place where not all leading zeros are dropped (as it would be empty otherwise)
This appears to be the solution you want and it should be basically the same in C or C++
static long reverse(long num) {
long rev = 1; // the 1 marks the start of the number.
do {
rev = rev * 10 + num % 10;
num /= 10;
} while(num != 0);
return rev;
}
// make the reversed number printable.
static String toStringReversed(long num) {
return Long.toString(num).substring(1);
}
long l = reverse(2500); // l = 10052
An alternative is to print the digits as you go and thus not need to store it.
e.g.
static void printReverse(long l) {
do {
System.out.print(l % 10);
l /= 10;
} while(l != 0);
}
or you can have the input record the number of digits.
static void printReverse(long l, int digits) {
for(int i = 0; i < digits; i++) {
System.out.print(l % 10);
l /= 10;
}
}
// prints leading zero backwards as well
printReverse(2500, 6); // original number is 002500
prints
005200
You cannot represent an integer with leading zeros as a single integer variable, that information is simply not part of the way bits are allocated in an integer. You must use something larger, i.e. a string or an array of individual (small integer) digits.
You can't store them in a simple integer variable because in binary format
00101 is same as 000101 which is same as 101 which only results into 5. The convertion between a decimal number and binary numbers don't consider leading zeroes so it is not possible to store leading zeroes with the same integer variable.
You can print it but you can't store the leading zeroes unless you use array of ints...
int num = 500;
while(num > 0)
{
System.out.print(num%10);
num = num/10;
}
Alternatively you can store the count of leading zeroes as a separate entity and combine them when ever you need to use. As shown below.
int num = 12030;
boolean leading=true;
int leadingCounter = 0;
int rev = 0;
while(num > 0)
{
int r = num%10;
if(r == 0 && leading == true)
leadingCounter++;
else
leading = false;
rev = rev*10 + r;
num = num/10;
}
for(int i = 1; i <= leadingCounter ; i++)
System.out.print("0");
System.out.println(rev);
I think the accepted answer is a good one, in that it both refutes the parts of the question that are wrong and also offers a solution that will work. However, the code there is all Java, and it doesn't expose the prettiest API. Here's a C++ version that based on the code from the accepted answer.
(Ha ha for all my talk, my answer didn't reverse the string! Best day ever!)
After going back to school and getting a degree, I came up with this answer: it has the makes the somewhat dubious claim of "not using strings" or converting any values to string. Can't avoid characters, of course, since we are printing the value in the end.
#include <ostream>
#include <iostream>
class ReverseLong {
public:
ReverseLong(long value) {
long num = value;
bool leading = true;
this->value = 0;
this->leading_zeros = 0;
while (num != 0) {
int digit = num % 10;
num = num / 10;
if (leading && digit == 0) {
this->leading_zeros += 1;
} else {
this->value = this->value * 10 + digit;
leading = false;
}
}
};
friend std::ostream & operator<<(std::ostream& out, ReverseLong const & r);
private:
long value;
int leading_zeros;
};
std::ostream & operator<<(std::ostream& out, ReverseLong const & r) {
for (int i =0; i < r.leading_zeros; i++) {
out << 0;
}
out << r.value;
return out;
};
int main () {
ReverseLong f = ReverseLong(2500); // also works with numbers like "0"!
std::cout << f << std::endl; / prints 0052
};
I came across a programming question of which I knew only a part of the answer.
int f( char *p )
{
int n = 0 ;
while ( *p != 0 )
n = 10*n + *p++ - '0' ;
return n ;
}
This is what I think the program is doing.
p is a pointer and the while loop is DE-refrencing the values of the pointer until it equals 0. However I don't understand the n assignment line, what is '0' doing? I am assuming the value of p is initially negative, that is the only way it will reach 0 after the increment.
You are confusing the number zero (none, nothing) with the character 0 (a circle, possibly with a slash through it). Notice that zero is in tick marks, so it's the character "0", not the number zero.
'0' - '0' = 0
'1' - '0' = 1
'2' - '0' = 2
...
So by subtracting the character zero from a digit, you get the number that corresponds to that digit.
So, say you have this sequence of digits: '4', '2', '1'. How do you get the number four-hundred and twenty-one from that? You turn the '4' into four. Then you multiply by ten. Now you have fourty. Convert the '2' into two and add it. Now you have fourty-two. Multiply by ten. Convert the '1' into one, and add, now you have four hundred and twenty one.
That's how you convert a sequence of digits into a number.
The n local variable accumulates the value of the decimal number that is passed to this function in the string. This is an implementation of atoi, without the validity checks.
Here is the workings of the loop body:
n = 10*n + *p++ - ‘0';
Assign to n the result of multiplying the prior value of n by ten plus the current character code at the pointer p less the code of zero; increment p after dereferencing.
Since digit characters are encoded sequentially, the *p-'0' expression represents a decimal value of a digit.
Let's say that you are parsing the string "987". As you go through the loop, n starts at zero; then it gets assigned the following values:
n = 10*0 + 9; // That's 9
n = 10*9 + 8; // That's 98
n = 10*98 + 7; // That's 987
It's poorly written, to say the least.
0) Use formatting!:
int f(char* p)
{
int n = 0;
while (*p != 0)
n = 10*n + *p++ - ‘0?;
return n;
}
1) ? there is syntactically invalid. It should probably be a ' as noted by chris (and your existing ‘ is wrong too, but that's probably because you copied it from a website and not a source file), giving:
int f(char* p)
{
int n = 0;
while (*p != 0)
n = 10 * n + *p++ - '0';
return n;
}
2) The parameter type isn't as contrained as it should be. Because *p is never modified (per our goals), we should enforce that to make sure we don't make any mistakes:
int f(const char* p)
{
int n = 0;
while (*p != 0)
n = 10 * n + *p++ - '0';
return n;
}
3) The original programmer was obviously allergic to readable code. Let's split up our operations:
int f(const char* p)
{
int n = 0;
for (; *p != 0; ++p)
{
const int digit = *p - '0';
n = 10 * n + digit;
}
return n;
}
4) Now that the operations are a bit more visible, we can see some independent functionality embedded in this function; this should be factored out (this is called reactoring) into a separate function.
Namely, we see the operation of converting a character to a digit:
int todigit(const char c)
{
// this works because the literals '0', '1', '2', etc. are
// all guaranteed to be in order. Ergo '0' - '0' will be 0,
// '1' - '0' will be 1, '2' - '0' will be 2, and so on.
return c - '0';
}
int f(const char* p)
{
int n = 0;
for (; *p != 0; ++p)
n = 10 * n + todigit(*p);
return n;
}
5) So now it's clear the function reads a string character by character and generates a number digit by digit. This functionality already exists under the name atoi, and this function is an unsafe implementation:
int todigit(const char c)
{
// this works because the literals '0', '1', '2', etc. are
// all guaranteed to be in order. Ergo '0' - '0' will be 0,
// '1' - '0' will be 1, '2' - '0' will be 2, and so on.
return c - '0';
}
int atoi_unsafe(const char* p)
{
int n = 0;
for (; *p != 0; ++p)
n = 10 * n + todigit(*p);
return n;
}
It's left as an exercise to the read to check for overflow, invalid characters (those that aren't digits), and so on. But this should make it much clearer what's going on, and is how such a function should have been written in the first place.
This is a string to number conversion function. Similar to atoi.
A string is a sequence of characters. So "123" in memory would be :
'1','2','3',NULL
p Points to it.
Now, according to ASCII, digits are encoded from '0' to '9'. '0' being assigned the value 48 and '9' being assigned the value 57. As such, '1','2','3',NULL in memory is actually : 49, 50, 51, 0
If you wanted to convert from the character '0' to the integer 0, you would have to subtract 48 from the value in memory. Do you see where this is going?
Now, instead of subtracting the number 48, you subtract '0', which makes the code easier to read.