accumulate with custom sum - c++

The function below convert a string to integer, making use of std::accumulate.
It first checks the presence of a sign and skips it.
The parameter c of lambda is fine as it just goes through all the remaining characters of input string s. But what about the first lambda parameter sum? How does it know that it should initialise sum to zero? And does the order of these lambda parameters matter?
int string2int(const string &s)
{
return (s[0] == '-' ? -1 : 1) *
accumulate(begin(s) + (s[0] == '-' || s[0] == '+'), end(s), 0,
[](int sum, char c) {
return sum * 10 + c - '0';
});
}
Btw, equivalent code without using std::accumulate would look something like this:
int string2int(const string &s)
{
int sign = (s[0] == '-' ? -1 : 0);
sign = (s[0] == '+' ? 1 : sign);
int index = 0;
if(sign != 0)
{
++index;
}
int result = 0;
for (auto i = index; i < s.size(); ++i)
{
result = result * 10 + (s[i] - '0');
}
sign = (sign < 0 ? -1 : 1);
return result * sign;
}

The parameter between end(s) and the lambda is the initial value.
Could be 1, for example, if you wanted product.
The first lambda parameter is the accumulated data, the second is the current element of the sequence.

Related

Smallest number whose sum of the digits is equal to the given number n

Below statement gives smallest number whose sum of digit is equal to the given number n.
If the input is 10 output will be 19 (1+9=10)
digits=(c % 9 + 1) * pow(10, (c / 9)) - 1
But when the input is greater like 100000, the output shows Inf. Can anyone help me to solve this, I even tried with unsigned long long int.
Assuming you just want to print the answer and not keep it stored in an integer variable, you can avoid overflow by taking the first digit as c%9and append c/9 number of '9' chars to complete the summation.
std::string getDigits(long long c)
{
if (c == 0)
{
return "0";
}
if (c < 0)
{
return "";
}
auto first = (c % 9);
c -= first;
auto nineCount = c / 9;
std::string result;
if (first != 0)
{
result += std::string(1, (char)(first+'0'));
}
result += std::string(nineCount, '9');
return result;
}
Example run:
int main()
{
std::cout << getDigits(987) << std::endl;
return 0;
}
prints:
69999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999

Binary Set Calculator Function

So I've been working on a project for my C++ class, and we have to create a binary calculator. Yet the Professor says the functions should return an 8 bit binary set back. My issue is this
11111111 + 11111111 = 0111111110
Yet in the function we originally create this is the outcome
11111111 + 1111111 = 00000000
Which to me is incorrect. So I changed my function to this
Decimal to Binary
string DecToBin(int num)
{
/*
Purpose: Changing a Decimal to a Binary Set
Pre: Valid positive integer
Post: Returns the valid binary string
*/
string bin = "";
while (num >= 0)
{
bin += (num % 2 == 0 ? "0" : "1");
if (num != 0)
num /= 2;
else break;
}
return bin;
}
Though here lies the issue again
01010101 + 10101010 = 011111111
But my function above returns
01010101 + 10101010 = 111111110
What would be the best possible function to create if one I NEED to return an 8 bit set or if like my said function above which returns the correct answer for some and wrong for the others which I need to figure out why that is in the first place.
Binary to Decimal
int BinToDec(string bin)
{
/*
Purpose: To generate a decimal integer from a string binary set
Pre: Valid String binary set
Post: Output the output decimal integer
*/
int output = 0; //initialize output as 0
int base2Start = 128;//base2 start at 128
int len = bin.length();//get the string length
for (int i = 0; i < len; i++)//iterate
{
if (bin[i] == '1')//if bin[i] in the array of string is a char 1
{
output = output + base2Start;//output gets + base2Start
}//end if condition
base2Start = base2Start / 2;//divide base2Start after each iteration
}//end for loop
return output;//return the output
}
Addition Function
int Addition(string st1, string st2)
{
/*
Purpose: Get's two valid Binary sets, then adds their decimal conversion, and returns the addition
Pre: Need two strings that SHOULD be valid binary
Post: Returns binary from decimal conversion
*/
int first, second;
if (ValidBin(st1))
{
first = BinToDec(st1);
}
else return 0;
if (ValidBin(st2)){
second = BinToDec(st2);
}
else return 0;
add++;
return first + second;
}
bin += (num % 2 == 0 ? "0" : "1");
Should be
bin = (num % 2 == 0 ? "0" : "1") + bin;
Since you each time you are adding the least significant bit of the num to string. So at the end, according to your code, you will have the least significant most left instead of most right.
Edit: In order to truncate the result to 8 bit width change the following line:
return first + second;
By the this one:
return (first + second) & 0xFF; // Same as (first + second) % 256
#include <iostream>
using namespace std;
string sumBinary (string s1, string s2);
int main()
{
cout << "output = "<< sumBinary ("10","10");
}
string sumBinary (string s1, string s2)
{
if (s1.empty())
return s2;
if (s2.empty())
return s1;
int len1 = s1.length() -1;
int len2 = s2.length() -1;
string s3;
s3 = len1 > len2 ? s1: s2;
int len3 = s3.length() -1;
bool carry = false;
while (len1>=0 || len2>=0) {
int i1 = len1>=0? s1[len1--] - '0': 0;
int i2 = len2>=0? s2[len2--] - '0': 0;
// Check if any invalid character
if (i1 <0 || i1>1 || i2<0 || i2>1)
return "";
// 3 bit sum
int sum = i1 ^ i2 ^ carry;
// 3 bit carry
carry = (i1 & carry) | (i2 & carry) | (i1 & i2);
s3[len3--] = '0' + sum;
}
if (carry)
s3 = "1" + s3;
return s3;
}

How does strings comparison in C++ work?

I am trying to solve this problem.
I am implementing it with strings. Here is my code snippet
string s,ss;
// s and ss both contains integer input.
while(s <= ss )
//while( s<=ss && s.size() <= ss.size())
{
int i = inc, j = dec; // inc and dec are middle values. both equal if odd else different
while((s[j]-'0')==9 && i < len && j>=0){
// for cases like 999
s[i] = s[j] = '0';
i++;
j--;
}
if(j<0){
s = "1" + s;
int l = s[len-1] - '0';
l++;
//cout<<l<<"\n";
s[len] = (l + '0');
}
else{
int l = s[j] - '0';
l++;
s[i] = s[j] = (l+'0');
}
if(s <= ss)
cout<<"out in wild "<<s<<" and "<<ss<<"\n";
}
cout<<s<<endl;
The problem that I am facing is when input is like 999 or 9999. The outer while loop keeps on looping even when the value of s increases, but if I add while( s<=ss && s.size() <= ss.size()) it works completely fine. Why is while(s<=ss) is not working? I rarely use the string class, so I don't understand it completely. Why don't string s= 101 and ss=99 stop the while loop?
Complete code link is here
You are comparing strings with lexicographical order, not numbers , so "101" is less than "99" (because '1' < '9') , e.g.
int main(){
std::string s = "99";
std::string ss = "101";
std::cout << std::boolalpha << (s <= ss);
}
Outputs false.
Notes:
A better design for your program would be to manipulate numbers (int or double ...) and not strings in the first place, so this kind of expressions would naturally work as you expect.
E.g. "101" + "99" is "10199", not "200" ...
But if you really need strings, consider this post to sort strings containing numbers.
As pointed by #Deduplicator, a program that needlessly overuses strings is sometimes called Stringly Typed
Also see std::lexicographical_compare
Since your input explicitly only involves positive integers without leading 0, writing a comparison function is trivial, something like : (untested)
/* Returns 1 if the integer represented by s1 > the integer represented by s2
* Returns -1 if the integer represented by s1 < the integer represented by s2
* Return 0 is both are equals
*
* s1 and s2 must be strings representing positive integers without trailing 0
*/
int compare(const std::string& s1, const std::string& s2)
{
if(s1.size() > s2.size())
return 1;
if(s2.size() > s1.size())
return -1;
for(std::size_t i = 0 ; i < s1.size() ; ++i)
{
if(s1[i] - '0' < s2[i] - '0')
return 1;
if(s2[i] - '0' < s1[i] - '0')
return -1;
}
return 0;
}
While s and ss are string variables, they are compared character by character.
In the case that you mentioned being: s = "101" & ss = "99", by first hand it will check the first character in each string, and as '1' < '9' it exit up with s < ss. I would advise you to convert those values to integers before comparison.
As the s is compared with ss in lexicographical order, I would suggest you to compare one char from tail with one char from head (one by one till you reach the middle) to solve that problem.

Converting from string to int with a function

I'm fairly new to programming and I'm trying to get a function working that converts a string to an int. My idea with this function was to collect every number in the string and store it in another string, then convert it to an int.
The function returns the value 0.
What this function is supposed to do is return the converted number. Which should not be 0.
int getNumberFromString(int convertedNumber, string textToConvert)
{
for (int i = 0; i < textToConvert.size(); i++)
{
string collectNumbers;
int j = 0;
if (textToConvert[i] == '1' || textToConvert[i] == '2' || textToConvert[i] == '3' ||
textToConvert[i] == '4' || textToConvert[i] == '5' || textToConvert[i] == '6' ||
textToConvert[i] == '7' || textToConvert[i] == '8' || textToConvert[i] == '9' || textToConvert[i] == '0')
{
collectNumbers[j] = textToConvert[i];
j++;
}
if (collectNumbers.size() == 0)
{
return false;
}
else if (collectNumbers.size() > 0)
{
stringstream convert(collectNumbers);
if (!(convert >> convertedNumber))
{
convertedNumber = 0;
}
return convertedNumber;
}
}
}
Maybe you should just use library function ?
int stoi (const string& str, size_t* idx = 0, int base = 10);
You want somehting more like:
int getNumberFromString(int convertedNumber, string textToConvert) {
int retval = 0;
for (auto c: textToConvert) {
retval *= 10;
retval += c - '0';
}
return retval;
}
if you need to code it, or simply use stoi()
Your MAIN problem is that you are trying to convert the number before you have collected all the digits. You should loop over all the digits (use isdigit or if (x >= '0' && x <= '9') to avoid long list of individual digits - or, if you really like to list all digits, use switch to make it more readable).
Once you have collected all the digits, then convert AFTER the loop.
The statement return false, will be the same as return 0; since false will get converted to an integer with the value zero. So you won't be able to tell the difference between reading the value zero from a string and returning false (this is not PHP or JavaScript where type information is included in return values).

C++ extract polynomial coefficients

So I have a polynomial that looks like this: -4x^0 + x^1 + 4x^3 - 3x^4
I can tokenize this by space and '+' into: -4x^0, x^1, 4x^3, -, 3x^4
How could I just get the coefficients with the negative sign: -4, 1, 0, 4, -3
x is the only variable that will appear and this will alway appear in order
im planning on storing the coefficients in an array with the array index being the exponent
so: -4 would be at index 0, 1 would be at index 1, 0 at index 2, 4 at index 3, -3 at index 4
Once you have tokenized to "-4x^0", "x^1", etc. you can use strtol() to convert the textual representation into a number. strtol will automatically stop at the first non-digit character so the 'x' will stop it; strtol will give you a pointer to the character that stoped it, so if you want to be paranoid, you can verify the character is an x.
You will need to treat implicit 1's (i.e. in "x^1" specially). I would do something like this:
long coeff;
if (*token == 'x')
{
coeff = 1;
}
else
{
char *endptr;
coeff = strtol(token, &endptr, 10);
if (*endptr != 'x')
{
// bad token
}
}
Start with "-4x^0 + x^1 + 4x^3 - 3x^4"
Split after ^number: "-4x^0", " + x^1", " + 4x^3", " - 3x^4"
Now everything behind an ^ is an exponent, everything before the x is an coefficient
EDIT: Simple method to get the coefficient (including the sign):
Init coefficient with 0, sign with '+'
Go through each character before the x from left to right
If it's a number ('0'..'9'), coefficient = coefficient * 10 + number
If it's '-', set sign to '-'
scan the string for an 'x', then go backward storing each character of the coefficient until you hit white space. eg:
for (int i=0; i<s.length(); ++i)
{
if (s[i] == 'x')
{
string c;
for (int j=i-1; j>=0 && s[j]!=' '; --j)
c = s[j] + c;
cout << "coefficient: " << c << endl;
}
}
For a quick solution, my approach would be to write a recursive descent parser. Move forward in the string and extract the components you want. There are many examples around for writing a parser of an expression like this.
If you want to use a library, you could use boost::regex or boost::spirit, depending on what kind of approach you want to take.
Write a simple tokenizer. Define a number token (/[-0123456789][0123456789]+/), an exponent token (/x^(::number::)/). Ignore whitespace and +.
Continually read tokens as you'd expect them until the end of the string. Then spit out the tokens in whatever form you want (e.g. integers).
int readNumber(const char **input) {
/* Let stdio read it for us. */
int number;
int charsRead;
int itemsRead;
itemsRead = sscanf(**input, "%d%n", &number, &charsRead);
if(itemsRead <= 0) {
// Parse error.
return -1;
}
*input += charsRead;
return number;
}
int readExponent(const char **input) {
if(strncmp("x^", *input, 2) != 0) {
// Parse error.
return -1;
}
*input += 2;
return readNumber(input);
}
/* aka skipWhitespaceAndPlus */
void readToNextToken(const char **input) {
while(**input && (isspace(**input) || **input == '+')) {
++*input;
}
}
void readTerm(const char **input. int &coefficient, int &exponent, bool &success) {
success = false;
readToNextToken(input);
if(!**input) {
return;
}
coefficient = readNumber(input);
readToNextToken(input);
if(!**input) {
// Parse error.
return;
}
exponent = readExponent(input);
success = true;
}
/* Exponent => coefficient. */
std::map<int, int> readPolynomial(const char *input) {
std::map<int, int> ret;
bool success = true;
while(success) {
int coefficient, exponent;
readTerm(&input, coefficient, exponent, success);
if(success) {
ret[exponent] = coefficient;
}
}
return ret;
}
This would probably all go nicely in a class with some abstraction (e.g. read from a stream instead of a plain string).