Keep output and input from alternating? - c++

I am very new to coding, and have been practicing with some easy problems at codeforces.com. I was working on this problem, but it seemed to be asking for the input (all at once) yielding the output (all at once). I can only figure out how to get one output at a time.
Here are the basic instructions for the problem:
Input
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.
Output
Print n lines. The i-th line should contain the result of replacing of the i-th word from the input data.
Examples
input
4
word
localization
internationalization
pneumonoultramicroscopicsilicovolcanoconiosis
output
word
l10n
i18n
p43s
Here is my code:
#include <iostream>
#include <string>
using namespace std;
void wordToNumbers(string word){
int midLetters = word.length();
char firstLetter = word.front();
char lastLetter = word.back();
cout <<firstLetter <<(midLetters-2) <<lastLetter <<endl;
}
int main(){
string wordInput;
string firstNum;
getline(cin,firstNum);
int i = stoi(firstNum);
for(i>=1; i--;){
getline(cin,wordInput);
if (wordInput.length() > 10){
wordToNumbers(wordInput);
} else {
cout <<wordInput <<endl;
}
}
return 0;
}

it's perfectly fine to read and print output for the lines one by one.
Exactly your solution accepted: http://codeforces.com/contest/71/submission/16659519

I'm also a beginner in c++. My idea would be to save every line first in a buffer and then write everything to std::cout.
I use a std::vector as the buffer, cause IMO it is simple to understand and very useful in many cases. Basically it is a better array. You can read more about std::vector here.
#include <iostream>
#include <string>
//for use of std::vector container
#include <vector>
using namespace std;
void wordToNumbers(string word){
int midLetters = word.length();
char firstLetter = word.front();
char lastLetter = word.back();
cout <<firstLetter <<(midLetters-2) <<lastLetter <<endl;
}
int main(){
string wordInput;
string firstNum;
//container for buffering all our strings
vector<string> bufferStrings;
getline(cin,firstNum);
int i = stoi(firstNum);
//read line by line and save every line in our buffer-container
for(i>=1; i--;){
getline(cin,wordInput);
//append the new string to our buffer
bufferStrings.push_back(wordInput);
}
//now iterate through the buffer and write everything to cout
for(int index = 0; index < bufferStrings.size(); ++index) {
if (bufferStrings[index].length() > 10){
wordToNumbers(bufferStrings[index]);
} else {
cout <<bufferStrings[index] <<endl;
}
}
return 0;
}
Probably this is not the best or most beautiful solution, but it should be easy to understand :)

Related

Logical Issue or Syntax issue with sorting String function

I'm new to C++ and coding in general. I'm attempting to make a simple program that essentially takes in two words and will tell you if these two words are anagrams or not.I also understand that there is likely a pre-made function to sort a string, like an array however I am trying to grasp the concept itself and hence why I'm attempting to make the function.
Here is a quick snippet of the code I've written so far.
Snippet of code
The issue that I'm currently having is that when I call the function to sort the string, the string isn't sorted! Sorry if there is a simple solution to this, I'm fairly new. Is this a logical issue or syntax based? Thank you so much!
#include <iostream>
#include <string>
using namespace std;
//Function Declarations
string sortString(string user_input);
//Program Body
int main()
{
string user_input_one, user_input_two;
cout << "Welcome to Sandip's Anagram Checker! \nPlease Input two words that you'd like the check!";
sortString(user_input_one);
sortString(user_input_two);
if (user_input_one == user_input_two)
cout << "These two words are Anagrams of each other!";
else
cout << "These are not Anagrams!";
return 0;
}
//Function Definations
string sortString(string user_input)
{
string temp_string = user_input;
int i,j;
for (i = 0; i<user_input.length();i++)
{
for (j=0; j<user_input.length();j++)
{
if (user_input[i] == user_input[j])
{
temp_string[i] = user_input[j];
}
else if (user_input[i] > user_input[j])
{
temp_string[i] = user_input[j];
}
else if (user_input[i] < user_input[j])
{
temp_string[i] = user_input[i];
}
}
}
return temp_string;
}
Adding to Daniel's answer, you don't need a temporary string in the sorting function, just process the passed string and return it. Also consider supporting letter cases as well, you can use std::transform from the STL algorithm library.
#include <algorithm>
Add this before looping in your sorting function or after taking inputs in main.
transform(user_input.begin(), user_input.end(), user_input.begin(), ::tolower);
There are a couple issues. You're not actually reading any user input. You can fix this by adding cin >> user_input_one >> user_input_two;.
Your sorting also doesn't work quite right. It looks similar to selection sort, so I tweaked it to be a variation of that. For each character in the string, it goes through the rest of the string and swaps letters if the later one should be first.
string temp_string = user_input;
int i, j;
for (i = 0; i < user_input.length(); i++)
{
for (j = i + 1; j < user_input.length(); j++)
{
if (temp_string[j] < temp_string[i]) {
swap(temp_string[i], temp_string[j]);
}
}
}
return temp_string;
Lastly, as #cigien commented, you aren't using the sorted result. You can change this by replacing your lines calling sortstring() with this:
user_input_one = sortString(user_input_one);
user_input_two = sortString(user_input_two);

Using isalpha function with string pointers

Hey I'm quite new to programming and I'm having trouble using the isalpha function in my programme. This a part of the code for a palindrome class. What I'm trying to do is remove all the non alphabetic characters from the input. So if the user inputs "Hi, How are you" I need to first count the size of the array of just the letters then in my removeNonLetters subclass, I need to get rid of the non alphabetical characters. Can someone please help me with this. Thank you so much!
#include <iostream>
#include <string>
#include <stdio.h>
#include <algorithm>
#include <cctype>
#include <cstring>
#include <ctype.h>
using namespace std;
class palindrome
{
private:
int only_letters_size;
string input_phrase;
string* only_letters;
public:
string inputPhrase();
string removeNonLetters();
string* new_Array;
int size_new_Array;
};
string palindrome::inputPhrase()
{
cout << "Input phrase: "; //asks the user for the input
getline(cin,input_phrase);
size_new_Array = input_phrase.length(); //creating a dynamic array to store
the input phrase
new_Array = new string[size_new_Array];
int i;
for (i=0; i<size_new_Array; i++)
{
new_Array[i]=input_phrase[i];
}
only_letters_size = 0;
while(new_Array[i])
{
if (isalpha(new_Array[i])) //PROBLEM OCCURS HERE
{
only_letters_size=only_letters_size+1;
}
}
cout << only_letters_size << endl;
return new_Array;
}
string palindrome::removeNonLetters()
{
int j=0;
int str_length = new_Array.length(); //string length
only_letters = new string[only_letters_size];
for (int i=0;i<size_new_Array;i++) //PROBLEM OCCURS HERE AS WELL
{
if (isalpha(new_Array[i]))//a command that checks for characters
{
only_letters[j] = new_Array[i];//word without non alphabetical c
characters is stored to new variable
j++;
}
}
cout << only_letters << endl;
return only_letters;
}
I've found the best way to determine if a string is a palindrome is to walk toward the center from both sides. In your case I would just opt to skip non-alpha characters like so.
bool is_palindrome(string mystring)
{
int start = 0, end = mystring.length() - 1;
while (start < end)
{
// Skip over non-alpha characters
while (!isalpha(mystring[start]))
{
start++;
}
while (!isalpha(mystring[end]))
{
end--;
}
if (tolower(mystring[start]) != tolower(mystring[end]))
{
return false;
}
else
{
start++;
end--;
}
}
return true;
}
If you must save the input first and remove nonalpha characters, I would do it like this.
string remove_non_alpha(string mystring)
{
string ret_string = "";
for (int i = 0; i < mystring.length(); i++)
{
if (isalpha(mystring[i]))
{
ret_string += tolower(mystring[i]);
}
}
return ret_string;
}
And then feed the result into the above function.
Sorry for being hard, but your trying far too much copying around. You can achieve all this with one single loop after retrieving your data and all on one single string object (unless you want to keep the original input for some other purposes):
getline(cin,input_phrase);
std::string::iterator pos = input_phrase.begin();
for(char c : input_phrase)
{
if(isalpha(c))
{
*pos++ = tolower(c);
}
}
input_phrase.erase(pos, input_phrase.end());
After that, your string is ready to use...
Explanation:
std::string::iterator pos = input_phrase.begin();
An iterator something similar than a pointer to the internal data of the string. We keep the position to move the alpha only characters to, skipping the non-alpha ones.
for(char c : input_phrase)
Simply iterating over all characters...
if(isalpha(c))
The essential check, is the current character an alpha one?
*pos++ = tolower(c);
If so, convert it to lower case immediately. Assign it to the current string position, and advance the "pointer" (iterator!).
input_phrase.erase(pos, input_phrase.end());
And at very last, drop the remaining part of the string occupied with surplus characters. You might note that there might be some characters you wanted to keep within, but you copied these to a position more to the left already...

How do I use the .find() in a while or for loop and have not give the same found value each time

I'm trying to build a function that goes through a while or for-loop and finds where the space is, outputs everything before the space, and then erases everything before the space including the space, and then repeats this again.
Any help is much appreciated.
int sentence()
{
string enteredSentence="";
getline(cin,enteredSentence);
string sentenceString(enteredSentence);
int sentenceLength=enteredSentence.size();
cout<<"size of sentence"<<sentenceLength<<endl;
int stringSize=sentenceString.size();
while(stringSize>0)
{
int spaceLoc = enteredSentence.find(" ");
cout<<spaceLoc;
cout<<sentenceString.substr(0,spaceLoc)<<endl;
sentenceString.substr(0,spaceLoc);
cout<<"string before string eraced"<<sentenceString<<endl;
sentenceString.erase (0,spaceLoc);
cout<<"string after string eraced"<<sentenceString<<endl;
stringSize=sentenceString.size();
cout<<"string size is"<<stringSize<<endl;
}
This is how I fixed your code:
#include <iostream>
using namespace std;
int main()
{
string enteredSentence="";
getline(cin,enteredSentence);
string sentenceString(enteredSentence);
int sentenceLength = enteredSentence.size();
cout<<"size of sentence:"<<sentenceLength<<endl;
string::size_type stringSize = sentenceString.size();
while(stringSize > 0)
{
int spaceLoc = sentenceString.find(" "); //there was incorrect var
cout<<spaceLoc<<endl;
if(spaceLoc == string::npos){
cout<<"last part:"<<sentenceString<<endl;
break;
}//check if there are no spaces left
cout<<sentenceString.substr(0,spaceLoc)<<endl;
//the substr line here was redundant
cout<<"string before string erased:"<<sentenceString<<endl;
sentenceString.erase(0, spaceLoc + 1);//also delete the space
cout<<"string after string erased:"<<sentenceString<<endl;
stringSize=sentenceString.size();
cout<<"string size:"<<stringSize<<endl<<endl;
}
return 0;
}
You could use a stringstream.
#include <sstream>
#include <iostream>
using namespace std;
int main(int argc, char* argv[]) {
string enteredSentence; // It's initialized to "" by default, by the way
getline(cin,enteredSentence);
cout<<"size of sentence: "<<enteredSentence.length()<<endl;
istringstream str_in(enteredSentence);
string word;
while(str_in >> word) {
// Do stuff with word
// I believe str_in.str() will also give you the portion that hasn't yet been processed.
}
return 0;
}
I'm not 100% sure that I understand what you want to achieve. But I can help you with find:
It has a second parameter that specifies from where on in the string the search will start:
size_t pos = 0;
while ((pos = str.find(' ', pos)) != std::string::npos) {
std::cout << "Found a space at " << pos << std::endl;
++pos;
}
Reference
With more information on what you actually want your code to do (show example input plus wanted output) I can help you clear the rest of your code.
Currently your description suggests that you want to output the entire string, but in pieces (separated by spaces).
Your code makes a (needless?) copy of your input, generates substrings only to throw them away and doesn't return an int as said in the function declaration.
If you want to tokenize your input then this question has some answers for you.

Comparing numbers in strings to numbers in int?

I'm trying to make a program that will open a txt file containing a list of names in this format (ignore the bullets):
3 Mark
4 Ralph
1 Ed
2 Kevin
and will create a file w/ organized names based on the number in front of them:
1 Ed
2 Kevin
3 Mark
4 Ralph
I think I'm experiencing trouble in line 40, where I try to compare the numbers stored in strings with a number stored in an int.
I can't think of any other way to tackle this, any advice would be wonderful!
#include <iostream>
#include <fstream>
#include <vector>
#include <cstdlib>
using namespace std;
int main()
{
ifstream in;
ofstream out;
string line;
string collection[5];
vector <string> lines;
vector <string> newLines;
in.open("infile.txt");
if (in.fail())
{
cout << "Input file opening failed. \n";
exit(1);
}
out.open("outfile.txt");
if (out.fail())
{
cout << "Output file opening failed. \n";
exit(1);
}
while (!in.eof())
{
getline(in, line);
lines.push_back(line);
}
for (int i = 0; i < lines.size(); i++)
{
collection[i] = lines[i];
}
for (int j = 0; j < lines.size(); j++)
{
for (int x = 0; x < lines.size(); x--)
{
if (collection[x][0] == j)
newLines.push_back(collection[x]);
}
}
for (int k = 0; k < newLines.size(); k++)
{
out << newLines[k] << endl;
}
in.close( );
out.close( );
return 0;
}
Using a debugger would tell you where you went wrong, but let me highlight the mistake:
if (collection[x][0] == j)
You're expecting a string like 3 Mark. The first character of this string is '3', but that has the ASCII value of 51, and that is the numerical value you'll get when trying work with it is this way! This will never equal j, unless you've got a lot of lines in your file, and then your search system will not work at all like you wanted. YOu need to convert that character into an integer, and then do your comparison.
C++ offers many way to process data via streams, including parsing simple datafiles and converting text to numbers and vice versa. Here's a simple standalone function that will read a datafile like you have (only with arbitrary text including spaces after the number on each line).
#include <algorithm>
// snip
struct file_entry { int i; std::string text; };
std::vector<file_entry> parse_file(std::istream& in)
{
std::vector<file_entry> data;
while (!in.eof())
{
file_entry e;
in >> e.i; // read the first number on the line
e.ignore(); // skip the space between the number and the text
std::getline(in, e.text); // read the whole of the rest of the line
data.push_back(e);
}
return data;
}
Because the standard way that >> works involves reading until the next space (or end of line), if you want to read a chunk of text which contains whitespace, it will be much easier to use std::getline to just slurp up the whole of the rest of the current line.
Note: I've made no attempt to handle malformed lines in the textfile, or any number of other possible error conditions. Writing a proper file parser is outside of the scope of this question, but there are plenty of tutorials out there on using C++'s stream functionality appropriately.
Now you have the file in a convenient structure, you can use other standard c++ features to sort it, rather than reinventing the wheel and trying to do it yourself:
int sort_file_entry(file_entry a, file_entry b)
{
return a.i < b.i;
}
int main()
{
// set up all your streams, etc.
std::vector<file_entry> lines = parse_file(in);
std::sort(lines.begin(), lines.end(), sort_file_entry);
// now you can write the sorted vector back out to disk.
}
Again, a full introduction to how iterators and containers work is well outside the scope of this answer, but the internet has no shortage of introductory C++ guides out there. Good luck!

C++ Find word in sentence

I've got a task to find the word "EYE" in a sentence (more like just line of chars) such as: EYEYECARASDFG. As you can see, the word "EYE" is there twice, overlapping each other. I am suppose to cout how many times the word "EYE" occurs in the sentence. I wrote some code that looks like this:
#include <iostream>
#include <string>
using namespace std;
string sentence;
int main()
{
int i = 0;
cin >> sentence;
while()
{
if (std::string::npos != sentence.find("EYE"))
{
i++;
}
}
cout << i;
}
Now without the while loop, it finds the EYE in the sentence and it kinda works. So I though, to count with the overlapping and make the code running until it hits the end, I need to loop it. So I though the while loop would be the best, but I don't know how to loop it, what to put into the brackets for while loop
First of all condition in while is required. If you want infinite loop use true as your statement. As a first draft, try to make it with "brute force". Just check every 3 letters substring of your sentence if equals "EYE". It will be one loop and 3 conditions or 2 loops and 1 condition. Then read about some text search algorithm e.g KMP.
If you just want to make this code run use following coed:
int pos = 0;
while(true) {
pos = sentence.find("EYE", ++pos);
if (pos != std::string::npos) {
i++;
} else break;
}
You can do this using a finite-state machine. (Google it.) That is efficient and easy to understand. As you read the characters, there are three states to distinguish, i.e., 1) when the most recent letter seen was an "E", 2) when the last two seen were "EY" in that order, and 3) everything else. As you go through a character at at time, increase the "found"-count by one whenever you are in state 2 and find another "E".
See if you can take it from there with no more hints.
The idea can be extended to arbitrary strings besides "EYE", and you can write a compiler of sorts to generate the finite-state machines for those strings. But that is a more advanced assignment.
#include<iostream>
#include<string>
using namespace std;
main()
{
string sen, sub;
int pos;
cout<<"Enter the Sentence"<<endl;
getline(cin,sen);
cout<<"Enter string to find"<<e`ndl;
cin>>sub;
for (int i=1;(pos=sen.find(sub)) != -1 ;i++)
{
sen=sen.substr(++pos);
cout<<"Found = "<<sub<<" "<<i<<" Times"<<endl;
}``
}
Code Snippet :
#include <bits/stdc++.h>
using namespace std;
int main()
{
string input, word;
getline(cin, input);
cin>>word;
int cnt=0;
size_t pos = input.find(word, 0);
while(pos != string::npos)
{
cnt++;
pos = input.find(word, pos+1);
}
cout<<cnt<<endl;
return 0;
}
Input :
Python Programming Python
Python
Output : 2