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;
}
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;
}
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question appears to be off-topic because it lacks sufficient information to diagnose the problem. Describe your problem in more detail or include a minimal example in the question itself.
Closed 9 years ago.
Improve this question
I'm trying to write a C++ program that creates a list of letters that will
be used to encode a message according to the following rules:
Input a word
Remove all repeating letters to form the modified word
Place the modified word at the beginning of the array
Fill the remainder of the list with any letters of the alphabet that were not used in the word working from A to Z. (Your list should have all 26 letters of the alphabet)
For example, if the user enters HELLO, the modified word would become HELO, and the list would become HELOABCDFGIJKMNPQRSTUVXYZ. The list must be stored in an array of CHARacters.
This is the code I've written:
#include <iostream>
using namespace std;
int main()
{
char a;
int b = 0;
char word[4] = "\0";
char alphabet[27] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
char code[27];
cout << "Please enter a word:" << endl;
cin >> word;
for (int i = 0; i<3; i++)
{
if (word[i] == word[i - 1])
{
a = word[i];
word[i] = word[i + 1];
}
code[i] = word[i];
b++;
}
for (int o = 0; o<27; o++)
{
if (alphabet[o] == word[1] || alphabet[o] == word[2] || alphabet[o] == word[3] || alphabet[o] == word[0])
{
o++;
}
code[b] = alphabet[o];
b++;
}
cout << code;
return 0;
}
Unfortunately, I'm getting this error:
Run-Time Check Failure #2
Stack around the variable word was corrupted.
Secondly, my code works for 4 characters. How can I make it work for any word?
this is a simple way to do this assignment.
note that input word lenght should be smaller than 100
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
char word[100]; // input word lenght should be smaller than 100
char used[26];
memset(used, 0, 26);
scanf("%s", word);
for (int i=0; i<strlen(word); i++)
{
// convert to uppercase
if (word[i]>='a' && word[i]<='z')
word[i] -= 'a'-'A';
// skip non-alphabetic characters
if (word[i]<'A' || word[i]>'Z')
continue;
// print this char only if it's not been printed before
if (!used[word[i]-'A'])
printf("%c", word[i]);
// set to 1 so that we don't print it again
used[word[i]-'A'] = 1;
}
// print all unused characters
for (int i=0; i<26; i++)
if (!used[i])
printf("%c", i+'A');
printf("\n");
return 0;
}
This question already has answers here:
Convert single char to int
(3 answers)
Closed 3 years ago.
I have a string which has 5 characters. I want to convert each single character to int and then multiply them with each other. This is the code :
int main()
{
int x;
string str = "12345";
int a[5];
for(int i = 0; i < 5; i++)
{
a[i] = atoi(str[i]);
}
x = a[0]*a[1]*a[2]*a[3]*a[4];
cout<<x<<endl;
}
It gives this error for the line with atoi :
invalid conversion from 'char' to 'const char*' [-fpermissive]|
How can I fix this? Thanks.
You can use:
a[i] = str[i] - '0';
Does a char to digit conversion by ASCII character positions.
The proper way to do this is std::accumulate instead of rolling your own:
std::accumulate(std::begin(str), std::end(str), 1, [](int total, char c) {
return total * (c - '0'); //could also decide what to do with non-digits
});
Here's a live sample for your viewing pleasure. It's worth noting that the standard guarantees that the digit characters will always be contiguous, so subtracting '0' from any of '0' to '9' will always give you the numerical value.
std::atoi takes a const char*(a null terminated sequence of characters)
Try to change like
a[i]= str[i]-'0';
You are supplying with a single char hence the compiler is complaining
str[i] is char not char *
Use following :-
int x;
std::string str = "12345";
int a[5];
for(int i = 0; i < 5; i++)
{
a[i] = str[i] -'0' ; // simply subtract 48 from char
}
x = a[0]*a[1]*a[2]*a[3]*a[4];
std::cout<<x<<std::endl;
look at this way
string str = "12345";
int value = atoistr.c_str());
// then do calculation an value in a loop
int temp=1;
while(value){
temp *= (value%10);
value/=10;
}
This question already has answers here:
Counting the Frequency of Specific Words in Text File
(4 answers)
Closed 9 years ago.
I wrote a function for counting frequency of specific word in a text.This program every time return zero.How can I improve it?
while (fgets(sentence, sizeof sentence, cfPtr))
{
for(j=0;j<total4;j++)
{
frequency[j] = comparision(sentence,&w);
all_frequency+=frequency[j];
}}
.
.
.
int comparision(const char sentence[ ],char *w)
{
int length=0,count=0,l=0,i;
length= strlen(sentence);
l= strlen(w);
while(sentence[i]!= '\n')
if(strncmp(sentence,w,l))
count++;
i++;
return count;
}
I have proofread your code and have commented on coding style and variable names. There
is still a flaw I left with the conditional, which is due to not iterating through the
sentence.
Here is your code marked up:
while(fgets(sentence, sizeof sentence, cfPtr)) {
for(j=0;j<total4;j++){
frequency[j] = comparision(sentence,&w);
all_frequency+=frequency[j];
}
}
// int comparision(const char sentence[ ],char *w) w is a poor variable name in this case.
int comparison(const char sentence[ ], char *word) //word is a better name.
{
//int length=0,count=0,l=0,i;
//Each variable should get its own line.
//Also, i should be initialized and l is redundant.
//Here are properly initialized variables:
int length = 0;
int count = 0;
int i = 0;
//length= strlen(sentence); This is redundant, as you know that the line ends at '\n'
length = strlen(word); //l is replaced with length.
//while(sentence[i]!= '\n')
//The incrementor and the if statement should be stored inside of a block
//(Formal name for curley braces).
while(sentence[i] != '\n'){
if(strncmp(sentence, word, length) == 0) //strncmp returns 0 if equal, so you
count++; //should compare to 0 for equality
i++;
}
return count;
}