Exercise Self Study Help - c++

I've started learning C++ and am working through some exercises in the C++ Primer Plus book.
In chapter 5 one of the exercises is:
Write a program that uses an array of
char and a loop to read one word at a
time until the word done is entered.
The program should then report the
number of words entered (not counting
done). A sample run could look like this:
Enter words (to stop, type the word done):
anteater birthday category dumpster
envy finagle geometry done for sure
You entered a total of 7 words.
You should include the cstring header
file and use the strcmp() function to
make the comparison test.
Having a hard time figuring this out. It would be much easier if I could use if statements and logical operators but I'm restricted to using only:
Loops
Relational Expressions
char arrays
Branching statments (ie if, case/switch ) and logical operators are not allowed.
Can anyone give me hints to push me in the right direction?
Edit: Clarification. The input must be one string. So, several words for one input.

Edit: oops, spec says to read into an array of char… I'm not going to bother editing, this is really stupid. std::string contains an array of char too!
cin.exceptions( ios::badbit ); // avoid using if or && to check error state
int n;
string word;
for ( n = 0; cin >> word, strcmp( word.c_str(), "done" ) != 0; ++ n ) ;
I prefer
string word;
int n;
for ( n = 0; cin && ( cin >> word, word != "done" ); ++n ) ;

Use this pseudo-code:
while (input != done)
do things
end-while

HINT: A loop could also act as a conditional...

integer count
char array input
count = 0
read input
while(input notequal "done")
count++
read input
done
print count
The input notequal "done" part can
be done as strcmp(input,"done"). If
the return value is 0 is means
input is same as "done"
reading input can be done using cin

You should define a max len for char arrays first. Then a do while loop would be sufficient. You chould check the string equality with the strcmp function. That should be ok.

Related

Time limit exceeded on test 10 code forces

hello i am a beginner in programming and am in the array lessons ,i just know very basics like if conditions and loops and data types , and when i try to solve this problem.
Problem Description
When Serezha was three years old, he was given a set of cards with letters for his birthday. They were arranged into words in the way which formed the boy's mother favorite number in binary notation. Serezha started playing with them immediately and shuffled them because he wasn't yet able to read. His father decided to rearrange them. Help him restore the original number, on condition that it was the maximum possible one.
Input Specification
The first line contains a single integer n (1⩽n⩽105) — the length of the string. The second line contains a string consisting of English lowercase letters: 'z', 'e', 'r', 'o' and 'n'.
It is guaranteed that it is possible to rearrange the letters in such a way that they form a sequence of words, each being either "zero" which corresponds to the digit 00 or "one" which corresponds to the digit 11.
Output Specification
Print the maximum possible number in binary notation. Print binary digits separated by a space. The leading zeroes are allowed.
Sample input:
4
ezor
Output:
0
Sample Input:
10
nznooeeoer
Output:
1 1 0
i got Time limit exceeded on test 10 code forces and that is my code
#include <iostream>
using namespace std;
int main()
{
int n;
char arr[10000];
cin >> n;
for (int i = 0; i < n; i++) {
cin >> arr[i];
}
for (int i = 0; i < n; i++) {
if (arr[i] == 'n') {
cout << "1"
<< " ";
}
}
for (int i = 0; i < n; i++) {
if (arr[i] == 'z') {
cout << "0"
<< " ";
}
}
}
Your problem is a buffer overrun. You put an awful 10K array on the stack, but the problem description says you can have up to 100K characters.
After your array fills up, you start overwriting the stack, including the variable n. This makes you try to read too many characters. When your program gets to the end of the input, it waits forever for more.
Instead of putting an even more awful 100K array on the stack, just count the number of z's and n's as you're reading the input, and don't bother storing the string at all.
According to the compromise (applicable to homework and challenge questions) described here
How do I ask and answer homework questions?
I will hint, without giving a code solution.
In order to fix TLEs you need to be more efficient.
In this case I'd start by getting rid of one of the three loops and of all of the array accesses.
You only need to count two things during input and one output loop.

how to ignore n integers from input

I am trying to read the last integer from an input such as-
100 121 13 ... 7 11 81
I'm only interested in the last integer and hence want to ignore all
previous integers.
I thought of using cin.ignore but that won't work here due to
unknown integers (100 is of 3 digits, while 13 is of 2 digits & so on)
I can input integer by integer using a loop and do nothing with them. Is there a better way?
It all depends on the use case that you have.
Reading a none specified number of integers from std::cin is not as easy at it may seem. Because, in contrast to reading from a file, you will not have an EOF condition. If you would read from a file stream, then it would be very simple.
int value{};
while (fileStream >> value)
;
If you are using std::cin you could try pressing CTRL-D or CTRL-Z or whatever works on your terminal to produce an EOF (End Of File) condition. But usually the approach is to use std::getline to read a complete line until the user presses enter, then put this line into a std::istringstream and extract from there.
Insofar, one answer given below is not that good.
So, next solution:
std::string line{};
std::getline(std::cin, line);
std::istringstream iss{line};
int value{};
while (iss >> value)
;
You were asking
Is there a better way?
That also depends a little. If you are just reading some integers, then please go with above approach. If you would have many many values, then you would maybe waste time by unnecessarily converting many substrings to integers and loose time.
Then, it would be better, to first read the complete string, then use rfind to find the last space in the string and use std::stoi to convert the last substring to an integer.
Caveat: In this case you must be sure (or check with more lines of code) that there are no white space at the end and the last substring is really a number. That is a lot of string/character fiddling, which can most probably avoided.
So, I would recommend the getline-stringstream approach.
You can try this simple solution for dynamically ignoring rest of the values except the last given in this problem as shown:
int count = 0;
int values, lastValue; // lastValue used for future use
std::cout << "Enter your input: ";
while (std::cin >> values) {
lastValue = values; // must be used, otherwise values = 0 when loop ends
count++;
}
std::cout << lastValue; // prints
Note: A character must be required to stop the while(), hence it's better put a . at last.
Output example
Enter your input: 3 2 4 5 6 7.
7
Try this:
for( int i=0; i<nums_to_ignore; i++) {
int ignored;
std::cin >> ignored;
}

Is this a valid for loop?

I'm currently learning c++ and i cant get my head around this syntax for the for loop.
I'm aware that for(<T>: <V>) (for-each) and the standard for(init; cond; incr) but i haven't come across the following before
for (char ch; cin>>ch && !isdigit(ch); )
If someone could shed some light onto it it would be greatly appreciated!
for (char ch; cin>>ch && !isdigit(ch); )
^^ A ^^ ^^^^^^^^ B ^^^^^^^^^^^^ ^ C ^
A: Is the init section but in this case it only declared a char named ch
B: Is the condition section executed on each iteration
It starts be taking a single character as input and then continues looping if it is not a digit
C: Is the increment section but is empty, the condition section is relied upon to get the next input (i.e., the increment) and cause the loop's termination
This is the same syntax as your second example:
for ( init ; cond ; incr)
for (char ch; cin>>ch && !isdigit(ch); )
This just default-initializes a char, then reads a new value in and ensures it's a digit each iteration.
for (char ch; cin>>ch && !isdigit(ch); )
Is your standard 3 part for loop. char ch; declares a char called ch. The condition of the the loop is the result of cin>>ch logically and with !isdigit(ch) and there is nothing being incremented.
The result of this for loop is it will read in input until the input is a digit or it reaches the end if the input.
A for loop does not need to have something in each part. As an extreme if you write for(;;) you would have a loop that runs forever.
It is.
The first value is simply an initialization value (char ch will remain unchanged, but simply be defined).
The second value is a value that has to be true for the loop to end (condition) - so until cin >> ch is not null (it gains a value) and until ch isn't a digit, it will run.
The third parameter is an increment, that is a void in your case, so nothing happens.
EDIT: I remember back in C++ classes in 1st year of college, my teacher would do something like:
for(int i = 0; i < 10; cout << array[i++]);
and basically shrinking the code by a line.

End array input with a newline?

Not sure if the title is properly worded, but what I am trying to ask is how would you signify the end of input for an array using newline. Take the following code for example. Not matter how many numbers(more or less) you type during the input for score[6], it must take 6 before you can proceed. Is there a method to change it so that an array can store 6 or 100 variables, but you can decide how many variables actually contain values. The only way I can think of doing this is to somehow incorporate '\n', so that pressing enter once creates a newline and pressing enter again signifies that you don't want to set any more values. Or is something like this not possible?
#include <iostream>
using namespace std;
int main()
{
int i,score[6],max;
cout<<"Enter the scores:"<<endl;
cin>>score[0];
max = score[0];
for(i = 1;i<6;i++)
{
cin>>score[i];
if(score[i]>max)
max = score[i];
}
return 0;
}
To detect "no input was given", you will need to read the input as a input line (string), rather than using cin >> x; - no matter what the type is of x, cin >> x; will skip over "whitespace", such as newlines and spaces.
The trouble with reading the input as lines is that you then have to "parse" the input into numbers. You can use std::stringstream or similar to do this, but it's quite a bit of extra code compared to what you have now.
The typical way to solve this kind of problem, however, is to use a "sentry" value - for example, if your input is always going to be greater or equal to zero, you can use -1 as the sentry. So you enter
1 2 3 4 5 -1
This would reduce the amount of extra code is relatively small - just check if the input is -1, such as
while(cin >> score[i] && score[i] >= 0)
{
...
}
(This will also detect end-of-file, so you could end the input with CTRL-Z or CTRL-D as appropriate for your platform)

How to remove a character from the string and change data if need it?

I have possible inputs 1M 2M .. 11M and 1Y (M and Y stand for months ) and I want to output "somestring1 somestring2.... and somestring12" note M and Y are removed and the last string is changed to 12
Example: input "11M" "hello" output: hello11
input "1Y" "hello" output: hello1
char * (const char * date, const char * somestr)
{
// just need to output final string no need to change the original string
cout<< finalStr<<endl;
}
The second string is getting output as a whole itself. So no change in its output.
The second string would be output as long as M or Y are encountered. As Stack Overflow discourages providing exact source codes, so I can give you some portion of it. There is a condition to be placed which is up to you to figure out.(The second answer gives that as well)
Code would be somewhat like this.
//Code for first string. Just for output.
for (auto i = 0 ; date[i] != '\0' ; ++i)
{
// A condition comes here.
cout << date[i] ;
}
And note that this is considering you just output the string. Otherwise you can create another string and add up the two or concatenate the existing ones.
is this homework? If not, here's what i'd suggest. (i ask about homework because you may have restrictions, not because we're not here to help)
1) do a find on 'M' in your string (using find), insert a '\0' at that position if one is found (btw i'm assuming you have well formatted input)
2) do a find on 'Y'. if one is found, insert a '\0' at that position. then do an atoi() or stringstream conversion on your string to convert to number. multiply by 12.
3) concatenate your string representation of part 1 or part 2 to your somestr
4) output.
This can probably be done in < 10 lines if i could be bothered.
the a.find('M') part and its checks can be conditional operator, then the conversion/concatenation in two or three lines at most.