I have written a P function that removes c digits in an n integer number.
The head of the function is : void P(int &n, int &c).
Let's say n = 23734 and c = 3
The output should be: 274
This what i have tried before asking here.
void P(int &n,int &c)
{
int p=1,k=0;
while(n)
{
if(n%10==c)
n=n/10;
else
{
k=k+n%10*10;
n=n/10;
}
}
cout<<k;
}
P.S. I am new here that's why i don't know how to correctly add codes.
Use std::to_string() to convert your n to a string:
std::string s = std::to_string(n);
then convert c to a char by adding 48 to it which is the equivalent of ‘0’ + your number c = some char between ‘0’ and ‘9’.
char myChar = '0' + c;
Now erase every occurrence of myChar by looping through the string and removing the index where myChar == s[i]
for(int i = 0; i < s.size(); i ++){
If(myChar == s[i]){
s.erase(s.begin()+i);
i--;
}
}
Finally, convert the string back to an int:
n = std::stoi (s);
Edit: you can accomplish this with division and modulo operations as well, as mentioned in one of the comments.
Here's an example I just put together:
bool sign = false; // false -> + , true -> -
if (n < 0) { n = -n; sign = true; }
int back = 0;
int front = n;
int i = 0;
while (front > 0) {
if(front % 10 != c){
back += (front % 10) * std::pow(10, i++);
}
front /= 10;
}
n = sign ? -back : back;
Related
I have an assignment which requires me to write a program that multiplies two large numbers that are each stored in an array of characters with the maximum length of 100. After countless efforts and debugging and multiplying 10 digit numbers step by step and by hand I have now written the following piece of messy code:
#include <iostream>
#include <string.h>
using namespace std;
const int MAX_SIZE = 100;
int charToInt(char);
char IntToChar(int);
long long int pow10(int);
bool isNumber(char[]);
void fillWith0(char[], int);
void multiply(char[], char[], char[]);
int main(){
char first_num[MAX_SIZE + 1], second_num[MAX_SIZE + 1], product[2 * MAX_SIZE + 1];
cout << "A =\t";
cin.getline(first_num, MAX_SIZE);
cout << "B =\t";
cin.getline(second_num, MAX_SIZE);
multiply(first_num, second_num, product);
cout << "A * B = " << product << endl;
return 0;
}
int charToInt(char ch){
return ch - '0';
}
char intToChar(int i){
return i + '0';
}
long long int pow10(int pow){
int res = 1;
for (int i = 0; i < pow ; i++){
res *= 10;
}
return res;
}
bool isNumber(char input[]){
for (int i = 0; input[i] != '\0'; i++){
if (!(input[i] >= '0' && input[i] <= '9')){
return false;
}
}
return true;
}
void fillWith0(char input[], int size){
int i;
for (i = 0; i < size; i++){
input[i] = '0';
}
input[i] = '\0';
}
void multiply(char first[], char second[], char prod[]){
_strrev(first);
_strrev(second);
if (isNumber(first) && isNumber(second)){
fillWith0(prod, 2 * MAX_SIZE + 1);
int i, j, k;
long long int carry = 0;
for (i = 0; second[i] != '\0'; i++){
for (j = 0; first[j] != '\0'; j++){
long long int mult = (pow10(i) * charToInt(first[j]) * charToInt(second[i])) + carry + charToInt(prod[j]);
prod[j] = intToChar(mult % 10);
carry = mult / 10;
}
k = j;
while (carry != 0){
carry += charToInt(prod[k]);
prod[k] = intToChar(carry % 10);
carry = carry / 10;
k++;
}
}
prod[k] = '\0';
_strrev(first);
_strrev(second);
_strrev(prod);
}
}
My problem is that it does not work with numbers that have more than 10 digits (1234567891 * 1987654321 works fine but nothing with more digits than that), as the output in those cases is a set of weird characters I presume the issue is somewhere something is overflowing and causing weird issues, although I have used long long int to store the only two numeric integers in the algorithm, doing so helped me bump from 6 digits to 10 but nothing more. Is there any suggestions or possibly solutions I can implement?
P.S. : As I mentioned before this is an assignment, so using libraries and other stuff is not allowed, I've already seen this implemented using vectors but unfortunately for me, I can't use vectors here.
The core mistake is using a long long int to store the intermediate multiplied number. Instead, use another char[] so the core of your multiply becomes simply:
for (i = 0; second[i] != '\0'; i++){
char scratch[2 * MAX_SIZE + 1];
// Fill up the first i positions with 0
fillWith0(scratch, i);
// Store second[i] * first in scratch, starting at position i.
// Make sure to 0-terminate scratch.
multiplyArrWithNumber(&scratch[i], intToChar(second[i]), first);
// Add pairwise elements with carry, stop at the end of scratch
addArrays(scratch, prod);
}
The Question is:
You are given a number 'N' in the form of a string 'S', which is a palindrome. You need to find the greatest number strictly less than 'N' which is also a palindrome.
I tried to solve this question but is giving wrong answer for some test cases. can anyone help me to correct my code.
Below is my code:
string nextSmallerPalindrome(string &s)
{
int n = s.length();
string ans = "";
if(n == 1)
{
s[0]--;
return s;
}
if(s == "11")
{
return "9";
}
// For Handling odd cases
if(n % 2 != 0)
{
int idx = n / 2;
int diff = 0;
if(s[idx] == '0')
{
s[idx] = '9';
diff = 1;
}
else
{
s[idx]--;
}
idx--;
while(idx >= 0 && diff == 1)
{
if(s[idx] == '0')
{
s[idx] = '9';
idx--;
}
else
{
s[idx]--;
diff = 0;
break;
}
}
int i = 0;
while(i < n && s[i] == '0')
{
i++;
}
for(; i < n; i++)
{
ans = ans + s[i];
}
int new_n = ans.length();
int j = 0;
int k = new_n - 1;
while(j < k)
{
if(ans[j] == ans[k])
{
j++;
k--;
}
else
{
ans[k] = ans[j];
j++;
k--;
}
}
return ans;
}
else // For handling even cases
{
int idx = n / 2 - 1;
int diff = 0;
if(s[idx] == '0')
{
s[idx] = '9';
diff = 1;
}
else
{
s[idx]--;
}
idx--;
while(idx >= 0 && diff == 1)
{
if(s[idx] == '0')
{
s[idx] = '9';
idx--;
}
else
{
s[idx]--;
diff = 0;
break;
}
}
int i = 0;
while(i < n && s[i] == '0') // For ignoring Zeros from front of the string
{
i++;
}
for(; i < n; i++) //storing all the string s in new string ans after ignoring front 0
{
ans = ans + s[i];
}
int new_n = ans.length();
int j = 0;
int k = new_n - 1;
while(j < k) // checking and changing the last half into first half
{
if(ans[j] == ans[k])
{
j++;
k--;
}
else
{
ans[k] = ans[j];
j++;
k--;
}
}
return ans;
}
}
Input Format:
The first line of the input contains an integer T denoting the number of test cases.
The first and the only line of each test case contains a string 'S', denoting the number whose next smaller palindrome is to be found.
Test Case:
19
7
77
101
1001
1221
144441
3444444443
57855875
10000001
11
1
111
101
1001
11011
1110111
1190911
20002
10011001
Excuse me, but I will not fix the code. I will rather describe how I would solve it. If you like the idea, then you will have a very easy time doing it.
A palindrome has n digits. n may be pair or odd. The first n / 2 digits (rounded upwards) is a number. Get that number (cut down the digits in the second half) and subtract 1.
Look at the result and the number of its digits. If subtracting 1 decreases the number of digits of your half-number, then handle that accordingly. Should be easy if you have the right idea.
Seems like using the same expression for idx in even cases as odd cases works better.
(It still doesn't handle the case for 7, though.)
Change this:
else // For handling even cases
{
int idx = n / 2 - 1;
to this:
else // For handling even cases
{
int idx = n / 2;
Results:
here's a working code
#include <bits/stdc++.h>
string nextSmallerPalindrome(string &s) {
// Write your code here.
string ans = s ;
if(s=="11"){
return "9";
}
int c = 0 ;
if(s.size()%2==1){
int k = s.size()/2 ;
//string ans = s ;
while(k>=0){
if(k==0 && ans[k]=='1' && ans.size()>1){
// cout<<"hola\n";
ans = ans.substr(1,ans.size()-2);
ans=ans+'9';
break;
}
if(ans[k]-'0'!=0){
int temp = ans[k]-'0';
temp-= 1 ;
ans[k] = (temp) +'0';
ans[s.size()-1-k] = (temp) +'0';
return ans;
}
else{
ans[k] = (9) +'0';
ans[s.size()-1-k] = (9) +'0';
k--;
}
}
}
else{
int k = s.size()/2 ;
while(k>=0){
if(k==0 && ans[k]=='1' && ans.size()>1){
ans = ans.substr(1,ans.size()-2);
ans=ans+'9';
break;
}
if(ans[k]-'0'!=0){
int temp = ans[k]-'0';
temp-= 1 ;
ans[k] = (temp) +'0';
ans[s.size()-1-k] = (temp) +'0';
return ans ;
}
else{
ans[k] = (9) +'0';
ans[s.size()-1-k] = (9) +'0';
if(c==0){
c++;
k-=2;
}
else k--;
}
}
}
return ans ;
}
Our teacher gave us this exercise:
"Given a string like '-5,14' write a function that returns the float value of -5,14
I used double here just to test the precision, but it also didn't work with floats.
[also i'm from Europe, we use the comma instead of the dot. Oh also we aren't allowed to use the type string and bool, we have to "make" them like in C]
This is what i came up with, and it seems to work a little bit. Positive numbers are similar, but wrong, and given a negative number, the result is similar to 10 times the positive of the given number.
It should work like this:
I read the string into an array of characters;
I check if the first character is a minus. if so, subtract 1 from the number of integer figures because i will count them later starting from index 0;
I count the number of integer figures with a loop from the start of the array to the ',' character;
I count the number of decimal figures with a loop from after the ',' to the end of the string;
[Keep in mind for the next step that, following the ASCII table, the code for the character of a number is that number + 48]
I add to the result variable every integer figure multiplied by ten to the power of whatever place in the number it has.
I do the same for the deicmal values but with the negative exponent.
if the number was negative, i multiply the result with -1.
But for some reason it's not working properly. The lower the number is, the less accurate it is (given 4,5 the result is 9, but given 345,543 the result is 350,43)
#include <iostream>
#define EOS '\0'
#define DIM 100
#define TRUE 1
#define FALSE 0
void leggiN(char* c)
{
std::cout << "Insert a number: ";
std::cin >> c;
}
double stof(char* str)
{
double Result = 0;
double ascii_to_int = 48;
int i = 0;
int j = 0;
int IntegerDigits = 0;
int DecimalDigits = 0;
int CommaIndex;
int isNegative = FALSE;
if (str[0] == '-')
{
IntegerDigits = -1;
isNegative = TRUE;
}
while (str[i] != ',')
{
++IntegerDigits;
++i;
}
CommaIndex = i;
++i;
while (str[i] != EOS)
{
++DecimalDigits;
++i;
}
for (i = (CommaIndex - 1); i >= 0; --i)
{
Result += (str[i] - ascii_to_int) * (std::pow(10, j));
++j;
}
j = 0;
for (i = (CommaIndex + 1); str[i] != EOS; ++i)
{
Result += (str[i] - ascii_to_int) * (std::pow(10, -j));
++j;
}
if (isNegative == 1)
Result = Result * -1;
return Result;
}
int main()
{
char str[DIM];
leggiN(str);
std::cout << stof(str);
}
use j = 1 to start your second for loop. You are trying to raise 10 to the power of -0
j = 1;
for (i = (CommaIndex + 1); str[i] != EOS; ++i)
{
Result += (str[i] - ascii_to_int) * (std::pow(10, -j));
++j;
}
If your code return 9.0 when you enter "4,5", your problem has nothing to do with imprecision.
There are other problems in your code, I've tried to un it and got a SEGFAULT...
#include <iostream>
#define EOS '\0' // 0 being such a special value, there is no need to
// define a named constant for it.
#define DIM 100
#define TRUE 1 // the language defines boolean values, avoid defining
#define FALSE 0 // unnecessary named constants for something that already
// exists.
void leggiN(char* c)
{
std::cout << "Insert a number: ";
std::cin >> c; // Inserting from cin to a char* is a BIG no-no.
// some compilers won't even allow it, for good reasons
// i.e.: what is the length of the array pointed to?
}
double stof(char* str) // you are indicating that you may modify str?
{
double Result = 0;
double ascii_to_int = 48; // this is a terrible name.
int i = 0;
int j = 0;
int IntegerDigits = 0;
int DecimalDigits = 0;
int CommaIndex;
int isNegative = FALSE;
if (str[0] == '-') // is str a valid pointer? what happens if NULL ??
{
IntegerDigits = -1;
isNegative = TRUE;
// you fail to skip the sing character, should have ++i here.
}
while (str[i] != ',') // what happens if there is no ',' in the string?
{ // you should check for str[i] == 0.
++IntegerDigits;
++i;
}
CommaIndex = i;
++i;
while (str[i] != EOS)
{
++DecimalDigits; // why do you count decimal digits?
++i; // you do not use this result anyway...
}
for (i = (CommaIndex - 1); i >= 0; --i)
{
// what happens if you have non-digit characters? they participate
// in the conversion??
// you call std::pow(), but do not include <cmath> at the top of the file.
// isn't str[i] - '0' clearer ?
Result += (str[i] - ascii_to_int) * (std::pow(10, j));
++j;
}
j = 0;
for (i = (CommaIndex + 1); str[i] != EOS; ++i)
{
Result += (str[i] - ascii_to_int) * (std::pow(10, -j));
++j;
}
if (isNegative == 1) // you had defined constants fot this, but don't use them.
Result = Result * -1;
return Result;
}
int main()
{
char str[DIM];
leggiN(str);
std::cout << stof(str);
}
Here is one way to achieve what you want.
#include <iostream>
#include <string>
const char DECIMAL_POINT = ','; // we'll use a named constant here....
// usually, we'd have to check the locale
// for regional specific information.
// works like atod(), conversion stops at end of string of first illegal character.
double stof(const char* str) {
// check input, must be not null, not empty
if (!str || str[0] == 0)
return 0;
int i = 0;
bool isNegative = false;
// take care of leading sign
if (str[0] == '-' || str[0] == '+') {
isNegative = (str[0] == '-');
++i;
}
// convert integer part.
double result = 0;
while ('0' <= str[i] && str[i] <= '9') {
result = (result * 10) + (str[i] - '0');
++i;
}
// only do decimals if they are there.
if (str[i] != DECIMAL_POINT)
return (isNegative) ? -result : result;
++i; // skip decimal point
double decimals = 0;
double multiplier = .1;
while ('0' <= str[i] && str[i] <= '9') {
decimals += (str[i] - '0') * multiplier;
++i;
multiplier *= .1;
}
result += decimals;
return (isNegative) ? -result : result;
}
int main() {
// always use std::string to read strings from cin.
std::string str;
std::cout << "Insert a number: ";
std::cin >> str;
std::cout << "in: " << str << " out: " << stof(str.c_str()) << '\n';
return 0;
}
So my problem is bigger but I just do not know what to do with my code. I can do what I want if I use an array works just fine but we are not using arrays yet so I have no idea how to do it. So I have to take user input as a string validate that the string is 16 characters long, all of them are digits, and most importantly I have to multiply every other or even character by 2. Then if it is a double digit add the two digit (ex. 10 1+0). Oh by the way I do not know why but every time I do i%2 == 0 I get the odd numbers. Is it because i is unsigned?
for(unsigned i = 1; i < card.length(); i++){
if (i % 2 == 1){
}
else {
}
}
return sum;
}
You could use an array of strings where each string contains a number.
Go through them checking for 2 conditions:
Double the number if it is even (i.e., i % 2 == 0)
Add the digits if the number has 2 digits (i.e., string's length is 2)
Code:
#include <iostream>
#include <iterator> using namespace std;
int TOTAL_CARDS = 16;
void printCards(string msg, string *array) {
cout<<msg<<endl;
for(int i = 0; i < TOTAL_CARDS; i++) {
cout<<"array["<<i<<"]="<<array[i]<<endl;
}
cout<<"\n"<<endl; }
int main() {
string cards[TOTAL_CARDS];
// hardcoded numbers 0 up to TOTAL_CARDS for demo purposes
for(int i = 0; i < TOTAL_CARDS; i++) {
cards[i] = to_string(i);
}
printCards("Before:", cards);
for (unsigned i = 1; i < TOTAL_CARDS; i++){
// double if even
if (i % 2 == 0){
cards[i] = to_string(stoi(cards[i]) * 2);
}
// add digits if double digit number
if (cards[i].length() == 2) {
// get each digit
string currentNum = cards[i];
int firstDigit = currentNum[0] - '0'; // char - '0' gives int
int secondDigit = currentNum[1] - '0';
// do sum and put in array
int sum = firstDigit + secondDigit;
cards[i] = to_string(sum);
}
}
printCards("After:", cards); }
Output:
Before:
array[0]=0
array[1]=1
array[2]=2
array[3]=3
array[4]=4
array[5]=5
array[6]=6
array[7]=7
array[8]=8
array[9]=9
array[10]=10
array[11]=11
array[12]=12
array[13]=13
array[14]=14
array[15]=15
After:
array[0]=0
array[1]=1
array[2]=4
array[3]=3
array[4]=8
array[5]=5
array[6]=3
array[7]=7
array[8]=7
array[9]=9
array[10]=2
array[11]=2
array[12]=6
array[13]=4
array[14]=10
array[15]=6
If you wanted to get user input for the numbers:
// get user to enter numbers
cout<<"Please enter "<<TOTAL_CARDS<<" numbers: "<<endl;
for(int i = 0; i < TOTAL_CARDS; i++) {
cin>>cards[i];
}
I found the answer to it. I first needed to create char variable named num. Convert the char to an int using chnum and then multiply.
for(unsigned i = 0; i < card.length(); i++){
if (i % 2 == 1){
num = card.at(i);
chnum = (num -'0');
add = chnum * 2;
if(add >= 10){
char ho = (add + '0');
string str(1,ho);
for (unsigned j = 0; j < str.length();j++){
char digi = str.at(j);
int chub = (digi - '0');
cout << digi;
//add = (chub) + (chub);
}
}
sum += add;
}
i was looking around the forums and i still couldnt find my answer to my problem.
I got two strings, that are just really an array of numbers. for example(i just choose random numbers
string input1="12345678909876543212";
string input2="12345";
I want to add these two string together but act them like there integers.
My goal is creating a class where i can add bigger numbers than (long long int) so it can exceed the largest long long int variable.
So i revese the string with no problem, so now there
input1="21234567890987654321"
input2="54321"
then i tried adding, let's say input1[0]+input2[0] (2+5) to a new string lets call it newString[0] where that would equal (7); but i cant find a good way to temporally convert the current number in the string so i can add it to the new string? can anyone help. I get sick and tired of atoi,stof,stod. they don't seem to work at all for me.
Any way i can make this function work.
I don't care about making the class yet, i just care about finding a way to add those two strings mathematically but still maintaining the newString's string format. Thank you for whoever can figure this out for me
Okay, so, assuming your only problem is with the logic, not the class design thing, I came up with this logic
fill up the inputs with 0s, checking the lengths, match the lengths
add like normal addition, keeping track of carry
finally remove leading zeros from result
So using std::transform with a lambda function on reverse iterators :-
char carry = 0;
std::transform(input1.rbegin(),input1.rend(),input2.rbegin(),
result.rbegin(),[&carry]( char x, char y){
char z = (x-'0')+(y-'0') + carry;
if (z > 9)
{
carry = 1;
z -= 10;
}
else
{
carry = 0;
}
return z + '0';
});
//And finally the last carry
result[0] = carry + '0';
//Remove the leading zero
n = result.find_first_not_of("0");
if (n != string::npos)
{
result = result.substr(n);
}
See Here
Edit "Can you comment on what your doing here"
+--------+--------------+------------+-------> Reverse Iterator
| | | |
std::transform( | input1.rbegin(), input1.rend(),input2.rbegin(),
result.rbegin(), [&carry]( char x, char y){
//This starts a lambda function
char z = (x-'0')+(y-'0') + carry; // x,y have ASCII value of each digit
// Substracr ASCII of 0 i.e. 48 to get the "original" number
// Add them up
if (z > 9) //If result greater than 9, you have a carry
{
carry = 1; // store carry for proceeding sums
z -= 10; // Obviously
}
else
{
carry = 0; //Else no carry was generated
}
return z + '0'; // Now you have "correct" number, make it a char, add 48
});
std::transform is present in header <algorithm>, see the ideone posted link.
Here's A Solution for adding two numbers represented as strings .
#include<iostream>
using namespace std;
string add(string a, string b)
{
int al=a.size()-1;
int bl=b.size()-1;
int carry=0;
string result="";
while(al>=0 && bl>=0)
{
int temp = (int)(a[al] - '0') + (int)(b[bl] - '0') + carry ;
carry = 0;
if(temp > 9 )
{
carry=1;
temp=temp-10;
}
result+=char(temp + '0');
al--;
bl--;
}
while(al>=0)
{
int temp = (int)(a[al] - '0') + carry ;
carry = 0;
if(temp>9)
{
carry=1;
temp=temp%10;
}
result+=char(temp + '0');
al--;
}
while(bl>=0)
{
int temp = (int)(b[bl] - '0') + carry ;
carry = 0;
if(temp>9)
{
carry=1;
temp=temp%10;
}
result+=char(temp + '0');
bl--;
}
if(carry)
result+="1";
string addition="";
for(int i=result.size()-1;i>=0;i--)
addition+=result[i]; // reversing the answer
return addition;
}
string trim(string a) // for removing leading 0s
{
string res="";
int i=0;
while(a[i]=='0')
i++;
for(;i<a.size();i++)
res+=a[i];
return res;
}
int main()
{
string a;
string b;
cin>>a>>b;
cout<<trim(add(a,b))<<endl;
}
I am not a very femilier with C++ but cant we do this?
int i = stoi( input1[0]);
int j = stoi( input2[0]);
int x = i+j;
Please note this can be done in C++11 Please refer [1] and 2 as well
You can convert a char to an int by subtracting '0' from it:
char sumdigit = (input1[0]-'0') + (input2[0]-'0') + '0';
atoi() would be a better to go, as far as converting input[0] to an int:
int temp = atoi(input.substr(0,1).c_str());
then use stringstream to convert back to string:
stringstream convert;
convert << temp;
string newString = convert.str();
Here is a solution, but this is so far from sensible that it is not even funny.
GCC 4.7.3: g++ -Wall -Wextra -std=c++0x dumb-big-num.cpp
#include <algorithm>
#include <cctype>
#include <iostream>
#include <sstream>
#include <stdexcept>
#include <string>
// dumb big num
// unsigned integer
class DBN {
public:
DBN() : num("0") {}
explicit DBN(const std::string& s) : num(s) {
for (const auto& c : num) {
if (!std::isdigit(c)) { throw std::invalid_argument("DBN::DBN"); } }
std::reverse(std::begin(num), std::end(num)); }
DBN operator+(const DBN& rhs) const {
DBN tmp(*this);
return tmp += rhs; }
DBN& operator+=(const DBN& rhs) {
std::string r;
const int m = std::min(num.size(), rhs.num.size());
int c = 0;
for (int i = 0; i < m; ++i) {
int s = (num[i] - '0') + (rhs.num[i] - '0') + c;
c = s / 10;
s %= 10;
r += static_cast<char>('0' + s); }
const std::string& ref = num.size() < rhs.num.size() ? rhs.num : num;
for (int i = m; i < ref.size(); ++i) {
int s = (ref[i] - '0') + c;
c = s / 10;
s %= 10;
r += static_cast<char>('0' + s); }
if (0 < c) { r += '1'; }
num = r;
return *this; }
friend std::ostream& operator<<(std::ostream& os, const DBN& rhs);
friend std::istream& operator>>(std::istream& os, DBN& rhs);
private:
std::string num;
};
std::ostream& operator<<(std::ostream& os, const DBN& rhs) {
std::string s(rhs.num);
std::reverse(std::begin(s), std::end(s));
return os << s;
}
std::istream& operator>>(std::istream& is, DBN& rhs) {
std::stringstream ss;
char c;
while (is && std::isspace(is.peek())) { is.ignore(); }
while (is) {
if (!std::isdigit(is.peek())) { break; }
is >> c;
ss << c; }
DBN n(ss.str());
rhs = n;
return is;
}
int main() {
DBN a, b, t;
while (std::cin >> a >> b) {
std::cout << a + b << "\n";
(t += a) += b;
}
std::cout << t << "\n";
}
Here it is a simple C++ code
string Sum(string a, string b)
{
if(a.size() < b.size())
swap(a, b);
int j = a.size()-1;
for(int i=b.size()-1; i>=0; i--, j--)
a[j]+=(b[i]-'0');
for(int i=a.size()-1; i>0; i--)
if(a[i] > '9')
{
int d = a[i]-'0';
a[i-1] = ((a[i-1]-'0') + d/10) + '0';
a[i] = (d%10)+'0';
}
if(a[0] > '9')
{
string k;
k+=a[0];
a[0] = ((a[0]-'0')%10)+'0';
k[0] = ((k[0]-'0')/10)+'0';
a = k+a;
}
return a;
}
cited from C - Adding the numbers in 2 strings together if a different length
answer, I write a more readable code:
void str_reverse(char *beg, char *end){
if(!beg || !end)return;
char cTmp;
while(beg < end){
cTmp = *beg;
*beg++ = *end;
*end-- = cTmp;
}
}
#define c2d(c) (c - '0')
#define d2c(d) (d + '0')
void str_add(const char* s1, const char* s2, char* s_ret){
int s1_len = strlen(s1);
int s2_len = strlen(s2);
int max_len = s1_len;
int min_len = s2_len;
const char *ps_max = s1;
const char *ps_min = s2;
if(s2_len > s1_len){
ps_min = s1;min_len = s1_len;
ps_max = s2;max_len = s2_len;
}
int carry = 0;
int i, j = 0;
for (i = max_len - 1; i >= 0; --i) {
// this wrong-prone
int idx = (i - max_len + min_len) >=0 ? (i - max_len + min_len) : -1;
int sum = c2d(ps_max[i]) + (idx >=0 ? c2d(ps_min[idx]) : 0) + carry;
carry = sum / 10;
sum = sum % 10;
s_ret[j++] = d2c(sum);
}
if(carry)s_ret[j] = '1';
str_reverse(s_ret, s_ret + strlen(s_ret) - 1);
}
test code as below:
void test_str_str_add(){
char s1[] = "123";
char s2[] = "456";
char s3[10] = {'\0'};
str_add(s1, s2, s3);
std::cout<<s3<<std::endl;
char s4[] = "456789";
char s5[10] = {'\0'};
str_add(s1, s4, s5);
std::cout<<s5<<std::endl;
char s7[] = "99999";
char s8[] = "21";
char s9[10] = {'\0'};
str_add(s7, s8, s9);
std::cout<<s9<<std::endl;
}
output:
579
456912
100020