Adding two strings that represent numbers in c++ - c++

I need to write a function string add(string a, string b)
where a and b are strings representing integers and the function add(a,b) returns a string
representing their sum.
Strings a and b can have a maximum of 100 characters.
I have tried different ways but failed, here is where I'm standing right now.
So I took the 2 strings and I tried adding each digit starting from last.
If in the array at [i] it's more than 10, then add 1 to [i-1], and mod it by 10 to get the last digit.
The return is empty:
string add(string a, string b){
int arrA[a.length()];
int arrB[b.length()];
string Res=" ";
//99999999 2222222
if(a.length()>=b.length()){
//i=7
for (int i=b.length();i>=0;i--){
arrA[i] = (int) (a[i]-'0') + (int) (b[i]-'0');
}
for(int i=b.length()-1;i>=1;i--)
Res[i]=arrA[i];
for(int i=a.length()-1;i>=1;i--){
if (arrA[i]>=10){
arrA[i]=arrA[i]%10;
arrA[i-1]=arrA[i-1]+1;}
}
}
else{
for (int i=a.length();i>=0;i--){
arrB[i] = (int) (a[i]-'0') + (int) (b[i]-'0');
}
for(int i=b.length()-1;i>=1;i--)
Res[i]=arrB[i];
for(int i=b.length()-1;i>=1;i--){
if (arrB[i]>=10){
arrB[i]=arrB[i]%10;
arrB[i-1]=arrB[i-1]+1;}
}
}
return Res;
}
Thank you in advance!

Think about how you would do this with pencil and paper, then write code to do the same thing.
You have two strings of digits. Start at the right, add the two digits, and if the result overflows, subtract 10 and note that you have a carry. Store the resulting digit. Move one place to the left. Repeat until done. If you run out of digits in one string, just pretend that you've got zeros for the rest of the digits.
Note that each digit in the input is the character representation of the digit. To get the numeric value, subtract '0' from each digit. Once you have the result, convert it to a character by adding '0'.

string add(string a, string b) {
int c = stoi(a) + stoi(b);
return to_string(c);
}

Related

How to sort non-numeric strings by converting them to integers? Is there a way to convert strings to unique integers while being ordered?

I am trying to convert strings to integers and sort them based on the integer value. These values should be unique to the string, no other string should be able to produce the same value. And if a string1 is bigger than string2, its integer value should be greater. Ex: since "orange" > "apple", "orange" should have a greater integer value. How can I do this?
I know there are an infinite number of possibilities between just 'a' and 'b' but I am not trying to fit every single possibility into a number. I am just trying to possibly sort, let say 1 million values, not an infinite amount.
I was able to get the values to be unique using the following:
long int order = 0;
for (auto letter : word)
order = order * 26 + letter - 'a' + 1;
return order;
but this obviously does not work since the value for "apple" will be greater than the value for "z".
This is not a homework assignment or a puzzle, this is something I thought of myself. Your help is appreciated, thank you!
You are almost there ... just a minor tweaks are needed:
you are multiplying by 26
however you have letters (a..z) and empty space so you should multiply by 27 instead !!!
Add zeropading
in order to make starting letter the most significant digit you should zeropad/align the strings to common length... if you are using 32bit integers then max size of string is:
floor(log27(2^32)) = 6
floor(32/log2(27)) = 6
Here small example:
int lexhash(char *s)
{
int i,h;
for (h=0,i=0;i<6;i++) // process string
{
if (s[i]==0) break;
h*=27;
h+=s[i]-'a'+1;
}
for (;i<6;i++) h*=27; // zeropad missing letters
return h;
}
returning these:
14348907 a
28697814 b
43046721 c
373071582 z
15470838 abc
358171551 xyz
23175774 apple
224829626 orange
ordered by hash:
14348907 a
15470838 abc
23175774 apple
28697814 b
43046721 c
224829626 orange
358171551 xyz
373071582 z
This will handle all lowercase a..z strings up to 6 characters length which is:
26^6 + 26^5 +26^4 + 26^3 + 26^2 + 26^1 = 321272406 possibilities
For more just use bigger bitwidth for the hash. Do not forget to use unsigned type if you use the highest bit of it too (not the case for 32bit)
You can use position of char:
std::string s("apple");
int result = 0;
for (size_t i = 0; i < s.size(); ++i)
result += (s[i] - 'a') * static_cast<int>(i + 1);
return result;
By the way, you are trying to get something very similar to hash function.

Encrypt by using string c++ with diffrent key on each char

Was given to me a task to do encrypt by 2 string, with allowed only latters and spacebar.
One string is text which should I encrypt and second string is key to encrypt text. Also I should add that text must be longer than key.
Replace letters with numbers. So I decided to use ASCII, maybe if I made numbers on my own it would be easier.
Successive characters to be encrypted are summed up with an following character from key the effect of summing modulo n. Im not so sure what it means with this modulo n.
There is few more points but I can handle them alone.
Here is my 1st try with this but original text is resetting also with key.
int pom=0;
int tabenc[a.length()];
int l=0;
while(pom<=a.length()-1){
for(int k=0;k<a.length();k++){
cout<<"Nr: "<<l<<" Sum char: "<<a[k]+b[k]<<" number text:"<<a[k]<<" number key: "<<b[k]<<endl;
tabenc[pom]=a[pom]+b[k];
pom++;
}
}
And my 2nd try was with 2 fors but here probably i already overthinked. I have no clue how I can manage to do this.
int pom=0;
for(int i=0;i<a.length();i++)
{
pom=a[i];
}
for(int j=0;j<b.length();j++){
pom=a[i]+b[j];
cout<<"Nr: "<<i<<" | Sum: "<<a[i]<<" + "<<b[j]<<" = "<<pom<<endl;
}
cout<<"Nr: "<<i<<" | Sum: "<<a[i]<<" + "<<b[i]<<" = "<<pom<<endl;
}

my run-length encoding doesn't work with big numbers

I have a assingment were I need to code and decode txt files, for example: hello how are you? has to be coded as hel2o how are you? and aaaaaaaaaajkle as a10jkle.
while ( ! invoer.eof ( ) ) {
if (kar >= '0' && kar <= '9') {
counter = kar-48;
while (counter > 1){
uitvoer.put(vorigeKar);
counter--;
}
}else if (kar == '/'){
kar = invoer.get();
uitvoer.put(kar);
}else{
uitvoer.put(kar);
}
vorigeKar = kar;
kar = invoer.get ( );
}
but the problem I have is if need to decode a12bhr, the answer is aaaaaaaaaaaabhr but I can't seem to get the 12 as number without problems, I also can't use any strings or array's.
c++
I believe that you are making following mistake: imagine you give a32, then you read the character a and save it as vorigeKar (previous character, I am , Flemish so I understand Dutch :-) ).
Then you read 3, you understand that it is a number and you repeat vorigeKar three times, which leads to aaa. Then you read 2 and repeat vorigeKar two times, leading to aaaaa (five times, five equals 3 + 2).
You need to learn how to keep on reading numeric characters, and translate them into complete numbers (like 32, or 12 in your case).
Like #Dominique said in his answers, You're doing it wrong.
Let me tell you my logic, you can try it.
Pesudo Code + Logic:
Store word as a char array or string, so that it'll be easy to print at last
Loop{
Read - a //check if it's number by subtracting from '0'
Read - 1 //check if number = true. Store it in int res[] = res*10 + 1
//Also store the previous index in an index array(ie) index of char 'a' if you encounter a number first time.
Read - 2 //check if number = true. Store it in res = res*10 + 2
Read - b , h and so on till "space" character
If you encounter another number, then store it's previous character's index in index array and then store the number in a res[] array.
Now using index array you can get the index of your repeating character to be printed and print it for it's corresponding times which we have stored in the result array.
This goes for the second, third...etc:- numbers in your word till the end of the word
}
First, even though you say you can't use strings, you still need to know the basic principle behind how to turn a stream of digit characters into an integer.
Assuming the number is positive, here is a simple function that turns a series of digits into a number:
#include <iostream>
#include <cctype>
int runningTotal(char ch, int lastNum)
{
return lastNum * 10 + (ch -'0');
}
int main()
{
// As a test
char s[] = "a123b23cd1/";
int totalNumber = 0;
for (size_t i = 0; s[i] != '/'; ++i)
{
char digit = s[i]; // This is the character "read from the file"
if ( isdigit( digit) )
totalNumber = runningTotal(digit, totalNumber);
else
{
if ( totalNumber > 0 )
std::cout << totalNumber << "\n";
totalNumber = 0;
}
}
std::cout << totalNumber;
}
Output:
123
23
1
So what was done? The character array is the "file". I then loop for each character, building up the number. The runningTotal is a function that builds the integer from each digit character encountered. When a non-digit is found, we output that number and start the total from 0 again.
The code does not save the letter to "multiply" -- I leave that to you as homework. But the code above illustrates how to take digits and create the number from them. For using a file, you would simply replace the for loop with the reading of each character from the file.

luhn algorithm and 'digit manipulation' in C++

In generating the 'check digit' in Luhn's algorithm
The check digit (x) is obtained by computing the sum of digits then computing 9 times that value modulo 10 (in equation form, (67 * 9
mod 10)). In algorithm form: Compute the sum of the digits (67).
Multiply by 9 (603). The last digit, 3, is the check digit.
Natural instincts point towards taking an id as a string to make individual digit operation easier. But there seems to be no way to extract a digit at a time through stringstream since there's no delimiter(as far as I can tell). So the process turns into a cumbersome conversion of individual characters to ints...
There's modulus for each digit approach as well, which also takes a bit of work.
I guess what I'm getting at is that I feel maybe I'm overlooking a more elegant way taking an input and operating on the input as if they were single digit inputs.
Use modular arithmetic to simply the equation like following :-
checkdigit = (sum_digits*9)%10
= ((sum_digits)%10*9)%10
Now sum_digits%10 is very simple to evaluate using strings.
C++ implementation :-
#include<iostream>
using namespace std;
int main() {
char* str = new char[100];
cout<<"Enter the String: ";
cin>>str;
int val = 0;
for(int i=0;str[i]!=0;i++) {
val = (val+str[i]-'0')%10;
}
val = (val*9)%10;
cout<<"Checkdigit("<<str<<") = "<<val;
return 0;
}
Stringstream has to calculate all digits and then convert each digit to a char by adding '0'. You'd have to subtract '0' again to get the digit values back. You'd be better off using the modulo approach directly.

Comparing Each Character in Java String

I am a beginner at C++, and I am trying to create two strings
any suggestion?
Equals method will not help you in this situation. compare using charAt(). Use two for loop and iterate both strings then add not matching characters to one string and print it at last.
ex:
for(int i=0;i<inputword.length;i++){
for(int j=0;i<inputword2.length;j++){
if(inputword.chatAt(i)==inputword2.charAt(j)){
//here write your logic or remove it from your string
}
}
}
To calculate how many characters at the start one word "overlap" the end of second:
public static int combinedLength(String s1, String s2) {
s1 = s1.toLowerCase();
s2 = s2.toLowerCase();
for (int i = 1; i < s1.length() && i < s2.length(); i++)
if (s1.endsWith(s2.substring(0, i+1)) || s2.endsWith(s1.substring(0, i+1)))
return s1.length() + s2.length() - i;
return s1.length() + s2.length();
}
This works by progressively testing longer letter sequences at the start/end if find if s1 starts with s2's end or visa versa. Because there can be only one such match, the first match found returns the result of the sum of both lengths minus the iteration number. No match returns the sum of both lengths.
Testing:
combinedLength("super", "perfect") ==> 9
combinedLength("perfect", "super") ==> 9
combinedLength("pencil", "eraser") ==> 12