Parse numbers at positions in a given string - c++

I have std::string with value 1T23:
How can I get x = 1, y = 2, z = 3;
I tried:
int x = std::atoi(&myString.at(0));
int y = std::atoi(&myString.at(2));
int z = std::atoi(&myString.at(3));
but it returned: x = 0, y = 23, z = 3?

You can do this:
int x = std::stoi(myString.substr(0, 1));
int y = std::stoi(myString.substr(2, 1));
int z = std::stoi(myString.substr(3, 1));

If it's all sigle digits, it could be simple:
int x = myString.at(0) - '0';
int y = myString.at(2) - '0';
int z = myString.at(3) - '0';
Of course, you need to handle potential exceptions (e.g. myString has less than 4 characters). at operator can throw std::out_of_range.
Also consider what if the interested chars are not digits in myString.

std::atoi will treat the input as a char const *, and try to convert from that position to the null-terminator.
In this case
int x = std::atoi(&myString.at(0));
the string 1T23 is converted to an int. Since this conversion is not possible, you get the result of 0.
For the other cases:
int y = std::atoi(&myString.at(2)); // converts "23" to 23
int z = std::atoi(&myString.at(3)); // converts "3" to 3
You can get the actual numbers by using std::stoi, and using the appropriate substrings. Alternatively, since you only want single digits, you could index into the string, and subtract '0'. The other answers show how to do this exactly.

Related

Python equivalent code to append two integers directly like in C++

X Y
So,I'm having two numbers. say, [12,3]
And I want to compare 123 with 321 i,e XY and YX
Or [1234,4] ---> 12344<44321
If I directly try using append, that is not valid in python.
C++ code which does what I want->
int Compare(string X, string Y)
{
// first append Y at the end of X
string XY = X.append(Y);
// then append X at the end of Y
string YX = Y.append(X);
// Now see which of the two formed numbers is greater
if (XY > YX)
{
return 1;
}
else
{
return 0;
}
}
Firstly there is a mistake in your C++ code
XY=X.append(Y) will also change X to X+Y
for example consider the following code snippet:
string X="ab", Y="cd";
string XY=X.append(Y);
cout<<"X="<<X<<", Y="<<Y<<", XY="<<XY;
output:
X=abcd, Y=cd, XY=abcd
Because append will first join Y in X then assign value of X to XY.
this will cause problem when you compute YX later.
I will suggest using '+' operator instead:
int Compare(string X, string Y)
{
string XY = X+Y;
string YX = Y+X;
if (XY > YX) return 1;
else return 0;
}
Equivalent Python3 code would be
def Compare(X, Y):
X=str(X) # Convert to string in case integer parameters are passed (if you are
Y=str(Y) # sure that only string will be passed you can skip these two lines)
XY = X+Y
YX = Y+X
if (XY > YX):
return 1
else:
return 0
You can concatenate strings in python using +. I.e., "a" + "b" results in the string "ab". To convert a string into a number use int() constructor. I.e., int("10") will produce the number 10.
This should provide you with enough information to form the solution to your problem.

Failing to sort my array with std::sort and custom comparator

arr.push_back("1");
arr.push_back("34");
arr.push_back("3");
arr.push_back("98");
arr.push_back("9");
arr.push_back("76");
arr.push_back("45");
arr.push_back("4");
sort(arr.begin(), arr.end(), myCompare);
//Here is the compare function
int myCompare(string X, string Y)
{
string XY = X.append(Y);
string YX = Y.append(X);
return XY.compare(YX) > 0 ? 1: 0;
}
//output should be 998764543431
I got some confusion regarding the sorting for eg. we have numbers {"1","34","3","98","9","76","45","4"}. When we first compare 2 strings we have 2 options 134 and 341 so as 341 is bigger we'll get 341 as a returned string.
Similarly, we get 3341 in next iteration and 983341 in next and 9983341 in next but when 76 arrives it has to be appended either at the beginning or at the end either it will 998334176 or 769983341 which is wrong. Am I missing something?
There are a few issues. Ignoring the questions of why you're storing int as std::string? This only makes sense if you'll be storing non-integer data in the array at some point. Integer comparison is very fast. string comparison is slow and almost never produces the desired result.
First,
std::string::append modifies the parameter. So, if I have:
string x = "left";
string y = "right";
string xy = x.append(y);
x now equals "leftright", as does xy. Your comparison function would append x to y, then y to the result.
Your method, called with X = 1, Y = 34:
string XY = X.append(Y);
// XY = "134", X = "134", Y = "34"
string YX = Y.append(X);
// YX = 34134, Y = "34134", X = "134"
return XY.compare(YX) > 0 ? 1: 0;
So, this could be expressed as
X = X + Y;
XY = X;
Y = Y + X;
YX = Y;
string::compare does a character compare. So, if your array were sorted just using string::compare, you'd get
1 3 34 4 45 76 9 98
Second,
When we first compare 2 strings we have 2 options 134 and 341 so as
341 is bigger we'll get 341 as a returned string.
"341" is bigger than "134". However, you aren't comparing "341" with "134" - you're comparing "134" with "3134". "3134" is only bigger because it starts with a 3 instead of a "1". If the numbers were "1341" and "341", "341" would still be bigger.
If your goal is just to sort the list based on integer value,
int myCompare(string X, string Y)
{
return atoi(X.c_str()) < atoi(Y.c_str());
}
Or, more sanely, use an int array instead of strings, and let sort use it's built-in comparison function.

c++ changing number digits places?

I have a 3 digit number, let's say n = 135. I need to change the digits in the number so that I get a different number. Putting first number in the middle for the result of 315. I figured first thing i have to do is extract separate digits and I went with this
int n = 135;
int a, b, c, x;
a = n / 100;
b = n % 100 / 10;
c = n % 10;
Now I have separate digit values but no idea how to put them all together into one variable to get x = 315.
EDIT:
Figured it out after writing. Don't know how to mark post as solved without choosing an answer. Solved it like this (if someone else encounters same problem):
x = b * 10 + a;
x = x * 10 + c;
cout << "Changed number: " << x << endl;
Multiplication is your friend.
x = b * 100 + a * 10 + c;
So, alright. The way I would do this, and please correct me if this doesn't work, would be to make it into a string, and then re-arrange stuff like that. To do that, we could use the string formatting library like this:
string number = to_string(135);
Then, you could do stuff like this:
char swap;
swap = number[0];
number[0] = number[1];
number[1] = swap;
That'll swap the first and second items, making it 315. The others follow logically. After you're done, just convert the string back to an int, like this:
int number = atoi(number.c_str());

Converting letters to numbers in C++

PROBLEM SOLVED: thanks everyone!
I am almost entirely new to C++ so I apologise in advance if the question seems trivial.
I am trying to convert a string of letters to a set of 2 digit numbers where a = 10, b = 11, ..., Y = 34, Z = 35 so that (for example) "abc def" goes to "101112131415". How would I go about doing this? Any help would really be appreciated. Also, I don't mind whether capitalization results in the same number or a different number. Thank you very much in advance. I probably won't need it for a few days but if anyone is feeling particularly nice how would I go about reversing this process? i.e. "101112131415" --> "abcdef" Thanks.
EDIT: This isn't homework, I'm entirely self taught. I have completed this project before in a different language and decided to try C++ to compare the differences and try to learn C++ in the process :)
EDIT: I have roughly what I want, I just need a little bit of help converting this so that it applies to strings, thanks guys.
#include <iostream>
#include <sstream>
#include <string>
int returnVal (char x)
{
return (int) x - 87;
}
int main()
{
char x = 'g';
std::cout << returnVal(x);
}
A portable method is to use a table lookup:
const unsigned int letter_to_value[] =
{10, 11, 12, /*...*/, 35};
// ...
letter = toupper(letter);
const unsigned int index = letter - 'A';
value = letter_to_value[index];
cout << index;
Each character has it's ASCII values. Try converting your characters into ASCII and then manipulate the difference.
Example:
int x = 'a';
cout << x;
will print 97; and
int x = 'a';
cout << x - 87;
will print 10.
Hence, you could write a function like this:
int returnVal(char x)
{
return (int)x - 87;
}
to get the required output.
And your main program could look like:
int main()
{
string s = "abcdef"
for (unsigned int i = 0; i < s.length(); i++)
{
cout << returnVal(s[i]);
}
return 0;
}
This is a simple way to do it, if not messy.
map<char, int> vals; // maps a character to an integer
int g = 1; // if a needs to be 10 then set g = 10
string alphabet = "abcdefghijklmnopqrstuvwxyz";
for(char c : alphabet) { // kooky krazy for loop
vals[c] = g;
g++;
}
What Daniel said, try it out for yourself.
As a starting point though, casting:
int i = (int)string[0] + offset;
will get you your number from character, and: stringstream will be useful too.
How would I go about doing this?
By trying to do something first, and looking for help only if you feel you cannot advance.
That being said, the most obvious solution that comes to mind is based on the fact that characters (i.e. 'a', 'G') are really numbers. Suppose you have the following:
char c = 'a';
You can get the number associated with c by doing:
int n = static_cast<int>(c);
Then, add some offset to 'n':
n += 10;
...and cast it back to a char:
c = static_cast<char>(n);
Note: The above assumes that characters are consecutive, i.e. the number corresponding to 'a' is equal to the one corresponding to 'z' minus the amount of letters between the two. This usually holds, though.
This can work
int Number = 123; // number to be converted to a string
string Result; // string which will contain the result
ostringstream convert; // stream used for the conversion
convert << Number; // insert the textual representation of 'Number' in the characters in the stream
Result = convert.str(); // set 'Result' to the contents of the stream
you should add this headers
#include <sstream>
#include <string>
Many answers will tell you that characters are encoded in ASCII and that you can convert a letter to an index by subtracting 'a'.
This is not proper C++. It is acceptable when your program requirements include a specification that ASCII is in use. However, the C++ standard alone does not require this. There are C++ implementations with other character sets.
In the absence of knowledge that ASCII is in use, you can use translation tables:
#include <limits.h>
// Define a table to translate from characters to desired codes:
static unsigned int Translate[UCHAR_MAX] =
{
['a'] = 10,
['b'] = 11,
…
};
Then you may translate characters to numbers by looking them up in the table:
unsigned char x = something;
int result = Translate[x];
Once you have the translation, you could print it as two digits using printf("%02d", result);.
Translating in the other direction requires reading two characters, converting them to a number (interpreting them as decimal), and performing a similar translation. You might have a different translation table set up for this reverse translation.
Just do this !
(s[i] - 'A' + 1)
Basically we are converting a char to number by subtracting it by A and then adding 1 to match the number and letters

Finding a Specific Digit of a Number

I'm trying to find the nth digit of an integer of an arbitrary length. I was going to convert the integer to a string and use the character at index n...
char Digit = itoa(Number).at(n);
...But then I realized the itoa function isn't standard. Is there any other way to do this?
(number/intPower(10, n))%10
just define the function intPower.
You can also use the % operator and / for integer division in a loop. (Given integer n >= 0, n % 10 gives the units digit, and n / 10 chops off the units digit.)
number = 123456789
n = 5
tmp1 = (int)(number / 10^n); // tmp1 = 12345
tmp2 = ((int)(tmp1/10))*10; // tmp2 = 12340
digit = tmp1 - tmp2; // digit = 5
You can use ostringstream to convert to a text string, but
a function along the lines of:
char nthDigit(unsigned v, int n)
{
while ( n > 0 ) {
v /= 10;
-- n;
}
return "0123456789"[v % 10];
}
should do the trick with a lot less complications. (For
starters, it handles the case where n is greater than the number
of digits correctly.)
--
James Kanze
Itoa is in stdlib.h.
You can also use an alternative itoa:
Alternative to itoa() for converting integer to string C++?
or
ANSI C, integer to string without variadic functions
It is also possible to avoid conversion to string by means of the function log10, int cmath, which returns the 10th-base logarithm of a number (roughly its length if it were a string):
unsigned int getIntLength(int x)
{
if ( x == 0 )
return 1;
else return std::log10( std::abs( x ) ) +1;
}
char getCharFromInt(int n, int x)
{
char toret = 0;
x = std::abs( x );
n = getIntLength( x ) - n -1;
for(; n >= 0; --n) {
toret = x % 10;
x /= 10;
}
return '0' + toret;
}
I have tested it, and works perfectly well (negative numbers are a special case). Also, it must be taken into account that, in order to find tthe nth element, you have to "walk" backwards in the loop, subtracting from the total int length.
Hope this helps.
A direct answer is:
char Digit = 48 + ((int)(Number/pow(10,N)) % 10 );
You should include the <math> library
const char digit = '0' + number.at(n);
Assuming number.at(n) returns a decimal digit in the range 0...9, that is.
A more general approach:
template<int base>
int nth_digit(int value, int digit)
{
return (value / (int)pow((double)base, digit)) % base;
}
Just lets you do the same thing for different base numbers (e.g. 16, 32, 64, etc.).
An alternative to itoa is the std::to_string method. So, you could simply do:
char digit = to_string(number)[index]