Say as part of input, a user inputted nrt:x to tell the program to calculate the nth root of x. If I wanted to send n and x to another method to simplify the nth root, I was thinking I could use std::string::find to look for "rt:". If find returns true, I then need to send n and x to another method, but how could I do that after "rt:" is found? For example, user inputs 7rt:3. Find would return true for "rt:", how could I then send 3 and 7 to another method?
if(std::string::find(rt:)) {
//manipulate numbers before/after rt: from user input
if(result will be an int) {
nthRoot(double n, double x);
}
If(result will not be an int) {
nthRootSimplify(double n, double x);
}
}
void nthRoot(double x, double n){
double nthRootSol = pow(x, double(1 / n));
}
edit: Code I have written as a solution with your guy's help. Any advice would be great. I see myself running into problems if "n" or "z" are longer than 1 int.
void findNthRoot(string x) {
if(x.find("rt:") != string::npos) {
unsigned position = x.find("rt:");
cout << position << endl;
double n = position - 1;
cout << n << endl;
double z = position + 3;
cout << z << endl;
string str1 = x.substr(n, 1);
string str2 = x.substr(z);
cout << str1 << endl;
cout << str2 << endl;
}
}
int main() {
findNthRoot("2 - 1+3rt:4");
return 0;
}
output is:
7
6
10
3
4
with the most important being that "3" and "4" are the values of str1 and str2
If you are assuming that input will always begin with n and end with the number under the radical, you can use std::string::front() to access the first element and std::string::back() to access the last element.
find would not return true. Such a find would be pretty damn useless. The real std::string::find returns the position of the found string.
Knowing the position, you can now separate your string into the "before" and "after" part using std::string::substr.
Related
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;
}
I am working on a lab assignment where the user inputs a string and a starting and stopping point for a substring within the string to be reversed. For example, if a user inputs the string "go bobcats", and the numbers 3 (for starting index) and 7 (for ending index), the output should be "go acbobts". I was able to write a recursive function that reverses an entire string ("go bobcats" becomes "stacbob og"), but I am having trouble with the substring aspect.
code for full string reverse:
void reversing(string s, int start, int end){
if(s.size() == 0){return;}
else{
reversing(s.substr(1), start + 1, end);
cout << s[0];
}
}
For the starting and ending index for this I just entered 0 and 9 because that would be the full length of the string.
How can I adjust the function so that it only reverses the string starting and ending at the indexes the user inputs? Also, with my current function I have to use an endl in the main to make a new line at the end of the output of the string. Is there a way I can do this inside the function? If I put an endl after cout << s[0]; it puts in a new line after each iteration making the output vertical:
s
t
a
c
b
o
b
o
g
Implementation in main:
string s;
int start, end;
cout << "Enter a string: ";
while(cin.peek() == '\n' || cin.peek() == '\r'){
cin.ignore();
}
getline(cin,s);
cout << "Now enter two numbers that are within the bounds of the string. ";
cin >> start >> end;
cout << "This is how your words look now:\n";
reversing(s,start,end);
cout << endl;
A function to reverse the string can swap the elements at both ends of the range and decrease the range by one on both sides.
void reversing(string& s, int start, int end) {
if (start >= end)
return;
swap(s[start], s[end]);
reversing(s, start + 1, end - 1);
}
And then inside main():
// ...
cout << "This is how your words look now:\n";
reversing(s, start, end);
cout << s << endl;
Sometimes it is sad to see how C++ is used to teach everything but not C++. The following is sort of an experiment to see if we can somehow approach std::reverse (the algorithm you should actually use) by actually ignoring the requirements of your homework and doing small digestable steps.
Lets start with a small variation on the solution presented in this answer. Instead of passing the string together with indices we can use iterators. In a nutshell, iterators are the glue between algorithms and data structures, more specifically container. They can refer to elements in a container, just like an index or pointer can do.
void reversing2(std::string::iterator first, std::string::iterator last) {
if (first >= last) return;
std::swap(*first,*last);
reversing2(++first,--last);
}
Iterators can be dereferenced like pointers to get a reference to the element (*first and *last). RandomAccessIterators can be incremented (++first), decremented (--last) and be compared (first >= last), just like you would do it with indices.
The next step is a difficult one, because it requires even more handwaving. Note that apart from the function signature nothing in the above function actually depends on first and last being iterators for elements in a std::string. For example to reverse a subarray of an int[] only the signature would have to change:
void reversing2(int* first, int* last) {
if (first >= last) return;
std::swap(*first,*last);
reversing2(++first,--last);
}
That makes a nice opportunity to get in touch with templates. I know that I am commiting a small crime here, because I cannot give a thorough intro, but will only present you a very narrow case. To make the same code usable for different containers we just have to modify it a little
template <typename IT>
void reversing(IT first,IT last) {
if (first >= last) return;
std::swap(*first,*last);
reversing(++first,--last);
}
This can now be called with any RandomAccessIterator. So this:
#include <string>
#include <iostream>
int main() {
std::string s{"Hello world"};
std::cout << s << '\n';
reversing2(s.begin()+3,s.begin()+7); // pass iterators to 4th and 8th character
std::cout << s << '\n';
reversing(s.begin()+3,s.begin()+7);
std::cout << s << '\n';
int x[]= {1,2,3,4,5,6};
reversing(&x[2],&x[5]); // pointers are iterators too
for (const auto e : x) std::cout << e;
}
Will produce this output:
Hello world
Helow olrld
Hello world
126543
Eventually, and this was the whole motivation for the preceding, we can see that the reversing is quite similar to std::reverse. Of course std::reverse is not recursive and there is one small caveat: standard algorithms typically work on half-open intervals, ie a range made from two iterators first and last where first is included in the interval, but last is one past the last element in the interval. Hence to get the same result, you would have to call it with the second iterator one position further than with the above function:
std::reverse(s.begin()+3,s.begin()+8); // pass iterators to 4th and one past the 8th character
Complete online example
In your function declaration the type of the first parameter is not a referenced type. So the function deals with a copy of an original string passed to the function as an argument.
However in any case your recursive function definition is invalid. At least there is no need to extract a sub-string.
Pay attention to that the second and the third parameters of the function should have the type std::string::size_type. Otherwise the user can supply a negative values for the parameters when they have the type int and the function will have undefined behavior.
Also it is better when the function returns reference to the reversed string itself.
In fact within the function you need to use only one check that the start position is less than the end position.
Here is a demonstrative program that shows how the function can be defined.
#include <iostream>
#include <string>
std::string & reversing( std::string &s, std::string::size_type start, std::string::size_type end )
{
if ( not s.empty() )
{
if ( not ( end < s.size() ) ) end = s.size() - 1;
if ( start < end )
{
std::swap( s[start], s[end] );
reversing( s, start + 1, end - 1 );
}
}
return s;
}
int main()
{
std::string s( "Hello bobaloogie" );
std::cout << s << '\n';
std::cout << reversing( s, 0, 4 ) << '\n';
std::cout << reversing( s, 6, s.size() ) << '\n';
return 0;
}
The program output is
Hello bobaloogie
olleH bobaloogie
olleH eigoolabob
well i also have a solution but without implementing library function just to give you a feel of implementation and it's pretty simple.
adjusting your function - swap the start and last position recursively instead of doing
exhaustively .
endl in the main - if you wish to save the answer in input string only then yes you have to do that in main . Else just before returning from function put 'endl '.
My code goes like this.
#include<bits/stdc++.h>
using namespace std;
void rev(string &str,int s,int l){ // s = start l = last
if(l<s) return ; // base condition when l precedes s
else {
char temp = str[s];
str[s] = str[l];
str[l] = temp;
rev(str,++s,--l);
}
return ;
}
int main(){
string str;
int s,l;
getline(cin,str);
cin>>s>>l;
assert(s<str.size() && l<str.size());
rev(str,s,l);
cout<<str;
}
There are different way to approach this problem, the greedy one is to use substring to pass the exact string to the reverse function:
void reversing(string s){
if(s.size() == 0){return;}
else{
reversing(s.substr(1));
cout << s[0];
}
}
void main(string s, int start, int end) {
string substring = reversing(s.substr(start, end - start + 1));
cout << s.substr(0, start) + substring + s.substr(end + 1);
}
else you need to edit your function that reverse to edit the string only when in such range
void reversing(string s, int start, int end, int index = 0, string output = ""){
if(s.length() == index){return output;}
else{
if (index >= start && index <= end) {
output = output + s[end - (index - start)];
} else {
output += s[index];
}
reversing(s, start, end, index+1, output);
cout << output[output.length()-1];
}
}
I have a string that look like this,
x:12812Y:121Z:1292
where there is always "X:","Y:", and "Z:"
I need to convert the numerals following each letter into a int variable, thus
int x = 12812
int y = 121
int y = 1292
Is there a way to do it?
Thanks!
Yes there is a way to do it:
Read two characters (the X: part), then read an integer. Repeat two more times.
If the "string" is in a file, I first recommend you read the whole line from the file into an std::string (using e.g. std::getline), then use std::istringstream to extract the data of each line.
If the order of the data is not fixe (e.g. X may not always be first) then check the first character to see what data the number is.
If the order is always fixed and the same, you can also store the number in an array or a vector.
using standard scanf is as simple as this:
#include<cstdio>
int main() {
int x, y, z;
char xx, yy, zz;
scanf("%c:%d%c:%d%c:%d", &xx, &x, &yy, &y, &zz, &z);
printf("%d %d %d\n", x, y, z);
return 0;
}
If the order and format is always fixed you could do something like this:
string str="x:12812Y:121Z:1292";//you might want to convert this to uppercase first
string xword,yword,zword;
istringstream ss(&str[1]);//put the string read in to string stream, jump the first x
//you may want to this in a loop
::getline(ss,xword,'Y');//will getthe x part,something like :12812
::getline(ss,yword,'Z');//get the y part, the y will not be read here, something like :121
::getline(ss,zword,'X');//get the z part
xword.erase(0,1);//remove the leading colon
yword.erase(0,1);//remove the leading colon
zword.erase(0,1);//remove the leading colon
// convert the string to int
Try this:
#include<iostream>
#include<sstream>
#include<string>
int main()
{
std::string str = "x:12812Y:121Z:1292";
std::string::size_type sz;
std::stringstream ss(str);
char tmp;
int x, y, z;
ss>>tmp;
ss>>tmp;
ss>>x;
ss>>tmp;
ss>>tmp;
ss>>y;
ss>>tmp;
ss>>tmp;
ss>>z;
std::cout<<"x:"<<x<<"\n";
std::cout<<"y:"<<y<<"\n";
std::cout<<"z:"<<z<<"\n";
return 0;
}
Output:
x:12812
y:121
z:1292
Some things can be done surprisingly elegantly without relying on a library.
This code demonstrates using the next_int function. next_int only takes up 9 lines -- the rest of the code demonstrates use with wide-character C-string, a char C-string and a std::string (through a C-string from std::string::c_str()).
#include <iostream>
#include <string>
// next_int parses a non-negative decimal integer value
// beginning at or after the passed string pointer.
// The pointer is incremented to point to the character
// which follows the parsed digits.
// If no digits follow the passed pointer, a value of
// zero is returned and the pointer is advanced to the
// string's terminating nul.
template <typename C>
inline int next_int(const C* &p) {
while(*p && (*p < C('0') || *p > C('9'))) { ++p; }
int val = 0;
while(*p >= C('0') && *p <= C('9')) {
val = val * 10 + *(p++) - C('0');
}
return val;
}
int main() {
const auto* pws = L"x:12812Y:121Z:1292";;
int x = next_int(pws);
int y = next_int(pws);
int z = next_int(pws);
std::cout << "(" << sizeof(*pws) << " Wide String) x: " << x << " y: " << y << " z: " << z << '\n';
const char* pcs = "54321,891011,0,1";
std::cout << "\n* char String\n";
for(int index=0; *pcs; ++index) {
const int value = next_int(pcs);
std::cout << " " << index << ": " << value << '\n';
}
// This example shows what happens when no digits follow the pointer
// passed to next_int. Because no digits appear in the characters
// following the final "10", the last call to next_int returns 0.
// next_int could be modified to unambiguously enumerate arbitrarily-sized
// sets of numbers, possibly by returning a magic number (like -1) if
// val was never updated by a digit, or adding a second scan, advancing
// p to the next digit or nul character, thus skipping the phantom
// parse at the end.
std::string nums = "Flight 552 to Paris cost me $400 1-way and lasted 10 hours";
const auto* pstr = nums.c_str();
std::cout << "\n* char String from std::string\n";
std::cout << " The extra 0 at the end comes from passing next_int a string containing no digits\n";
for(int index=0; *pstr; ++index) {
const int value = next_int(pstr);
std::cout << index << ": " << value << '\n';
}
}
This is the output:
(2 Wide String) x: 12812 y: 121 z: 1292
* char String
0: 54321
1: 891011
2: 0
3: 1
* char String from std::string
The extra 0 at the end comes from passing next_int a string containing no digits
0: 552
1: 400
2: 1
3: 10
4: 0
Assuming that keys are case-sensitive letters, values are always integers and relationship between key and value is important, but order of key/value pairs is not.
#include <string>
#include <sstream>
#include <iostream>
int main()
{
std::istringstream ss("x:12812Y:121Z:1292");
int x, Y, Z;
while (!ss.eof())
{
char tag, delim;
int val;
ss >> tag >> delim >> val;
switch(tag)
{
case 'x': x = val; break;
case 'Y': Y = val; break;
case 'Z': Z = val; break;
}
}
std::cout << "parsed: x=" << x << " Y=" << Y << " Z=" << Z << std::endl;
return 0;
},
First, let me apologize if this is the world's stupidest question. But, I'm stumped and I've done a bunch of searching both here and on Google. I'm teaching myself C++, so it's possible I just don't have to vocabulary necessary to know what to search for.
I'm trying to write a Finite State Machine to parse equations. I know it's been done before, but I'm trying to learn. To that end, I want to be able to take a string, recognize numbers, and convert them to doubles or floats. (I'll entertain any advice you have on which format to use.)
I have a function to convert a string to a double:
double convertToDouble(string value)
{
/* -- From http://www.parashift.com/c++-faq-lite/misc-technical-issues.html#faq-39.2
Using stringstream, convert a string to a double by treating it like a stream
*/
istringstream stream(value);
double doubleValue;
stream >> doubleValue;
return doubleValue;
}
And I have a function to look for the next numeric value in a string:
string evaluateNextValue (int operatorPosition, string equation)
{
/* -- Find the next value
My idea is that, since I'm using spaces as my dividers, we'll look for
the first number and then, using insert to put the individual numbers
into a string until a space is found again. Then, the numbers--now
in the correct order--can be converted to a double and returned
*/
bool digitFound = false;
string workingNumbers;
for (int pos = operatorPosition; pos < equation.size(); pos ++)
{
if (equation.at(pos) == ' ' && digitFound == true)
{
double result = convertToDouble(workingNumbers);
cout << "Converting a string to " << result << endl;
cout << "The result plus one is: " << result +1 << endl;
return workingNumbers;
} else if (equation.at(pos) == ' ' && digitFound == false)
{
cout << "Skipping a blank space." << endl;
continue;
} else
{
if (digitFound == false)
{
digitFound = true;
cout << "First digit found." << endl;
}
cout << "Adding " << equation.at(pos) << " to the string." << endl;
workingNumbers.insert(workingNumbers.end(),equation.at(pos));
}
}
}
And this is the main() I'm using to call them both as a sort of test.
int main()
{
string dataInput;
cout << "Insert a number" << endl;
getline(cin, dataInput);
cout << "You entered: " << dataInput << endl;
double numberValue = convertToDouble(evaluateNextValue(0, dataInput));
cout << "Adding ten: " << numberValue + 10;
return 0;
}
Here's the thing: as it is now, with the evaluateNextValue() returning a string, it works. It seems a bit ungainly to me (may it all seems ungainly to you), but it works.
When I have the code manipulate the variable result in the function, it works fine. I just convert the string to a double and I can work with it.
BUT, when I convert the string to a double and try to return the double. . . the double works fine in the function itself. But it's nan when it arrives in main(). Even weirder (or just as weird, at any rate) is the fact that trying to return an int DOES return an int, but never anything remotely connected to the value I enter.
I'd appreciate any help you care to offer. And, as this is my first post here, I'm open to any style pointers.
The return value is undefined if evaluateNextValue arrives at the end of the string due to the for loop condition (because you have no return statement there). This triggers undefined behaviour, which can include returning NaN values.
You should enable your compiler's warnings to catch such errors.
So I'm trying to make a brute force string generator to match and compare strings in CUDA. Before I start trying to mess around with a language I don't know I wanted to get one working in C++. I currently have this code.
#include <iostream>
#include <string>
#include <cstdlib>
using namespace std;
int sLength = 0;
int count = 0;
int charReset = 0;
int stop = 0;
int maxValue = 0;
string inString = "";
static const char charSet[] = //define character set to draw from
"0123456789"
"!##$%^&*"
"abcdefghijklmnopqrstuvwxyz"
"ABCDEFGHIJKLMNOPQRSTUVWXYZ";
int stringLength = sizeof(charSet) - 1;
char genChars()
{
return charSet[count]; //Get character and send to genChars()
}
int main()
{
cout << "Length of string to match?" << endl;
cin >> sLength;
cout << "What string do you want to match?" << endl;
cin >> inString;
string sMatch(sLength, ' ');
while(true)
{
for (int y = 0; y < sLength; y++)
{
sMatch[y] = genChars(); //get the characters
cout << sMatch[y];
if (count == 74)
{
charReset + 1;
count = 0;
}
if (count == 2147000000)
{
count == 0;
maxValue++;
}
}
count++;
if (sMatch == inString) //check for string match
{
cout << endl;
cout << "It took " << count + (charReset * 74) + (maxValue*2147000000) << " randomly generated characters to match the strings." << endl;
cin >> stop;
}
cout << endl;
}
}
Now this code runs and compiles but it doesn't exactly do what I want it to. It will do 4 of the same character, EX. aaaa or 1111 and then go onto the next without incrementing like aaab or 1112. I've tried messing around with things like this
for (int x = 0; x < sLength; x++)
{
return charSet[count-sLength+x];
}
Which in my mind should work but to no avail.
You basically just need to increment a counter, than convert the count number to base (size of char array)
Here's an example which does normal numbers up to base 16.
http://www.daniweb.com/code/snippet217243.html
You should be able to replace
char NUMS[] = "0123456789ABCDEF";
with your set of characters and figure it out from there. This might not generate a large enough string using a uint, but you should be able to break it up into chunks from there.
Imagine your character array was "BAR", so you would want to convert to a base 3 number using your own symbols instead of 0 1 and 2.
What this does is perform a modulus to determine the character, then divide by the base until the number becomes zero. What you would do instead is repeat 'B' until your string length was reached instead of stopping when you hit zero.
Eg: A four character string generated from the number 13:
14%3 = 2, so it would push charSet[2] to the beginning of the empty string, "R";
Then it would divide by 3, which using integer math would = 4. 4%3 is again 1, so "A".
It would divide by 3 again, (1) 1%3 is 1, so "A".
It would divide by 3 again, (0) -- The example would stop here, but since we're generating a string we continue pushing 0 "B" until we reach 4 our 4 characters.
Final output: BAAR
For an approach which could generate much larger strings, you could use an array of ints the size of your string, (call it positions), initialize all the ints to zero and do something like this on each iteration:
i = 0;
positions[i]++;
while (positions[i] == base)
{
positions[i] = 0;
positions[++i]++;
}
Then you would go through the whole array, and build the string up using charSet[positions[i]] to determine what each character is.