Find digit in an integer at user requested position - c++

I am trying to take a user entered integer (positive or negative) and let them pick a digit position and output the digit at that position.
int findDigAtPos(int number)
{
int position;
int result;
cout << "Enter digit position between 1 and " << std::to_string(number).length() << endl;
cin >> position;
while (position < 0 || position > std::to_string(number).length())
{
cout << "Enter digit position between 1 and "<< std::to_string(number).length()<<endl;
cin >> position;
}
if (std::to_string(number).length() == 1)
cout << "Only one digit" << endl;
number = number / pow(10, (position - 1.0));
result = number % 10;
return result;
}
This is the code I currently have for the function. However, it outputs the number in reverse. How do I correct the digit position? I thought it didn't even function correctly until noticing it's in reverse order.

First, note that you shouldn't be using the pow function when working with integers, because it returns a double result, which can cause problems due to unexpected truncation of the result.
But, if you insist on using it, then you need to remember that the power of 10 by which to divide will decrease as the digit position increases: i.e., the position is given with the leftmost (most significant) digit in position 1. Thus, that power of 10 will be total number of digits minus the position:
number = number / pow(10, (std::to_string(number).length() - position));
result = number % 10;
The safer method (not using pow) would be a small loop, like this:
for (int d = std::to_string(number).length() - position; d > 0; --d) number /= 10;
result = number % 10;
However, as you're already converting the passed number to a string, then why not just save that string and extract the digit from it – at position-1, because array (and string) indexes in C++ are zero-based:
int findDigAtPos(int number)
{
int position;
std::string str = std::to_string(std::abs(number)); // If -ve, remove sign!
int ndig = str.length();
std::cout << "Enter digit position between 1 and " << ndig << "\n";
std::cin >> position;
while (position < 0 || position > ndig) {
std::cout << "Enter digit position between 1 and " << ndig << "\n";
std::cin >> position;
}
return str.at(position-1) - '0';
}
Note that the codes (ASCII or otherwise) for the numeric digits, 0 thru 9 are guaranteed by the C++ standard to be contiguous and in order, so subtracting the value of the digit 0 will 'convert' any digit to its actual, numerical value.

Instead of this:
number = number / pow(10, (position - 1.0));
result = number % 10;
This:
int length = (int)(std::to_string(number).length());
while (position < length)
{
number = number / 10;
length--;
}
result = number % 10;
The above should work fine for positive numbers. For negative numbers, you might need to a fixup. I'll leave that as an exercise for you to manage.

Related

My code for computing large sums fails this very specific test case and I'm not sure why

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.

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

How do I use the char value for string?

Sorry if this is a dumb question, this is my first coding class.
If the checksum is 10, the last digit is denoted as X according to the
ISBN-10 convention. Write a program that prompts the user to enter the
first 9 digits and displays the 10-digit ISBN (including leading
zeros). Your program should read the input as an integer.
A sample run should look something like this:
Enter the first nine digits of the ISBN: 013601267
The ISBN-10 number is: 0136012671
I have successfully made a program that can do this but using int value for all nine numbers. Unfortunately, this required the user to input every number separately.
So what I am trying to do now is use use a string ISBN so that I can target individual sections ie. isbn[0] * 1 + isbn[1] * 2...
I have also tried static_cast<char>(ISBN[0]) * 1 + static_cast<char>.... thinking it would do something and I get the same results.
string ISBN;
cout << "Enter the first nine digits of the ISBN as integer: ";
cin>>ISBN;
int n10 = (ISBN[0] * 1 + ISBN[1] * 2 + ISBN[2] * 3 + ISBN[3] * 4 + ISBN[4] * 5 + ISBN[5] * 6 + ISBN[6] * 7 + ISBN[7] * 8 + ISBN[8] * 9) % 11;
if (n10 == 10)
{
cout << ISBN << "X" << endl;
}
else
{
cout << ISBN << n10 << endl;
}
So when I input this number 013601267 I should get a 1 (0136012671) at the end instead I am getting a 5 (0136012675).
I think this is happening because it is giving me ASCII dec value instead of the char value.
Four things you should check:
1: The size of the string is actually 9 characters.
if (ISBN.size() != 9) {
// Error
}
Otherwise accessing elements that do not exist will cause an error in your program.
2: The digits do not start at value 0. In ASCII (or UTF-8) the digits start at 48. Therefore 48 => '0' 49 => '1' etc. But C++ guarantees all the digits are contiguous so as long as you know the first one you can subtract that and get a correct value. If you use '0' in an integer expression it will convert to the correct value. Thus to generate a number value from a char you should subtract this value from each digit before multiplying.
n10 = ((ISBN[0] - '0') * 1) + ((ISBN[1] - '0') * 2) + ...
3: But you should check the string is all digits.
for(auto x: ISBN) {
if (!std::is_digit(x)) {
// ERROR
}
}
4: To print a string of 9 characters with leading zero you need to make sure you prep the stream coreectly:
std::cout << std::setw(9) << std::setfill('0') << number;
Or if the number is already in a string form that you know is 9 characters long you can simply use:
std::cout << ISBN;
So To output the correct 10 character number in your case:
std::cout << ISBN << ((n10 == 10) ? 'X' : ('0' + n10)) << "\n";
First you should check the size of string
if(ISBN.size() != 9){
// ERROR
}
You can use for to calculate 'n10'
int n10 = 0;
for(int i = 0; i < ISBN.size(); ++i){
if(std::is_digit(x)){ // check digit
// characters '0','1','2'... are not same as digits 0, 1, 2...
// the value of '0' is 48, as shown here [ascii table][1]
n10 = (ISBN[i] - '0') * (i+1) + n10;
} else {
// ERROR
}
}

Understanding int reversing logic [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
I'm new to C++.
So I found this reverse code on the internet. My prof. told me to make a palindrome checker, so I look for the reverse first.
Here is what I made
void main()
{
int num;
int new_num = 0;
int dummy;
cout << "Masukkan angka";
cin >> num;
dummy = num;
cout << dummy << endl;
while (num > 0)
{
new_num = new_num*10 + (num % 10);
num = num/10;
}
cout << new_num << endl;
if ( new_num == dummy)
{
cout << "true";
}
else
cout<<"false";
getch();
}
The most confusing part is this
while(num > 0)
{
new_num = new_num*10 + (num % 10);
num = num/10;
}
cout << new_num << endl;
I found this on the internet and I don't know how it works.
Can someone explain how this code can reverse the number I input? Like when I input 12345, the output would be 54321. I can't understand.
Its talking the last char of your input by using modulo.
input is: 12345
Cycle 1:
new_num is 0, multiply by 10 give 0.
add modulo or your input 12345 % 10 = 5, new_num is now 5.
divide your input by 10 to remove last digit. input = 1234
Cycle 2,3,4 etc.:
new_num is 5, multiply by 10 gives 50.
add modulo or your input 1234 % 10 = 4, new_num is now 54.
divide your input by 10 to remove last digit. input = 123
I have taken the liberty to modify your source, and provide it in a more readable format
int inputNumber = 123;
int reversedNumber = 0;
cout << "The input number is " << inputNumber << endl;
while (inputNumber > 0) {
reversedNumber = reversedNumber*10 + inputNumber%10;
inputNumber = inputNumber/10;
}
cout << "The reversed number is " << reversedNumber << endl;
First of all, always use meaningful variables.
It will be more helpful while reading your code.
Now on to the explanation,
The modulo operator gives the remainder (not quotient!) of a division,
i.e. 5%2 = 1.
In the while loop,
1) We keep over-writing reversedNumber by changing (increasing) its decimal position (multiply by 10) and adding the remainder of the division of inputNumber and 10
2) We over-write reversedNumber by changing (decreasing) its decimal position (divide by 10).
I encourage you to actually trace out the program on paper, or printing the variable's values (debugging?) to see how this operation works.
First take a look at what num % 10 does:
#include <iostream>
int main() {
for (int i = 0; i < 100; ++i) {
std::cout << i << " % 10 = " << i % 10 << '\n';
}
}
http://coliru.stacked-crooked.com/a/8d26b893682b0001
Do you see the pattern? This expression basically just gets the least significant decimal digit from a number.
You should know the pattern in new_num*10 without even looking, since we learned this in elementary school math: It shifts the digits to the left one place.
Then if you think about what addition will do in this case, new_num*10 + num % 10, you should see that adding a number in the range [0..9] to an integer where the lowest digit is zero, will just replace that zero with the new digit.
num/10 shifts digits to the right, and since it's using integral division the fractional parts are discarded.
So all together we have:
int remove_last_digit(int value) { return value / 10; }
int get_last_digit(int value) { return value % 10; }
int push_digit(int value, int digit) {
return value * 10 + digit;
}
bool has_more_digits(int value) { return value != 0; }
int reverse_int(int value) {
int reversed_value = 0;
while ( has_more_digits(value)) {
reversed_value = push_digit(reversed_value, get_last_digit(value));
value = remove_last_digit(value);
}
return reversed_value;
}
Think of a number as digits piled on top of each other. If you take the top digit and put it on top of a second pile, and keep doing that until the first pile is empty, then the digits in the second pile are now stacked in the reverse order.

Encrypt Digit C++

So I am trying to encrypt a four digit integer by adding seven to the digit then dividing the whole digit by ten. In my program I am taking each single digit separately and then I need to divide the whole digit by ten. How can I combine all the separate int into one four digit number?
#include "stdafx.h"
using namespace std;
int main()
{
//Define all variables needed
int a,b,c,d,enc,ext;
//Print dialog and input each single digit for the four number digit
cout << "Enter Your First Digit:" << endl;
cin >> a;
cout << "Enter Your Second Digit:" << endl;
cin >> b;
cout << "Enter Your Third Digit:" << endl;
cin >> c;
cout << "Enter Your Fourth Digit:" << endl;
cin >> d;
//Add seven to each digit
a += 7;
b += 7;
c += 7;
d += 7;
a /= 10;
b /= 10;
c /= 10;
d /= 10;
cout << "Your encrpyted digits:" << c << d << a << b <<endl;
cout << "Enter 1 to exit:" <<endl;
cin >> ext;
if (ext = 1) {
exit(EXIT_SUCCESS);
}
}
As you probably noticed I am dividing each number separately. I need to do them together. Then I am also creating a decrypting which I will get me back to the original number in a separate program.
Based on your comment you are trying to do a variation on the Caesar Cipher, in which case you should be using the modulus operator (%) not the integer division operator (/). Using integer division loses information which will prevent you from decrypting. When your digit is in {0, 1, 2} your division results in a 0. When it is in {3, 4, 5, 6, 7, 8, 9}, the division results in a 1. You can't decrypt {0, 1} back into the original number without some additional information (which you have discarded).
If you want to encrypt on a digit by digit basis using the Caesar Cipher approach, you should be using modulo arithmetic so that each digit has a unique encrypted value which can be retrieved during decryption. If that's really what you are looking for then you should be doing something like the following to encrypt with a 7:
a = (a + 7) % 10;
b = (b + 7) % 10;
c = (c + 7) % 10;
d = (d + 7) % 10;
To decrpyt, you subtract 7, which in mod 10 arithmetic is an addition by 3, so that would be:
a = (a + 3) % 10;
b = (b + 3) % 10;
c = (c + 3) % 10;
d = (d + 3) % 10;
This of course presupposes you've properly validated your input (which isn't the case in your example above).
Combining the individual digits into one four-digit number is simple; just multiple the first digit by 1000, add the second multiplied by 100, and so on.
But this is a one-way algorithm; you will never be able to retrieve the original four-digit number from this.
This is what youd'd probably be looking for :
int e = (a*1000)+(b*100)+(c*10)+d;
e=e/10;
It's not clear from your description whether the addition should be modulo 10 or not; if so
((((((a % 10) * 10) + (b % 10)) * 10) + (c % 10)) * 10) + (d % 10)
if you don't want the modulo 10
(((((a * 10) + b) * 10) + c) * 10) + d
Stepping aside the fact that you almost certainly want mod instead of divide (as #Andand has said), there's more than one way to turn the digits into a number!
A lot of people using interpreted languages these days would probably want to do it symbolically. C++ can do that too, fairly neatly in fact:
// create a string stream that you can write to, just like
// writing to cout, except the results will be stored
// in a string
stringstream ss (stringstream::in | stringstream::out);
// write the digits to the string stream
ss << a << b << c << d;
cout << "The value stored as a string is " << ss.str() << endl;
// you can also read from a string stream like you're reading
// from cin. in this case we are reading the integer value
// that we just symbolically stored as a character string
int value;
ss >> value;
cout << "The value stored as an integer is " << value << endl;
It won't be as efficient as multiplications in this narrow case of a 4 digit number, because of the round trip to a string and back. But good to know the technique. Also it's a style of coding that can be a lot easier to maintain and adapt.
You'll get stringstream if you #include <sstream>.