Example: if the input was DOGS LIKE CATS
output- CATS LIKE DOGS
consider that I have to use only : If-else conditions, while & for loops, Arrays, strings and Functions. NOT strings functions, Pointers & Dynamic memory allocation & structures.
Spaces need to be the same as the example as well.
I tried to do the following but it doesnt work can you help please?
void revSent(char str[]){
char temp[100];
int k;
for (i=sentenceSize ; i>0 ; i--)
for (k=0 ; k<sentenceSize ; k++)
temp[k]=str[i];
for (k=0 ; k<sentenceSize ; k++)
if (temp[k]!=' ')
for (i=k ; i>0 ; i--)
printf("%c", temp[i]);
}
It's easy to do this in-place, without any additional data structures:
reverse the whole string: DOGS LIKE CATS -> STAC EKIL SGOD
reverse each word in the string: STAC EKIL SGOD -> CATS LIKE
DOGS
Hint: you can use the same function for both (1) and (2).
You could implement the following to arrive at a solution:
Separate the sentence into a list of words.
Reverse this list.
Concat this list together to form the sentence.
If you define a word as a whitespace-delimited token then the following will do:
std::vector<std::string> sentence;
std::copy(std::istream_iterator<std::string>(std::cin),
std::istream_iterator<std::string>(),
std::back_inserter(sentence));
std::reverse(sentence.begin(), sentence.end());
In essence you want to start with the definition of a word, then place in a container your words, and finally use std::reverse() to reverse them.
For an algorithms homework your instructor probably won't be satisfied with this. You want to create a function that splits a sentence into words. You can, of course, work with pointers within the same string -- and that may well be the intent of your instructor, but if that isn't what you must then I personally find working with a container easier.
I'll give a hint: since you can't use data structures you can't directly use Paul or OJ's method. BUT, recursive function calling would form a stack.
Break the sentence into words
In order, push each word onto a stack
Pop each item off the stack and print out/add to list/write to file/whatever.
Voila!
who says the STL isn't useful?
Depending on how you do this, there are different ways to attack this.
my way is just:
while (original_string isn't empty){
take first word
prepend to reversed string
}
Here's the C++ solution (using find and substr, two very useful string functions)
using namespace std;
string word_reverse(string original){
string reverse_string;
if (original.find(' ')!=string::npos){
do{
int pos=original.find(' ');
//prepend word
reverse_string=original.substr(0,pos)+' '+reverse_string;
//remove word from original,considering the found whitespace
original=original.substr(pos+1,original.length()-(pos+1));
}while(original.find(' ')!=string::npos);
//don't forget the last word!
return original+' '+reverse_string;
}
else{//no whitespace: return original text
return original;
}
}
Related
I must browse a collection of strings to replace a pattern and save the changes.
The saving operation is (very) expensive and out of my hands, so I would like to know beforehand if the replacement did anything.
I can use std::regex_search to gain knowledge on the pattern's presence in my input, and use capture groups to store details in a std::smatch. std::regex_replace does not seem to explicitely tell me wether it did anything.
The patterns and strings are arbitrarily long and complicated; running regex_replace after a regex_search seems wasteful.
I can directly compare the input and output to search for a discrepancy but that too is uncomfortable.
Is there either a simple way to observe regex_replace to determine its impact, or to use a smatch filled by the regex_search to do a faster replacement operation ?
Thanks in advance.
No regex_replace doesn't provide this info and yes you can do it with a regex_search loop.
For example like this:
std::regex pattern("...");
std::string replacement_format = "...";
std::string input = "......"; // a very, very long string
std::string output, replacement;
std::smatch match;
auto begin = input.cbegin();
int replacements = 0;
while (std::regex_search(begin, input.cend(), match, pattern)) {
output += match.prefix();
replacement = match.format(replacement_format);
if (match[0] != replacement) {
replacements++;
}
output += replacement;
begin = match.suffix().first;
}
output.append(begin, input.cend());
if (replacements > 0) {
// process output ...
}
Live demo
As regex_replace creates a copy of your string you could simply compare the replaced string with the original one and only "store" the new one if they differ.
For C++14 it seems that regex_replace returns a pointer to the last place it has written to:
https://www.cplusplus.com/reference/regex/regex_replace/ Versions 5
and 6 return an iterator that points to the element past the last
character written to the sequence pointed by out.
I need to use getline(infile, aSentence) on 4 different sentences in a file and store them as strings. Then, I have to create an algorithm to move the first letter of every word to the last letter, then append "ay" the the word.
For example: "you may call me claptrap" will become "ouyay aymay allcay emay laptrapcay"
What's the best way to do this? I was thinking about using aSentence.find(" ") for the white space and aSentence.append to add "ay". I have no idea how to move the letter position though.
Hopefully this makes sense, thanks.
Code I have so far (incomplete, but it's the concept):
int characterIndex = 0;
char firstChar = sentence.at(characterIndex);
char currentChar = sentence.at(characterIndex);
while (currentChar != '.');
{
if(currentChar == ' ')
{
sentence.replace(characterIndex, "ay")
}
}
First thing is to write your function prototype
std::string toPigLatin(const std::string &english);
Now write a unit test for it. Pass in Hello world! and get back elloHay orlday! or whatevery you should get.
Now get it it through the unit test. If you pass an index variable i through the english, and append to the pig Latin, then i can be in three states, off-word (in whitespace or punctuation), on word, or on initial letter. We can have 1 letter words so we can go from on initial letter to off-word, but not from off-word to on-word, we have to go through the initial letter state.
When you enter the initial letter state, store the letter in a temporary. When you go into the off-word state, write it out and append an "ay". Otherwise write out the character you just read. Initial state is off-word.
I try to locate a special part in a string.
The example of string as follow:
22.21594087,1.688530832,0
I want to locate 1.688530832 out.
I tried
temp.substr(temp.find(",")+1,temp.rfind(","));
and got 1.688530832,0.
I replaced rfind() with find_last_of() but still got the same result.
temp.substr(temp.find(",")+1,temp.find_last_of(","));
I know this is a simple problem and there are other solutions.But I just want to know why the rfind did not work.
Thank you very much!
The second argument for substr is not the ending index, but rather the length of the substring you want. Simply throw in the length of 1.688530832 and you'll be fine.
If the length of the search string is not available, then you can find the position of the last comma and subtract that from the position of the first character of the special word:
auto beginning_index = temp.find(",") + 1;
auto last_comma_index = temp.rfind(",");
temp.substr(beginning_index, last_comma_index - beginning_index);
I see what you are doing. You are trying to have kind of iterators to the beginning and the end of a substring. Unfortunately, substr does not work that way, and instead expects an index and an offset from that index to select the substring.
What you were trying to achieve can be done with std::find, which does work with iterators:
auto a = std::next(std::find(begin(temp), end(temp), ','));
auto b = std::next(std::find(rbegin(temp), rend(temp), ',')).base();
std::cout << std::string(a, b);
Live demo
I have the following strings in a long string:
a=b=c=d;
a=b;
a=b=c=d=e=f;
I want to first search for above mentioned pattern (X=Y=...=Z) and then output like the following for each of the above mentioned strings:
a=d;
b=d;
c=d;
a=b;
a=f;
b=f;
c=f;
d=f;
e=f;
In general, I want all the variables to have an equal sign with the last variable on the extreme right of the string. Is there a way I can do it using regexprep in MATLAB. I am able to do it for a fixed length string, but for variable length, I have no idea how to achieve this. Any help is appreciated.
My attempt for the case of two equal signs is as follows:
funstr = regexprep(funstr, '([^;])+\s*=\s*+(\w+)+\s*=\s*([^;])+;', '$1 = $3; \n $2 = $3;\n');
Not a regexp but if you stick to Matlab you can make use of the cellfun function to avoid loop:
str = 'a=b=c=d=e=f;' ; %// input string
list = strsplit(str,'=') ;
strout = cellfun( #(a) [a,'=',list{end}] , list(1:end-1), 'uni', 0).' %'// Horchler simplification of the previous solution below
%// this does the same than above but more convoluted
%// strout = cellfun( #(a,b) cat(2,a,'=',b) , list(1:end-1) , repmat(list(end),1,length(list)-1) , 'uni',0 ).'
Will give you:
strout =
'a=f;'
'b=f;'
'c=f;'
'd=f;'
'e=f;'
Note: As Horchler rightly pointed out in comment, although the cellfun instruction allows to compact your code, it is just a disguised loop. Moreover, since it runs on cell, it is notoriously slow. You won't see the difference on such simple inputs, but keep this use when super performances are not a major concern.
Now if you like regex you must like black magic code. If all your strings are in a cell array from the start, there is a way to (over)abuse of the cellfun capabilities to obscure your code do it all in one line.
Consider:
strlist = {
'a=b=c=d;'
'a=b;'
'a=b=c=d=e=f;'
};
Then you can have all your substring with:
strout = cellfun( #(s)cellfun(#(a,b)cat(2,a,'=',b),s(1:end-1),repmat(s(end),1,length(s)-1),'uni',0).' , cellfun(#(s) strsplit(s,'=') , strlist , 'uni',0 ) ,'uni',0)
>> strout{:}
ans =
'a=d;'
'b=d;'
'c=d;'
ans =
'a=b;'
ans =
'a=f;'
'b=f;'
'c=f;'
'd=f;'
'e=f;'
This gives you a 3x1 cell array. One cell for each group of substring. If you want to concatenate them all then simply: strall = cat(2,strout{:});
I haven't had much experience w/ Matlab; but your problem can be solved by a simple string split function.
[parts, m] = strsplit( funstr, {' ', '='}, 'CollapseDelimiters', true )
Now, store the last part of parts; and iterate over parts until that:
len = length( parts )
for i = 1:len-1
print( strcat(parts(i), ' = ', parts(len)) )
end
I do not know what exactly is the print function in matlab. You can update that accordingly.
There isn't a single Regex that you can write that will cover all the cases. As posted on this answer:
https://stackoverflow.com/a/5019658/3393095
However, you have a few alternatives to achieve your final result:
You can get all the values in the line with regexp, pick the last value, then use a for loop iterating throughout the other values to generate the output. The regex to get the values would be this:
matchStr = regexp(str,'([^=;\s]*)','match')
If you want to use regexprep at any means, you should write a pattern generator and a replace expression generator, based on number of '=' in the input string, and pass these as parameters of your regexprep func.
You can forget about Regex and Split the input to generate the output looping throughout the values (similarly to alternative #1) .
My question is, how can I split a string in C++? For example, I have `
string str = "[ (a*b) + {(c-d)/f} ]"
It need to get the whole expression individually like [,(,a,*,b,......
And I want to get the brackets only like [,(,),{,(,),},] on their proper position
How can I do these with some easy ways
This is called lexical analysis (getting tokens from some sequence or stream of characters) and should be followed by parsing. Read e.g. the first half of the Dragon Book.
Maybe LL parsing is enough for you....
There are many tools for that, see this question (I would suggest ANTLR). You probably should build some abstract syntax tree at some point.
But it might not worth the effort. Did you consider embedding some scripting language in your application, e.g. lua (see this and this...), or gnu guile, python, etc...
Here is a way I got to do this,
string expression = "[ (a*b) + {(c-d)/f} ]" ;
string token ;
// appending an extra character that i'm sure will never occur in my expression
// and will be used for splitting here
expression.append("~") ;
istringstream iss(expression);
getline(iss, token, '~');
for(int i = 0 ; i < token.length() ; i++ ) {
if(token[i] != ' ' ) {
cout<<token[i] << ",";
}
}
Output will be: [,(,a,*,b,),+,{,(,c,-,d,),/,f,},],