Can someone explain this C++ code? [closed] - c++

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 5 years ago.
Improve this question
I am a new here. I do not understand the if statement: i==0, It eliminates repetition. How it works? Thanks.
vector<string>words;
for (string temp; cin >> temp;)
words.push_back(temp);
cout << "Number of words:" << words.size() << '\n';
sort(words);
for (int i = 0; i < words.size(); ++i)
if (i == 0 || words[i - 1] != words[i])
cout << words[i] << '\n';

If i equals 0, then you can't look words[i-1] because you can't do words[-1]
Furthermore, when you use || operator, if the first expression is true, the second expression is not checked
With i == 0 || words[i - 1] != words[i] you can print your first words because i equals 0 and the expression words[i - 1] != words[i] isn't checked and doesn't crash your program !
then with i different from 0, the first expresion isn't true and the second is checked.
For the unrepetition part :
Your array is sorted, so same words are one after another.
Then you have to check if the previous word isn't the same, you can print the word
How words[i - 1] != words[i] works :
for std::string, operators == and != look for the length of each string, and each character in the string
Comparison operator for std::string
Moreover, words[i-1] look for the previous words, and words[i] for the current one, to compare them.
So here, the expression is true if the two consecutives words aren't the same, in length and letters.
if you have words dog cat cat cat_ in your array, dog is printed first (because of the i == 0 part), the second word cat is printed, then the epression is false because the words are identical ("cat" == "cat"), and finaly, cat_is printed because different from cat

This program is first sorting all the words which are a vector of strings, and prints only unique word.
i==0 means the first word, Since you can't compare the first word with any previous so it will always be unique(from its previous words which doesn't exist)
word[i-1]!=word[i] check if the current word is different from previous the print that word.
|| is a Logical Or operator.

looks like your program prints the first word, and every other word that isn't repeated in a sorted list of words. If you're trying to look for unique words, try using std::unique.

Related

Check an Array String character value without extra variable [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 1 year ago.
Improve this question
suppose I've this code:
string str[] = {"devil", "chandra"};
// check if str[0] has properly devil, character by character or not without extra variable
Now I want to check str[ 0 ]'s all character which is 'd','e','v','i','l' one by one without extra variable.
with extra variable code will be :
string n1 = "devil";
for(int i=0; i<1; i++){
string s1 = str[i]
for(int j=0; j<s1.size(); j++){
if(s1[i] == n[i]){
cout << s1[i] << " ";
}
}
Basically, I want O(n) loop where I can access all indexes string and among them all characters.
Like s[ i ] is "devil" and s[[i]] = 'd' something like this, Know it's not valid, but is there any way to do that??
Even I don't know is it a valid question or not!
I'm not sure why you would need an extra variable. If you need a conditional that checks that the first value in the array of strings is "devil", it shouldn't be anymore complicated than:
if (str[0] == "devil")
{
* Do things *
}
C++ can check a standard string all at once. You don't need to check each individual character if that's what you're thinking.
Keep in mind, this isn't going to account for situations where the string is not exactly the same. For instance, if str[0] has "Devil" instead of "devil", then the conditional will evaluate to false.

Finding matching letters in a string at same spots [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 2 years ago.
Improve this question
I need a code to compare two strings: word and ptw. Both strings only have one word, and are of equal length and same case. The code needs to check the first character of both words and see if they are same and it will do this untill the end of the word. Then it will output the amount of matching letters (I don't need to know the matching letters).
Example: If word is windows and ptw is winowes it should output 4 as w, i, n, and s match.
I have tried the following however it does not check the positions:
string matchingletters(string word, string ptw) {
string result = "";
sort(begin(word), end(word));
sort(begin(ptw), end(ptw));
std::string intersection;
std::set_intersection(begin(word), end(word), begin(ptw), end(ptw),
back_inserter(intersection));
string mlr = to_string(intersection.length());
result = mlr + result;
cout << result << endl;
return result;
}
The result this gives when word is kanton and ptw is balkon is 4.
It counts k even though k is at 0 position in word and 3 position at ptw and thus they are not in the same postion and should not be counted.
Assuming the two words have the same length and since you don't care which letters match you can simply iterate and count matching characters
unsigned matchingletters(const std::string& word, const std::string& ptw) {
assert(word.size() == ptw.size());
unsigned count{0};
for (size_t i = 0; i < word.size(); ++i) {
if(word[i] == ptw[i])
count++;
}
return count;
}

Finding words in a (weird) string in C++

What is technically wrong in this program? The expected result is 6 since that is the total number of words present in the string.
#include <iostream>
using namespace std;
int main()
{
string str = " Let's count the number of words ";
int word = 0;
for (int i = 0; str[i] != '\0';)
{
if ((str[i] == 32 && str[i + 1] == 32) || (str[i] == 32 && str[i - 1] == 32))
{
++i;
}
else if ((str[i] == 32 && str[i - 1] != 32) || (str[i] == 32 && str[i + 1] != 32))
{
word++;
}
++i;
}
cout << "No. of words: " << word << endl;
return 0;
}
My incorrect result:
No. of words: 0
Also, if I try changing the spaces in the string or even the string itself to a totally new set of spaced out words, say:
string str = " Hello world ";
string str = "Hello world! How are you? ";
I still get incorrect results, but different from 0. I'm new to C++ programming and these kinds of strange behaviors are giving me nightmares. Is this common? What I can do to get this corrected?
If you could highlight or correct my program the way I'd written it, it would be much helpful and quick for me to understand the mistake instead of having to know some new commands at this point. Because, as I said, I'm a total beginner in C/C++.
Thanks for your time!
I'm new to C++ programming and these kinds of strange behaviors are giving me nightmares. Is this common?
Yes, it's very common. You've written a load of logic piled up in a heap and you don't have the tools to understand how it behaves.
What I can do to get this corrected?
You can work on this from both directions:
debug this to improve your understanding of how it operates:
identify in advance what you expect it to do for some short input, at each line
single-step through it in the debugger to see what it actually does
think about why it doesn't do what you expected
Sometimes the problem is that your code doesn't implement your algorithm correctly, and sometimes the algorithm itself is broken, and often it's a bit of both. Working through both will give you some insight.
write code that is easier to understand in the first place (and equivalently, write algorithms that are easy to reason about).
This depends on you having some intuition about whether something is easy to reason about, which you develop from iterating step 1.
... instead of having to know some new commands at this point.
Well, you need to learn to use a debugger anyway, so now is as good a time to start as any.
We can certainly improve the existing code, although I'd prefer to fix the logic. In general I'd encourage you to abstract your existing if conditions out into little functions, but the problem is that they don't currently seem to make any sense.
So, how do we define a word?
Your code says it is at least one non-space character preceded or followed by a space. (Do definitely prefer ' ' to 32, by the way, and std::isspace is better than either.)
However your code's implied definition is problematic, because:
each word longer than one character has both a first and last character, and you'll count each of them
you can't check whether the first character is preceded by anything, without going out of bounds
the last character is followed by the null terminator, but you don't count that as whitespace
Let's just choose a different definition, that doesn't require reading str[i-1], and doesn't require the tricky traversal your current code gets wrong.
I claim that a word is a contiguous substring of non-whitespace characters, and words are separated by contiguous substrings of whitespace characters. So, instead of looking at each pair of consecutive characters, we can write pseudocode to work in those terms:
for (current = str.begin(); current != str.end(); ) {
// skip any leading whitespace
current = find_next_non_whitespace(str, current);
if (current != str.end()) {
// we found a word
++words;
current = find_next_whitespace(str, current);
}
}
NB. When I talked about abstracting your code out into little functions, I meant things like find_next_non_whitespace - they should be trivial to implement, easy to test, and have a name that tells you something.
When I said your existing conditions didn't seem to make sense, it's because replacing
if ((str[i] == 32 && str[i + 1] == 32) || (str[i] == 32 && str[i - 1] == 32))
with, say,
if (two_consecutive_spaces(str, i))
prompts more questions than it answers. Why have a special case for exactly two consecutive spaces? Is it different to just one space? What will actually happen if we have two words with a single space between them? Why do we advance by two characters in this case, but only one on the word branch?
The fact that the code can't easily be mapped back onto explicable logic is a bad sign - even if it worked (which we know it doesn't), we don't understand it well enough to ever change, extend or refactor it.
I think you have some ways to do it. Take a look at this code. Very similar to yours:
string s = " Let's count the number of words ";
int word = 0;
for (auto i = 0; s[i] != '\0'; i++) {
if (i == 0) {
if (s[i] != ' ') {
++word;
}
continue;
}
if (s[i - 1] == ' ' && s[i] != ' ') {
++word;
}
}
cout << "No of Words: " << word << endl;
The idea is to iterate over the string reading character by character. So we do some logic:
If we are in the first string character and it's equals to ' ', go to the next loop iteration
If we are in the first string character and it's different from ' ', means we are starting a word, so counts it and jump to the next loop iteration.
If we reach the second if, means we are not at the first position, so trying to access i - 1 should be valid. Then we just check if the previous char is a blank space and the current one it's not. This means we are starting a new word. So counts it and jump to the next loop iteration.
Another and more simple way to do it is using stringstream:
string s = " Let's count the number of words ";
stringstream ss(s);
string sub;
int word = 0;
while (ss >> sub) {
++word;
}
cout << "No of Words: " << word << endl;
This way you're basically extracting word by word from your string.

Adding char which is a math operator to random string [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 4 years ago.
Improve this question
I am trying to add "+", "-", "*" etc. to a string but it doesn't work.
Lets say I have string "12 3 +" Then I use string tmp to get values between spaces like "12" "3" "+". my cout prints "12" and "3", but "+" is missing
int ONP() {
string wyrazenie;
getline(cin, wyrazenie);
string tmp;
for (int i = 0; i < wyrazenie.length(); ++i) {
if (!isspace(wyrazenie[i])) {
tmp += wyrazenie[i];
} else {
cout << tmp << endl;
SOME CODE.....
tmp.clear();
}
}
}
Issue is that + is your last character, so you won't go in else block for it.
std::cout temp after the loop would show your missing character:
Demo
Your loop will never display the last token of the string unless the string ends in a space. When you have "12 3 +" you read in the 12 see a space, print the 12 and clear the string. You do the same thing for 3. Then you get + but since that is the last character in the string you never run the else part of the if statement to print it out. You can fix this a few ways. You can check if temp is not empty after the loop and if it is not then handle that. You can rework your logic in the loop to handle when you are on the last character and it is not a space. You could add a space to the end of the input so it will end with a space and the loop works as is.
From the code you provided, I see an issue that would cause the last character to not be printed. This is because you are only printing tmp when the next character is a space. So "12 3 +" would print "12", "3". Then tmp contains the value "+" since its never printed nor cleared, but is never printed. If your input string is "12 3 + " (notice the space) the '+' char would be printed too.
This can be solved with printing and clearing tmp after the loop is done if tmp still contains any data.

Have an if statement look ONLY at the first word in a string [duplicate]

This question already has answers here:
how to check string start in C++
(11 answers)
Closed 7 years ago.
I have a vector composed of strings, some strings have single words, some have multiple words, some have numbers, etc. I have a code that deletes elements of the vector IF the entire string is one specific word ("event") that works perfectly:
for (int j = 0; j< myvec.size()-1; j++) {
if(myvec[j] == "<event>") { //erase all instances of "<event>"
myvec.erase(myvec.begin()+j);
}
}
However, now I need to delete a few elements in the vector that only START with a word (these all have differing junk after that first key word "wgt"
I have no idea how to get this working. I'm assuming it will be something similar to the above for/if loop, I just don't know how to make the if statement only look at the first word in the string.
Any ideas?
Thanks in advance!
The first line places string beginning with 'abc' at the end, and the second erases them from the vector.
auto end_it = std::remove_if(myvec.begin(), myvec.end(),
[](const string &str){
return str.find("abc") == 0 ;}) ;
myvec.erase(end_it, myvec.end()) ;