This question already has answers here:
Testing stream.good() or !stream.eof() reads last line twice [duplicate]
(3 answers)
Why is iostream::eof inside a loop condition (i.e. `while (!stream.eof())`) considered wrong?
(5 answers)
Closed 24 days ago.
I'm currently working on the "Name That Number" USACO training problem.
It takes a number as input and outputs any matching names found in a dictionary using touch tone telephone keymapping.
The full code consistently gets a bad_alloc thrown on the USACO grader. I've been coding in a replit and it runs fine each time. I've also tried commenting out different parts of the code and running it on the USACO grader but sometimes it runs fine and sometimes it gets a bad_alloc thrown. I think it has something to do with my 2d array of vectors but I'm not sure exactly what or how to fix it.
/*
ID:*****
TASK: namenum
LANG: C++14
*/
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
using namespace std;
//function that takes letter and returns associated number
int convert(int letter){ //implicit conversion
if (letter < 81){
letter = letter - 65;
}
else {
letter = letter - 66;
}
int modify = letter % 3;
letter = (letter - modify) / 3 + 2;
return letter;
}
int main() {
ifstream numin ("namenum.in");
ifstream dictin ("dict.txt");
ofstream fout ("namenum.out");
//2d array storing vectors that will store matching names for that index
vector<string> names[8][8]{};
//read names in from dict and store in table
while (dictin.good())
{
string name{};
dictin >> name;
if (name[0] != 'Z' && name[1] != 'Z'){
int i = convert(name[0]) - 2;
int j = convert(name[1]) - 2;
names[i][j].push_back(name);
}
}
//read in digits from input
string digits{};
numin >> digits;
//output matches
int index1 = static_cast<int>(digits[0]) - 50;
int index2 = static_cast<int>(digits[1]) - 50;
string output{};
//check for matches
if (index1 >= 0 && index1 <= 8 && index1 >= 0 && index1 <= 8){
for (int i = 0; i < names[index1][index2].size(); i++){
string matchdigits{};
for (int j = 0; j < names[index1][index2][i].length(); j++){
matchdigits += static_cast<char>(convert(names[index1][index2][i][j]) + 48);
}
if (matchdigits == digits){
output = names[index1][index2][i] + "\n";
}
}
}
if (output == ""){
output = "NONE\n";
}
fout << output;
return 0;
}
I am trying to solve such competitive programming problem:
Alex likes to laugh a lot. Laughter is a sequence of alternating letters "a" and "h". For example, "ahahaha", "hah" and "a" are laughter and "abacaba" and "hh" are not.
Alex speaks very quickly, so all his words merge into one big one. You need to find out how long he can laugh. You have a line - a recording of Alex's conversation. Determine the maximum length of laughter in this conversation.
Input file is called "laugh.in"
Output file is called "laugh.out"
Input data:
The first line of the input file contains a single integer N (1 < N ≤ 10^5) - the length of the string with Alex's conversation. The second line contains a string of small Latin letters of length N - recording Alex's conversation.
Output data:
Output one number - the longest laugh length in Alex's conversation
Here's some examples of how input/output data must look like.
Examples:
Input in laugh.in
5
ahaha
Output in laugh.out
5
Input in laugh.in
24
ahahrunawayahahsofasthah
Output in laugh.out
4
Input in laugh.in
10
ahahaahaha
Output in laugh.out
5
So, here is my code, that is supposed to solve given problem:
#include <algorithm>
#include <cstdio>
#include <iostream>
using namespace std;
int main()
{
freopen("laugh.in", "r", stdin);
freopen("laugh.out", "w", stdout);
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n, i;
cin >> n;
char *s = new char[n + 1];
getchar();
for (i = 0; i < n; i += 1)
{
s[i] = getchar();
}
s[n] = '\0';
int max_length = 0;
int length = 0;
for (i = 0; i < n; i += 1)
{
length += !length && (s[i] == 'a' || s[i] == 'h');
if ((s[i] == 'a' && s[i + 1] == 'h') ||
(s[i] == 'h' && s[i + 1] == 'a'))
{
length += 1;
}
else
{
max_length = max(max_length, length);
length = 0;
}
}
cout << max(max_length, length) << endl;
delete[] s;
return 0;
}
It only passes 13 tests with other 33 resulting in "Wrong answer" verdict.
So why my code is not working? Please, give counter examples to it or explain error.
Any help would be highly appreciated.
First of all, do not write everything in main (learn to avoid it ASAP).
Secondly, the task doesn't say anything about opening files.
Avoid the use of new delete in modern C++; it is a bad practice to use it.
Here is pattern you can start over:
size_t laugh_length(const std::string& s)
{
...
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
size_t l;
cin >> l;
std::string s;
s.reserve(l);
cin >> s;
cout << laugh_length(s) << '\n';
}
After an extra comment form OP I see another bit problem with OP code:
ios::sync_with_stdio(false);
and then use of:
getchar();
which is cstdio API which synchronization has been disabled.
https://wandbox.org/permlink/PJzjc1joKQgmpbwa
vs https://wandbox.org/permlink/aH3OypI94CpgNuxd
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 4 years ago.
Improve this question
This a function of a code I wrote that subtracts two values which are both of type character over and over again to get a text, but the result is not a text of string but symbols instead.
I checked by cout that the keyLetters and analysis have both correct values in ASCII and clear letters before converting them to int.
The lengthText is correct too.
keyLetters is a word of 5 letters.
void originalText(string analysis, string keyLetters) {
int lengthText=analysis.length();
char originText[2000];
int hold;
int k;
for (int i=0; i<lengthText; i++) {
if(i%5==0)
k=0;
hold=keyLetters[k]-analysis[i];
if (hold<=0)
hold*=-1;
originText[i]=(char)hold;
cout<<originText[i];
k++;
}
}
A screenshot of the result I get:
Both keyLetters and analysis consist of characters between 'a' and 'z'.
That means the difference between characters in these two can be from -25 ('a' - 'z') up to +25 ('z' - 'a').
Then you want to represent this difference using ascii characters, multiplicing by -1 the negative case. Nothing simpler:
void originalText(string analysis, string keyLetters) {
int lengthText = analysis.length();
char originText[2000];
int hold;
int k;
for (int i = 0; i < lengthText; i++) {
if (i % 5 == 0) {
k = 0;
}
hold = keyLetters[k] - analysis[i];
if (hold < 0) {
hold *= -1;
}
originText[i] = (char)hold + 'a';
cout << originText[i];
k++;
}
}
You need shift the value in range <0,25> to printable small ascii characters <'a','z'> by adding a 'a' ascii value, that is 97. The range <0,25> in ascii are just control characters.
This will result in:
The decrypted text:
oncegpmnahioethejewasalihtpegirpehmwantedhoplacallthedacandihedidnmtcareabmuhhejshudcahallinschomlherlarenhsgetangjcatherallhhetimebutihedidnmtcareabmuhhejparentifeelingiwhethejthecareangrymriadiheeaisgchabadgirplehuinohbeashejnefejeverhakecaremfevejchhingarogndcogsharhingfjoocogrlarenhstilpcogshudieiatichooltakealpthatieriogslcbestmfpucknmtheshorcdmesnohfiniihherethereismojetmihthatgirlonedaceenhtmschomlwhichiiuniveriitcactualpcbgtleolletendhosacabogtitschmolhhatihiimojecommonandidonnohknmwanyeacthatgirlofcogriewenhtognivejsitymrcollegeifihavetmsacwhenihegohopdejlikeehenshebecameeighheenceariopdsmahuniversitcthereeaiapotmfitudcforhejtodoehichihehohallcicrewgpsmshecjiedandcriedalohahnighhsfhejshecamhmmeandherkindpajentsasqedhejabmuhthereasmnforhejunitmppabpeteajsthaheairgnningouhfjomhejeyesconhinuogspchmwevejsherefgsedtmtellmrsacanyhhingiinceiheeantedtmshayalmnehhatnighthereishwasfglfilledsoathhahnighhshesleltaloneinthedarqeihhmutanconebesideihejtmeahchhejandtmtakecajeofherinhersleepingasshedidhoherlajenhsanditgdiesehenshewascoungersmthecccpehasgothejrogndshapnotfrmmnmwherebgtbecauseofareaionandthatjeaionisbecauiehhingieillcomebackholeolleafhejthecdidhheminanctimeeihhmutanceajningmralejt
As to why this doesn't give the correct text, I leave that to OP, because i don't get this method of encryption.
The whole program:
#include <iostream>
#include <string>
#include <fstream>
#include <cmath>
using namespace std;
string encryptText(string, string);
string cryptanalyzeText(string);
void originalText(string, string);
int main() {
string text, analysis;
string key;
text = "onceuponatimetherewasalittlegirlwhowantedtoplayallthedayandshedidnotcareaboutherstudyatallinschoolherparentsgetangryatherallthetimebutshedidnotcareaboutherparentsfeelingswhethertheyareangryorsadshewassuchabadgirlletusnotbeasherneverevertakecareofeverythingaroundyoustartingfromyourparentstillyoustudiesatschooltakeallthatseriouslybestoflucknothestorydoesnotfinishherethereismoretoitthatgirlonedaywenttoschoolwhichisuniversityactuallybutpeopletendtosayaboutitschoolthatitismorecommonandidonnotknowanywaythatgirlofcoursewenttouniversityorcollegeifihavetosaywhenshegotolderlikewhenshebecameeighteenyearsoldsoatuniversitytherewasalotofstudyforhertodowhichshetotallyscrewupsoshecriedandcriedalotatnightsftershecamhomeandherkindparentsaskedheraboutthereasonforherunstoppabletearsthatwasrunningoutfromhereyescontinuouslyhoweversherefusedtotellorsayanythingsinceshewantedtostayalonethatnightherwishwasfulfilledsoatthatnightshesleptaloneinthedarkwithoutanyonebesideshertowatchherandtotakecareofherinhersleepingasshedidtoherparentsandstudieswhenshewasyoungersothecyclehasgotherroundshapnotfromnowherebutbecauseofareasonandthatreasonisbecausethingswillcomebacktopeopleaftertheydidtheminanytimewithoutanywarningoralert";
analysis = "qegegrfrafkdittgiiwmurpifvcigutcahayrrtqfkspxcpelxvyidmarrdejvhippfxcmtvebawkledukydkckelxkewctqfphqtgerqpkwgqvrrgdarxhqtrplfjvxiygsytejvhippfxcmtvebawkledrrvezvjjeqnzrgeyyittgixhqarvempxvyatjedejvaaeulghmdrhgutcpefwjrofdvestgirehgiivqtkekqerveahvzedaklizirvogpucogukerfkekfdqdcogtgerqpkwtunccogukydugjeteeysoxvroemncxhmvjiruqlwlkdvwtahcycwpfxhquksrkffiszqkjizkjlhqtvxhqtvmsyqiitakkxhmvxmrxqeidmaninfvfwctqfpwtktliewemvqtjmtkctxumnccbgvgiobnvxezfkssmarfogvzxsojfslfjrxifkjqodgtsmyqeenpkusnzqkonayrryicpxhmvxmrxqwgogtjiwqpkxogpzzeduzxyattslxgxiirkyevqvfwakyyinejvkofqchednzoeijvrstgsicmoviisjkiezavereqchsackynuxvvsuvpxhqtvaaeccstahjxupawsrtgixopqnliojjlefqkelxajgrqyltsauyicdkvhazftviqfrpofckrisjkwffgiwhqerqhaovenpjvvkuputadgexsmubidtgiebawkxhqtvesapwsrtgiynevftpmdcitqciwttckaaetlrnupxsufhismtgiiyqutsnfkeyogucchayvzeduyirqhlwepvfxexnfvsmarryfjzrgekegeejvaazvvhtaukeymnfrefjrxnuiyxhqtnmstyrwfgnwmlxguwomvklafpzkhfuyisxggxaxqeiizvyidmtbaifjfytmppsnqdvwipgjledvfaafeyledcehtavroeociiorjvvizjvvsxgvtizirwstgumdfqyirbciinfurrdevlhiqunlezuyiwmupsuzivvsavyickecihmuxsttgivogpuwhmrestrtfqnayyirqdlxbqerysqqwerqcjsnmpuxhmviiaeqemsngteuegklizijaixntsmqdrgkfqgiobnveffgixhqaumdfjvqizcectuovaifjfytmppaadpzrgatrpedv";
cout<<"\n1- The original text:\n"<<text;
cout<<"\n\nEnter a key of type string: ";
key = "cream";
cout<<endl;
cout<<"The text after it has been encrypted:\n"<<encryptText(text, key)<<endl;
cout<<"\n2- An encrpted text:\n"<<analysis;
string keyLetters= cryptanalyzeText(analysis);
cout<<"\n\nThe key is: "<<keyLetters<<endl<<endl;
cout<<"The decrypted text:\n";
originalText(analysis, keyLetters);
cout<<endl<<endl;;
return 0;
}
string encryptText(string text, string key) {
int lengthText=text.length();
int lengthKey=key.length();
int count=0;
for (int i=0; i<lengthText; i++) {
text[i]=key[count];
if (count<lengthKey-1)
count++;
else
count=0;
}
return text;
}
string cryptanalyzeText(string analysis) {
string keyLetters="aaaaa";
char ch;
int i;
int lengthText=analysis.length();
for (int keyPlace=0; keyPlace<6 ; keyPlace++) {
int alphabet[26]={0};
for (i=keyPlace; i<lengthText; i=i+5) {
ch=analysis[i];
alphabet[ch - 'a']++;
}
int max=alphabet[0];
int maxPlace=0;
for (int j=1; j<26; j++) {
if(max<alphabet[j]) {
max=alphabet[j];
maxPlace=j;
}
}
keyLetters[keyPlace]=maxPlace-4;
if (keyLetters[keyPlace]<0)
keyLetters[keyPlace]+=26+97;
else
keyLetters[keyPlace]+=97;
}
return keyLetters;
}
void originalText(string analysis, string keyLetters) {
int lengthText=analysis.length();
char originText[2000];
int hold;
int k;
for (int i = 0; i < lengthText; i++) {
if (i % 5 == 0) {
k=0;
}
hold = keyLetters[k] - analysis[i];
if (hold < 0) {
hold *= -1;
}
originText[i] = (char)hold + 'a';
cout << originText[i];
k++;
}
}
It appeared that since the encrypted text has been generated by %26 (mod 26), the values of the letters that was larger than 26 lost its original values. So when they have been decrypted, they were generated as incorrect letters. That's why I had to return the 26 they have lost, before doing the subtraction procedure, as it will be subtracted correctly.
void originalText(string analysis, string keyLetters) {
int lengthText=analysis.length();
char originText[2000];
int hold;
int k;
for (int i = 0; i < lengthText; i++) {
if (i % 5 == 0) {
k=0;
}
hold = (analysis[i]+26)-keyLetters[k];
if (hold < 0) {
hold *= -1;
}
hold%=26;
originText[i] = (char)hold + 'a';
cout << originText[i];
k++;
}
}
The result of it:
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 7 years ago.
Improve this question
After a user enters a text (with spaces), how do I delete only the last consonant of that certain text?
I have no idea how to do that, whatever I did by now deleted all the consonants.
Have you tried something or you have no idea how to do it?
I'll assume you didn't do anything yet.
First of all, you have to find the last consonant. How do you do that. Well, you start from the end and check the letter until you find a consonant.
Now, when you find the last consonant, you memorize the position of the consonant and then move every letter that's to the right of the consonant to the left.
And lastly, change the last character in the string to the '\0'.
Here is the code:
#include <iostream>
#include <string>
#include <cctype>
bool isConsonant(char);
int main (int argc, char *argv[]) {
char s[80];
// Input the text
std::cout << "Enter the text: ";
std::cin.getline(s,80,'\n');
// Creating string object
std::string text(s);
int length = text.length();
// Searching for the last consonant
int i = length - 1;
while ((!isConsonant(text.at(i)) && (i)))
i--;
// Moving every letter after the last consonant one place to the left
for (int j = i; j < length - 1; j++)
text.at(j) = text.at(j+1);
text.at(length-1) = '\0';
// Printing the text to the standard output
std::cout << text;
return 0;
}
bool isConsonant(char c) {
if (isalpha(c)) {
char temp = c;
if (isupper(c))
temp = tolower(c);
return !((temp == 'a') || (temp == 'e') || (temp == 'i') || (temp == 'o') || (temp == 'u'));
}
return false;
}
Edit: Of course there are other ways to do this, and you should try to think of them. This is a first thing that came to my mind.
Hi I'm working a program to unscramble a set of letters and output all the words that can be made from that set of letters, for example: If i inputed the letters "vlei", the program would output "live", "evil", and "vile".
So far I have looked through the internet about this quiiiite a bit and can't find anything on my specific questions relevant to my skill level at this point (level 2 noob).
So far I have gotten as far as making all the possible combinations from the the given letters. Excluding any that are less than 7 letters, which is a problem.
This is the code I have so far:
string letter;
char newWord[7];
int main()
{
cout << "Type letters here: ";
cin >> letter;
for(int i = 0 ; i < 7 ; i++)
{
for(int j = 0 ; j < 7 ; j++)
{
for(int k = 0 ; k < 7 ; k++)
{
for(int l = 0 ; l < 7 ; l++)
{
for(int m = 0 ; m < 7 ; m++)
{
for(int n = 0 ; n < 7 ; n++)
{
for(int o = 0 ; o < 7 ; o++)
{
sprintf(newWord, "%c%c%c%c%c%c%c", letter[i], letter[j], letter[k], letter[l], letter[m], letter[n], letter[o]);
}
}
}
}
}
}
}
return 0;
}
I was wondering if anyone has any experience with anything like this, and can offer and hints or advice.
Specifically what I'm having difficulty with is how to read in a .txt file to use as a dictionary to compare words to.
Also, I was having trouble using strcmp() which is what I was planning to use to compare the scrambled words to the dictionary. So if there are any other maybe simpler ways to compare the two strings, that would be greatly appreciated.
Thanks in advance.
Hi guys, so I've just finished my program and I hope it can help someone else. Thanks a lot for all your help.
#include <iostream>
#include <fstream>
#include <string>
#include <cstring>
#include <stdio.h>
#include <stdlib.h>
#include <algorithm>
#include <vector>
#include <array>
using namespace std;
//declaring variables
int i;
int scores[531811]; //array for scores of found words
string wordlist[531811]; //array for found matched words
string word[531811]; //array of strings for dictionary words about to be read it
string tester;//string for scrambled letters that will be read in
int scorefinder(string scrab) //SCORE FINDER FUNCTION
{
int score = 0;
int x = 0;
int j = 0;
while (scrab[j])
{
char ltr = toupper(scrab[j]); //converts to all caps
//assings values to each letter and adds it to itself
if(ltr == 'A' || ltr == 'E' || ltr == 'I' || ltr == 'L' || ltr == 'N' || ltr == 'O' || ltr == 'R' || ltr == 'S' || ltr == 'T' || ltr == 'U')
x += 1;
else if(ltr == 'D' || ltr == 'G')
x += 2;
else if(ltr == 'B' || ltr == 'C' || ltr == 'M' || ltr == 'P')
x += 3;
else if(ltr == 'F' || ltr == 'H' || ltr == 'V' || ltr == 'W' || ltr == 'Y')
x += 4;
else if(ltr == 'K')
x += 5;
else if(ltr == 'J' || ltr == 'X')
x += 8;
else if(ltr == 'Q' || ltr == 'Z')
x += 10;
++j;
}
score = x;
return score;
}
int main () {
//READS IN DICTIONARY
ifstream file("words.txt"); //reads in dictionary
if (!file.is_open()){ //checks if file is being NOT read correctly
cout << "BROEKN \n"; //prints error message if so
}
if(file.is_open()){ //checks if file IS being read correctly
for(int i = 0; i < 531811; i++){
file >> word[i]; //read in each word from the file and
} //assigns each to it's position in the words array
}
//END OF READ IN DICTIONARY
cout << "Enter scrambled letters: ";
cin >> tester; //reads in scrambled letters
sort(tester.begin(),tester.end()); //sorts scrambled letters for next_permutation
while (next_permutation(tester.begin(),tester.end())){ //while there are still permutations available
for(i=0;i<531811;i++){
if ( is_permutation (word[i].begin(),word[i].end(), tester.begin())){
wordlist[i] = word[i]; //assigns found word to foundword array
scores[i] = scorefinder(word[i]); //assigns found word score to foundscore array
}
}
}
//PRINTS OUT ONLY MATCHED WORDS AND SCORES
for(i=0;i<531811;i++){
if(scores[i]!=0){
cout << "Found word: " << wordlist[i] << " " << scores[i] << "\n";
}
}
}
Well, what you need is some sort of comparison. C++ doesn´t know, what a right word in english is. So you may need a wordlist. Then you can Brutforce(that´s what you´re doing at the moment) until you find a match.
For comparing your brutforced result, you may use a .txt with as many english words as you can find. Then you have to use a FileStream for iterating through every word and comparing it to your brutforce result.
After you sucessfully unscrambled a word, you should think about your solution again. As you can see, you are limited to a specific amount of chars which is not that nice.
This sounds like an interesting Task for a beginner ;)
Suppose you have found a word list in the form of plain text file on the Internet, you may load all the words into a vector for string first.
ifstream word_list_file("word_list.txt");
string buffer;
vector<string> all_words;
while (getline(word_list_file, buffer))
all_words.push_back(buffer);
Then we want to compare the input letters with the each entry of all_words. I suggest using std::is_permutation. It compares two sequence regardless the order. But it can have trouble when the two sequence has different length, so compare the length yourself first.
// Remember to #include <algorithm>
bool match(const string& letters, const string& each_word)
{
if (letters.size() != each_word.size())
return false;
return is_permutation(begin(letters), end(letters), begin(each_word));
}
Note that I have not tested my codes. But that's the idea.
An edit responsing the comment:
In short, just use std::string, not std::array. Or copy my match function directly, and invoke it. This will be easier for your case.
Details:
std::is_permutation can be used with any container and any element type. For example:
#include <string>
#include <array>
#include <vector>
#include <list>
#include <algorithm>
using namespace std;
int main()
{
//Example 1
string str1 = "abcde";
string str2 = "ecdba";
is_permutation(begin(str1), end(str1), begin(str2));
//Example 2
array<double, 4> array_double_1{ 4.1, 4.2, 4.3, 4.4 };
array<double, 4> array_double_2{ 4.2, 4.1, 4.4, 4.3 };
is_permutation(begin(array_double_1), end(array_double_1), begin(array_double_2));
//Example 3
list<char> list_char = { 'x', 'y', 'z' };
string str3 = "zxy";
is_permutation(begin(list_char), end(list_char), begin(str3));
// Exampl 4
short short_integers[4] = { 1, 2, 3, 4 };
vector<int> vector_int = { 3, 4, 2, 1 };
is_permutation(begin(list_char), end(list_char), begin(str3));
return 0;
}
Example 1 uses std::string as containers of chars, which is exactly how my match function work.
Example 2 uses two arrays of double of size 4.
Example 3 even uses two different kinds of containers, with the same element types. (Have you heard of `std::list'? Never mind, just focus on our problem first.)
Example 4 is even stranger. One container is old style raw array, another is a std::vector. There are also two element types, short and int, but they are both integer. (The exact difference between short and int is not relevant here.)
Yet, all four cases can use is_permutation. Very flexiable.
The flexibility is enabled by the following facts:
is_permutation is not exactly a function. It is a function template, which is a language feature to generate new functions according to the data type you pass to it.
The containers and is_permutation algorithm do not know each other. They communicate through a middleman called "iterator". The begin and end functions together give us a pair of iterators representing the "range" of elements.
It requires more studies to understand these facts. But the general idea is not hard. Also, these facts are also true for other algorithms in the Standard Library.
Try this :
# include <stdio.h>
/* Function to swap values at two pointers */
void swap (char *x, char *y)
{
char temp;
temp = *x;
*x = *y;
*y = temp;
}
/* Function to print permutations of string
This function takes three parameters:
1. String
2. Starting index of the string
3. Ending index of the string. */
void permute(char *a, int i, int n)
{
int j;
if (i == n)
printf("%s\n", a);
else
{
for (j = i; j <= n; j++)
{
swap((a+i), (a+j));
permute(a, i+1, n);
swap((a+i), (a+j)); //backtrack
}
}
}
/* Driver program to test above functions */
int main()
{
char a[] = "vlei";
permute(a, 0, 3);
getchar();
return 0;
}