Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
I am trying to solve this problem:
Write a program to count how many times each distinct word appears in its input.
This is the code so far:
#include <algorithm>
#include <iomanip>
#include <ios>
#include <iostream>
#include <string>
#include <vector>
#include <iterator>
using std::cin;
using std::sort;
using std::cout;
using std::streamsize;
using std::endl;
using std::string;
using std::setprecision;
using std::vector;
int main()
{
cout << "Enter words: ";
vector<string> lista;
vector<string> listaCitita;
string x;
while (cin >> x)
{
lista.push_back(x);
}
int listaSize = lista.size();
for (int i = 0; i <= listaSize -1; i++)
{
int x = 0;
int counter = 0;
vector<string>::iterator it = find(listaCitita.begin(), listaCitita.end(), lista[i]);
vector<string>::iterator itu = find(lista.begin(), lista.end(), lista[i]);
if (it != listaCitita.end())
{
break;
}
while(x <= listaSize -1)
{
if(lista[i] == lista[x])
{
counter++;
x++;
if(itu != lista.end())
{
}
else
{
listaCitita.push_back(lista[i]);
}
}
else
{
x++;
}
}
cout << "The string: '" << lista[i] << "' appeared " << counter << " times" << endl;
}
return 0;
}
I'm trying to: If the it variable has already been printed how many times the word showed, and it wouldn't be printed again how many times it showed.
That's why I made a second vector (listaCitita) where I add the elements that have already been iterated through. The problem is that it doesn't break out of the for loop when I do this.
if (it != listaCitita.end())
{
break;
}
The break statement ends execution of the nearest enclosing loop or conditional statement in which it appears. Control passes to the statement that follows the end of the statement, if any.
When you reach break, you will jump at the end of the for loop (return 0). What you want to use here is the continue keyword, which will skip the current word and continue with the next one.
If your program reaches break it will definitely break out of it.
One other way to break out of a loop especially if it is a nested loop and you want to break out of an outer loop would be goto.
...
while(...) { while(...) { if(...) { goto end; }}}
end: //will jump here
...
You can break out of nested loops using goto, throw or return (of course you need to separate your loops into a function or a lambda for this latter method to work).
In any case your particular task doesn't call for breaking out of a nested loop, or any other loop for that matter. You need to check if the word was already printed in the outer loop. If it was, continue, otherwise proceed to counting it, printing it, and pushing it to the vector of already-printed words.
Using containers and/or algorithms appropriate for the task would eliminate the need to use nested loops altogether. Consider std::unordered_map. Also read about std::count.
Related
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 months ago.
Improve this question
I have created a program for finding the duplicate character in a string. It is throwing garbage please help me to find the error and also find out its solution. I have created two arrays array a and b array a is a character array and array b is a integer array. array a is storing the characyeer that occurred in the string and array b for storing their frequency. please help me to find out the error
#include <iostream>
#include <stdlib.h>
using namespace std;
int main()
{
string s;
int i,j,k,l,m,n=0;
cout<<"Enter a string:";
cin>>s;
while (s[i]!='\0')
{
j++;
i++;
}
char *a=(char *)malloc(j*sizeof(char));
int *b = (int *)malloc(j*sizeof(int));
for (i=0;i<j;i++)
{
b[i]=0;
}
for (i=0;i<j;i++)
{
l=0;
for (k=0;k<i;k++)
{
if (s[i]==a[k])
{
b[k]++;
}
else
{
l++;
}
}
if (l+1==i)
{
a[i]=s[i];
b[i]++;
n++;
}
}
i=0;
while (a[i]!='\0')
{
m++;
i++;
cout<<a[i];
}
for (i=0;i<m;i++)
{
if (b[i]>1)
{
cout<<a[i]<<"occurs "<<b[i]<<" times";
}
}
return 0;
}
Let's actually use C++:
#include <cctype>
#include <iostream>
#include <string>
#include <unordered_map>
int main() {
std::string sample{"rat cat bat"};
std::unordered_map<char, int> letterFrequencies;
for (auto c : sample) {
if (std::isalpha(c)) {
++letterFrequencies[c];
}
}
for (auto entry : letterFrequencies) {
if (entry.second > 1) {
std::cout << "'" << entry.first << "' occurs " << entry.second
<< " times.\n";
}
}
}
Output:
❯ ./a.out
't' occurs 3 times.
'a' occurs 3 times.
Analyzing your code is difficult, as it seems to do far more than what's necessary. What it's doing unnecessarily is difficult to determine as your variable names are awful. Even if I wanted to use your two array method, I wouldn't. This can be done manually with a single array.
I don't know what the point of the nested loops are at all. All you need to do is count, and then analyze. That doesn't require nesting. It's two distinct loops.
You sized a wrong. It should be the size of the alphabet, not the size of your string that might have repeated characters that you are trying to count. But like I said, this array is unnecessary.
Shortcomings of the example above are that upper case and lower case letters are treated as different letters. It's an easy enough fix using another function from <cctype>.
It also explicitly only lists letters that were repeated.
std::unordered_map is a key-value data structure (similar to a python dictionary), usually implemented as a hash-map, meaning that lookups are very fast. Our keys are the letters of the string, the value is the count. The other key property is that when using operator[], if the key doesn't exist, it will be created for us.
Here is a different program that doesn't use a map.
#include <array>
#include <cctype>
#include <iostream>
#include <string>
int main() {
std::string sample{"rat cat bat"};
std::array<int, 26> letterFrequencies{0};
for (auto c : sample) {
if (std::isalpha(c)) {
++letterFrequencies[std::toupper(c) - 'A'];
}
}
for (std::size_t entry = 0; entry < letterFrequencies.size(); ++entry) {
if (letterFrequencies[entry] > 1) {
std::cout << "'" << static_cast<char>(entry + 'A') << "' occurs "
<< letterFrequencies[entry] << " times.\n";
}
}
}
Output:
❯ ./a.out
'A' occurs 3 times.
'T' occurs 3 times.
This program treats upper case and lower letters as the same.
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 3 years ago.
Improve this question
Hi there I have attached my code below and it is not working. I want to eliminate all possibles except number or character. Also no upper and lower case problem. But I don't know why it's not working even after I've tried this far. Please any help would be appreciated.
// C++ program to find if a sentence is
// palindrome
//#include <bits/stdc++.h>
#include <iostream>
#include <string>
#include <ctype.h>
using namespace std;
// To check sentence is palindrome or not
bool sentencePalindrome(string sentence)
{
int j = 0;
int l = sentence.length() - 1;
// Compares character until they are equal
while (j < l) {
//removing spaces and special characters
while(j<l&& isalnum(sentence[j])==0)
j++;
while(j<l && isalnum(sentence[l])==0)
l--;
//Checking if not palindrome
if(toupper(sentence[j])!=toupper(sentence[l]))
{
return false;
}
else
{
j++;
l--;
}
}
return true;
}
// Driver program to test sentencePalindrome()
int main()
{
string sentence;
cout << "enter sentence!" << endl;
cin >> sentence;
int result = sentencePalindrome(sentence);
if (result==1)
cout << "Sentence is palindrome.";
else
cout << "Sentence is not palindrome.";
return 0;
}
Your main issue appears to be the way you are reading in you input in your Main function. Using >> in C++ will only read in one word at a time, so you are not working with the full sentence in the function sentencePalindrome().
You should look at using getline() instead to be able to read an entire sentence in as input.
If you use the debugger, it is much easier to spot the problem. I took your code above and set a breakpoint right as the variable l is being declared on line 13 (you can see the orange dot to the left of the code for it).
When you reach that breakpoint when running the code, you can see that the value of sentence = "Test" down at the bottom, even though my input at the command line was Test the sentence.
Once you fix how you get input, you can check the logic of your program and see if it functions correctly. If you are unfamiliar with debugging, putting in a little time to learn GDB now will save you hours of frustration while coding in the future!
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 3 years ago.
Improve this question
Using c++ 14.
I'm prompting the user for a string containing both letters and integers, and trying to "strip" the integers from the string itself via the string.erase() function.
The problem i'm facing is when there are 2 or more sequential numbers, than the function seems to erase the first but delete the latter.
Example:
input: H23ey Th2e3re St01ack O34verflow
output: H3ey There St1ack O4verflow
I can do it another way by using a new string, looping through the existing one and adding only what isalpha or isspace, but it seems messier.
code:
string digalpha {};
cout << "Enter string containing both numbers and letters: ";
getline(cin, digalpha);
for (size_t i {}; i < digalpha.size(); i++)
if (isdigit(digalpha.at(i)))
digalpha.erase(i,1);
cout << digalpha << endl;
cout << endl;
return 0;
In the first sentence you were writing that you are using C++14.
In "more modern" C++ the usage of algorithm is recommended. So normally you would not use C-Style For loops.
The standard approach that you can find everywhere, is a combination of erase with std::remove_it. You will find this construct in many many examples.
Please consider to use such a solution instead of a for loop.
You can even include the output in an algorithm using std::copy_if.
Please see:
#include <string>
#include <iostream>
#include <algorithm>
#include <iterator>
int main()
{
std::string test1{ "H23ey Th2e3re St01ack O34verflow" };
std::string test2{ test1 };
// C++ standard solution for erasing stuff from a container
test1.erase(std::remove_if(test1.begin(), test1.end(), ::isdigit), test1.end());
std::cout << test1 << "\n\n";
// All in one alternative
std::copy_if(test2.begin(), test2.end(), std::ostream_iterator<char>(std::cout), [](const char c) { return 0 == std::isdigit(c); });
return 0;
}
If there's two digits next to each other, it skips the second digit. This happens because the index, i, keeps going up, even though everything got shifted over:
for (size_t i {}; i < digalpha.size(); i++)
if (isdigit(digalpha.at(i)))
digalpha.erase(i,1); //Here, i goes up anyway, skipping character after digit
To fix this, we just have to decriment i after erasing a digit:
for (size_t i {}; i < digalpha.size(); i++) {
if (isdigit(digalpha.at(i))) {
digalpha.erase(i,1);
i--;
}
}
So I'm a beginner programmer... and I can't figure out what the problem is in this bit of code I'm writing for a text adventure. All I want it do At the moment is let the user enter a command, and then it converts it to ALLCAPS and prints that out. It should output this:
What shall I do?
pie
Your raw command was: PIE
But instead, it outputs this:
What shall I do?
pie
PIE
...and then it freezes. Here's the code:
#include <iostream>
#include <string>
#include <cctype>
#include <cstring>
#include <vector>
using namespace std;
void command_case();
string userIn;
string raw_command;
int x = 0;
int main()
{
while(raw_command != "QUIT")
{
cout << "What shall I do?\n";
cin >> userIn;
command_case();
cout << "Your raw command was: " << raw_command << endl;
}
return 0;
}
void command_case()
{
char command[userIn.size()+1];
strcpy(command, userIn.c_str());
while(x < userIn.size()+1)
{
if(islower(command[x]))
{
command[x] = toupper(command[x]);
cout << command[x];
x++;
}
else if(isupper(command[x]))
{
cout << command[x];
x++;
}
}
raw_command = command;
}
I think it may be a problem with the while loop in void command_case(), but I can't figure out exactly what that problem is. I'd appreciate any advice you can give me.
One too much:
while(x < userIn.size()+1)
The problem is with the x variable in the command_case() function.
When x becomes 3 (and "command[x] points to the null character at the end of "pie")
neither islower(command[x]) or isupper(command[x]) are true.
Neither section of the if statement executes, so x stays at 3 forever.
Since "userIn.size()+1" is 4, and x never reaches 4, the loop never exits.
A possible solution is remove the "x++" from both sections of the if statement, and have a single "x++" after the if statement. This will increment x during every loop regardless of what character "command[x]" points to.
You could easily do something like
void command_case()
{
for(int i =0; i<userIn.size(); i++)
{
userIn[i] = toupper(userIn[i]);
}
}
then cout<<userIn in the main
You should remove all cout calls from command_case() function. In fact the whole if-branch in the function is useless and you could just replace it with the following:
command[x]=toupper(command[x]);
For the simplicity you could replace the whole command_case() function with (just remember to #include <algorithm>):
std::transform(userIn.begin(), userIn.end(), userIn.begin(), toupper);
The first line contains an integer n (1 ≤ n ≤ 100). Each of the following n lines contains one word. All the words consist of lowercase Latin letters and possess the lengths of from 1 to 100 characters.
(Source: http://codeforces.com/problemset/problem/71/A)
How would you get input from the user given n? I tried using a while loop but it doesn't work:
#include <iostream>
using namespace std;
int main()
{
int n;
cin>>n;
int i;
while (i<=n) {
cin>>i ;
i++;
}
}
You probably meant to have something like:
#include <iostream>
int main() {
int n;
cin>>n;
int theInputNumbers[n];
for(int i = 0; i<n; ++i) {
cin >> theInputNumbers[i];
}
}
Your loop is really quite far off of what you need. What you wrote is extremely wrong such that I cannot provide advice other than to learn the basics of loops, variables, and input. The assistance you need is beyond the scope of a simple question/answer, you should consider buying a book and working through it cover to cover. Consider reading Programming Principles and Practice Using C++
Here is a working example of something approximating your question's requirements. I leave file input and output as an exercise up to you. I also make use of C++11's front and back std::string members. You would have to access via array index in older versions.
#include <iostream>
#include <string>
#include <sstream>
using namespace std;
int main(){
int totalWords;
cin >> totalWords;
stringstream finalOutput;
for (int i = 0; i < totalWords; ++i){
string word;
cin >> word;
if (word.length() > 10){
finalOutput << word.front() << (word.length() - 2) << word.back();
}else{
finalOutput << word;
}
finalOutput << endl;
}
cout << endl << "_____________" << endl << "Output:" << endl;
cout << finalOutput.str() << endl;
}
With that said, let me give you some advice:
Name your variables meaningfully. "int i" in a for loop like I have above is a common idiom, the "i" stands for index. But typically you want to avoid using i for anything else. Instead of n, call it totalWords or something similar.
Also, ensure all variables are initialized before accessing them. When you first enter your while loop i has no defined value. This means it could contain anything, and, indeed, your program could do anything as it is undefined behavior.
And as an aside: Why are you reading into an integer i in your example? Why are you then incrementing it? What is the purpose of that? If you read in input from the user, they could type 0, then you increment by 1 setting it to 1... The next iteration maybe they'll type -1 and you'll increment it by 1 and set it to 0... Then they could type in 10001451 and you increment by 1 and set it to 10001452... Do you see the problem with the logic here?
It seems like you are trying to use i as a counter for the total number of iterations. If you are doing this, do not also read input into i from the user. That completely undermines the purpose. Use a separate variable as in my example.