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 1 year ago.
Improve this question
New to programming, I have tried just about everything to get my program to run, but cannot figure it out. This is for my Into to programming course, so I'll be posting the instructions for it as well for context purposes.
I know for a fact that my program is running properly up until the closing bracket in line 62. The primary issue that im having is right after that, where I call the function sharedLetters. For context, I have attempted multiple ways of trying to fix the function definition, so at this point its a little jumbled, but it was wrong to begin with, so there's that. As for the remainder of the code, im not entirely sure if its written correct or not, as I cant get beyond the called function.
Assignment Instructions
For this assignment, you will write a program that forms the basis of a crossword puzzle generator. In order to create a crossword puzzle you need to identify letters that are common to one or more words. This program helps you generate crossword puzzles by identifying letters that are common to several words and storing them in an intermediate data structure.
Using intermediate data structures is one way to simplify your coding. You create a data structure that organizes your input so the final output is easier to create. Your CrosswordGenerator program will open a file containing a list of words. To prepare for crossword puzzle generation your code should implement the following pseudo code:
Open a file named wordlist.txt
Determine the number of words (N) in the file.
Create an array of that size called wordArray[];
Read all the words from the file into an array called wordArray[N].
Sort the array of words by length in descending order
Start at the beginning of the array (the longest word) and examine the word
Find all other words in the array that can intersect the current word
Two words can intersect if they share a letter.
Write a function called String sharedLetters(String S1, String S2).
Implement sharedLetters(S1,S2) that will return a string containing letters shared by the two parameter strings S1 and S2.
If no letters are shared between S1 and S2 sharedLetters() should return the empty string "".
sharedLetters(S1,S2) should ignore case; capital and lower case letters are considered equal.
Create a two dimensional array of Strings wordsIntersect[N][N] where each dimension N is the size of wordArray.
Iterate over wordArray comparing distinct words. Do not compare a word to itself.
If wordArray[i] shares any letters with wordArray[j] place the result of sharedLetters(wordArray[i],wordArray[j]) into wordsIntersect[i][j].
Non-alphabetic characters should be ignored.
Upper and lower case letters should be equivalent. Your program should not treat them as distinct tokens.
The order of shared letters is not a consideration for this program.
Write the contents of the wordsIntersect array to a Comma Separated Values (CSV) text file named wordsIntersect.csv in row-major form: row,col,value. In the example below, there is an entry in wordsIntersect[12][33] which contains the string "tci". There would also be a line in wordsIntersect.csv that contains 12,33,tci -- there are no quotes around the letters and the line ends after the letter 'i'. Given that wordsIntersect[12][78] will contains "" there would be a line in the file containing: 12,78, where there is an end of line after the last comma.
N.B.
Example of what sharedLetters() output.
SharedLetters(transaction,dictum) returns "tci"
SharedLetters(Transaction,kudzu) returns ""
If "transaction" is stored in wordArray[12] and "dictum" is stored in wordArray[33] then wordsIntersect[12][33] will contain "tci".
If "kudzu" is stored in wordArray[78] then wordsIntersect[12][78] will contain "".
My actual code
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
using std::string;
//calling function that will record shared letters between words, to be called later
string sharedLetters(string S1[], string S2[]);
int main ()
{
//variables for indexes used in arrays
int i, compareIndex, count = 0;
//declaring array and its total size based on total words in file
const int N = 644;
string wordArray[N];
//declaring a 2-D array wordsIntersect, setting size of both dimensions to 'N'
string wordsIntersect[644][644];
//declaring file
ifstream file;
//opening file
file.open("wordlist.txt");
cout << "Reading data from the file." << endl;
while (count < N)
{
file >> wordArray[count];
count++;
}
//closing the file
cout << "Closing the wordlist.txt file now." << endl;
file.close();
//sort the array of strings in descending order using SelectionSort
//going through array of strings, wordArray[]
for (int i = 0; i < N; i++)
{
//creating a nested for loop to compare indexes
for (int compareIndex = i + 1; compareIndex < N; compareIndex++)
{
//compare the words at both indexes to determine which one is longer
if (wordArray[i].length() < wordArray[compareIndex].length())
{
//if true, swap the elements using selectionSort
string longerWord = wordArray[compareIndex];
//swap indexes i and compareIndex
wordArray[compareIndex] = wordArray[i];
wordArray[i] = longerWord;
}
}
}
//calling sharedLetters function
for(i = 0; i < N; i++)
{
for(compareIndex = 0; compareIndex < N; compareIndex++)
{
string sharedLetters(wordArray[i], wordArray[compareIndex]);
}
}
string word = string sharedLetters(wordArray[i], wordArray[compareIndex]);
cout << word << endl;
//compare every word in wordArray to every other word within the array, using the sharedLetters funtion
for (int i = 0; i < N; i++)
{
for (int compareIndex = i + 1; compareIndex < N; compareIndex++)
{
//saving a string result within the main function that will equal
//the return value of the called function in the previous step
wordsIntersect[i][compareIndex] = sharedLetters(wordArray[i], wordArray[compareIndex]);
}
}
for (int i = 0; i < N; i++)
{
for (int compareIndex = i + 1; compareIndex < N; compareIndex++)
{
cout << wordArray[i] << "," << wordArray[compareIndex] << " " << wordsIntersect[i][compareIndex] << endl;
}
}
return 0;
}
//setting up 2D array wordsIntersect
for (int i = 0; i < N; i++)
{
for (int compareIndex = 0; compareIndex < N; compareIndex++)
{
wordsIntersect[i][compareIndex];
}
}
//writing the data in 2-D array into file wordsIntersect.csv
cout << "Now opening the file wordsIntersect.csv." << endl;
ofstream outputFile;
outputFile.open("wordsIntersect.csv");
cout << "Inputting sorted array wordsIntersect within file, now." << endl;
outputFile << wordsIntersect[i][compareIndex];
//closing file
outputFile.close();
cout << "Data has successfully been entered into the file. The file is now closed." << endl;
return 0;
}
//function that will identify common letters between each word
string sharedLetters(string S1[], string S2[])
{
//declaring string for sharedLetters
string sharedletters = "";
//declaring a string for words with common letters
string commonLetter = "";
//nested for loop to compare letters in S1 and S2
for (int i = 0; i < S1.length(); i++)
{
for (int compareIndex = 0; compareIndex < S2.length(); compareIndex++)
{
//comparing letters in strings
if(S1[i] == S2[compareIndex])
{
//assigning the letter at index i whenever common is found
commonLetter = S1[i];
//adding the value of commonLetter to sharedletters
sharedletters = commonLetter;
break;
}
}
}
//return string of sharedletters
return sharedletters;
}
Related
this is a very challenging question as I'm not sure how to ask it correctly.
I wrote a program that will read in the same text data on load every time. The text data is a list of words in the dictionary and the program solves anagram type puzzles (like Jumble, Boggle, Scrabble, etc). This text data never changes. Currently I use to read a text file which MUST be present in the same folder as the .exe that is built. This assumes the user would not just go in and erase, edit, or otherwise corrupt the text file or something really within the realm of possibility for a user to do. Not only that but locking a file and reading it are very noticeably slow operations.
Most of what the program does is convert the .txt file into an abstract data type (ADT) which sorts the word into a 'signature' then builds a set of words that have the same signature. These sets are stored in a structure (called map here) that is a key:value type data structure where the key is the signature. Anyway that info is irrelevant to the question just sufficient to say that on load I need to build my ADT in memory. I'm looking for a more sophisticated way than text files.
Since I'm new at programming there is probably a much better way. I just don't know how to even ask the question since I don't know what is available out there.
I understand databases, but then again it seems like that relies on an external file. I have seen posts which talk about storing data in a .h file but they always want to build a character array (char[i]), which would require converting this data into my ADT and that seems again like a waste of time when the program is loading. (why bother converting it into a char array just to read it back to the ADT?)
/*
* Project: myJumble
* Created by CS106 C++ Assignment Wizard 0.1
*
* Name: Brad Beall
* Section: Life
* This code will solve the jumble puzzles in the newspaper.
*/
#include <fstream>
#include <iostream>
#include "simpio.h"
#include "map.h"
#include "set.h"
#include "genlib.h"
//This function swaps two characters.
void Swap(char &ch1, char &ch2)
{
char tmp = ch1;
ch1 = ch2;
ch2 = tmp;
}
//This function sorts all the chars in a word in alphabetical order
string SortWord(string inWord)
{
inWord = ConvertToLowerCase(inWord);
//these two for loops will sort the string alphabetically
// - idea is starting from the front, find the 'smallest' character in the string.
// (where a is 'smaller' than b)
// then move that smallest character to the front of the string
// now move to the next character and again look for the smallest character.
// Example: for "peach", first move the 'a' to the front to form "apech", then move 'c' to form "acpeh"...
for (int i = 0; i < inWord.length(); i++) {
int minIndex = i;
for (int j = i+1; j < inWord.length(); j++)
{
if (inWord[j] < inWord[minIndex])
{
// looking for the 'smallest' character
minIndex = j;
}
}
Swap(inWord[i], inWord[minIndex]);
}
return inWord;
}
void BuildDictionary(Map<Set<string> > &kDict, ifstream &in)
{
string nextWord = "";
while(true)
{
//read in the next word from the dictionary
in >> nextWord;
if (in.fail()) break;
//sort letters alphabetically using SortWord, use that as the key
// and then add that key:value pair to the set.
kDict[SortWord(nextWord)].add(nextWord);
}
}
//this function prints a set
void PrintSet(Set<string> &inputSet)
{
Set<string>::Iterator it = inputSet.iterator();
while (it.hasNext())
{
cout << it.next() << endl;
}
}
int main ()
{
////debug the function: string SortWord(string inWord)
//cout << "Enter a word to sort" << endl;
//string tempString = GetLine();
//tempString = SortWord(tempString);
//cout << tempString;
//building the dictionary may take some time.
cout << "Loading the dictionary. This may take some time." << endl;
//read in the text file with all dictionary words
ifstream in;
in.open("enable1.txt");
//call the member function that will create our data structure
//this will be a MAP:
// - key: the alphabetized letters from a word, or the word's "signature"
// - value: a Vector of words with the matching signature
Map<Set<string> > keyedDictionary;
BuildDictionary(keyedDictionary, in);
while(true)
{
//prompt user for a word to solve
cout << "Enter a jumbled word to solve." << endl;
cout << "Type '0' to exit." << endl << endl;
string solveWord = GetLine();
if(solveWord == "0"){
break;
}
//sort the word into a signature key
solveWord = SortWord(solveWord);
//call the PrintSet(Set) member function to print the set of solutions for this signature key
PrintSet(keyedDictionary[solveWord]);
}
return 0;
}
I have a program that is supposed to take a Dictionary.txt-which has 200 separate lines with one string per line- and hash each string into an array. Then I take a user inputted string and attempt to find this string within my newly filled array. The program is using a modulo hash function to get an array index for each string, and is supposed to read the .txt file line by line. As of right now, the program executes with no errors but the array is completely empty after attempting to read in the strings.
I have tried the getline function as well as file >> input.
EDIT: My file was not opening correctly, so I replaced the url in my file.open() method to the C:/ direct url instead of using the one I included in my Visual Studio project.
int wordFinder(fstream& file, string word) {
string Table[200];
for (int i = 0; i < 200; i++) {
//modulo hashing using size of array
int index = i % 200;
//collision
if (!(Table[index].empty())) {
int count = 0;
do {
index = (index + 1) % 200;
count++;
} while ((!(Table[index].empty())) && (count < 200));//while the current position is occupied and count is less than the size of the array
getline(file, Table[index], '\n');//take string from file and put it into the table array
cout << "Collision " << Table[index]<< endl;
}
//no collision
else {
cout << "No Collision " << Table[index]<<index<< endl;
getline(file, Table[index], '\n');//take string from file and put it into the table array
}
}
//find string if in array
for (int i = 0; i < 200; i++) {
if (Table[i].compare(word) == 0) {
return 1;
}
}
//print table values
for (int i = 0; i < 200; i++) {
cout << Table[i] << endl;
}
return 0;
}
The expected result is for the program to return 1 if the word is found, or 0 if not found. It should also print the array of values, each index having a separate word from the .txt file. As of now, the program always returns 0 because the array ends up completely empty, and therefore the program prints a bunch of whitespace.
My file was not opening correctly, so I replaced the url in my file.open() method to the C:/ direct url instead of using the one I included in my Visual Studio project. It worked after I made this change.
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
When I input a string that starts with the letter 'a' the program fails to check for that letter and excludes it. If i input a string that has an 'a' just not first in string, it checks out.
Here is the complete problem:
Write a program that will read a line of text and output a list of all the letters that occur in the text together with the number of times each letter occurs in the line. End the line with a period that serves as a sentinel value or delimiting character.
The letters should be listed in the following order: the most frequently occurring letter, the next most frequently occurring letter, and so forth.
Use two arrays, one to hold letters and one to hold integers. You may assume that the input uses all lowercase letters. For example, the input do be go bo. Should produce output similar to the following:
Letter Numbers of Occurrence
o 3
b 2
d 1
e 1
Note: you can modify the implementation of the selection sort algorithm in the book to sort the array in descending order. You can use either string type or c-string type in your program.
Code:
#include<iostream>
#include<string>
using namespace std;
void sort(char letters[],int letter_count[])
{
for(int i=0; i<26; i++)
{
int max = i;
for(int j=i; j<26; j++)
{
if(letter_count[j] > letter_count[max]) max = j;
}
int temp = letter_count[i];
letter_count[i] = letter_count[max];
letter_count[max] = temp;
char local = letters[i];
letters[i] = letters[max];
letters[max] = letters[i];
}
}
int main()
{
string str;
char letters[26];
int letter_count[26] = {0 };
cout <<"Enter a line of text :";
getline(cin,str);
for(int i=0; i<str.length(); i++)
letter_count[str[i]-'a']++;
for(int i=0; i<26; i++)
letters[i] = static_cast<char> ('a'+i);
sort(letters, letter_count);
cout <<"Letter Numbers of Occurrence" << endl;
for(int i=0; i<26; i++) {
if(letter_count[i]!=0)
cout << letters[i] << " " << letter_count[i]<<endl;
}
return 0;
}
Problem found on line 20, where you try to swap letters[i] with letters[max]. That line should be
letters[max] = local;
I'm writing a program to help solve crossword puzzles. So I'm getting a word from a text list of all words in the english language, making each one a vector of chars, and comparing that vector to a vector of whatever starting letters I have. It runs fine and gives me good output, but every time I'm getting an error "libc++abi.dylib: terminating with uncaught exception of type std::length_error: vector".
Here's my code:
#include <iostream>
#include <fstream>
#include <vector>
#include <algorithm>
#include <string>
#include <iterator>
using namespace std;
string getLetters() {
string word; // Get user letter, put in variable word
cout << "Enter a set of letters" << endl;
cin >> word;
return word;
}
int getLengthOfWord() {
int length; // Get length of word
cout << "Enter the number of letters in the word" << endl;
cin >> length;
return length;
}
// Change strings to vectors of chars
vector<char> stringToVector(string word) {
std::vector<char> v(word.begin(), word.end());
return v;
}
bool compareVectors(vector<char> userWord, vector<char> listWord, int length) {
if (listWord.size() != length) // Make sure the word from the list is the right length
{
return false;
}
int counter = 0; // Counter
for (int i = 0; i < userWord.size(); i++) { // Iterating through the two words
for (int j = 0; j < listWord.size(); j++) {
if (listWord[j] == userWord[i]) { // If the letters match
listWord.erase(listWord.begin() - 1 + j); // Erase the letter from the word
counter++; // Increase counter
break; // Break out of for loop
}
}
}
if (counter == userWord.size()) { // If there were as many matches as letters in user set
return true;
}
else {
return false;
}
}
int main() {
string example; // variable to put words
ifstream wordList; // New ifstream object
wordList.open("/Users/alexray/Dropbox/C++ Practice/WordJumbleSolver/wordsEn.txt"); //open word list
int length = getLengthOfWord(); // Get user input
string word = getLetters();
vector<char> vector1(stringToVector(word));
while (wordList.is_open()) {
getline(wordList, example); // Get word, put it in example variable
vector<char> vector2(stringToVector(example)); // Make word from list a vector
vector2.erase(vector2.end() - 1); // Erase escape character from end of word
if(compareVectors(vector1, vector2, length)) { // compare the vectors
cout << example << endl;
}
}
wordList.close(); // Close stream
return 0;
}
From googling around, I thought that it was a matter of my vector wasn't initially large enough to handle some of the words, but doing vector.reserve(some_number) before assigning a value to the vector didn't help anything. Also, I couldn't imagine that a vector would have any problems with <20 elements.
Thanks for the help! (I'm new to C++ so if there's something I should obviously be doing differently, let me know).
Edit: The file I'm working with is the wordsEn.txt file from this website: http://www-01.sil.org/linguistics/wordlists/english/
In my case it was a mismatch between C++ standard on two vcxproj projects.
I've simply aligned both projects to the same C++ standard (17) and it worked.
project ➤ Properties ➤ C/C++ ➤ Language ➤ C++ Language Standard
One issue I see is that you are not erasing the character you claim you want to erase:
listWord.erase(listWord.begin() - 1 + j);
This does not erase the jth character in the sequence.
The easiest example of this failing is if j == 0 at the start of the loop, and the first character matches.
Just simply do this instead:
listWord.erase(listWord.begin() + j);
I was looking in the wrong place the whole time. I looked at the number of words/lines in the file (109582) and changed the
while (wordList.is_open()) {
getline(wordList, example); // Get word, put it in example variable
vector<char> vector2(stringToVector(example)); // Make word from list a vector
vector2.erase(vector2.end() - 1); // Erase escape character from end of word
if(compareVectors(vector1, vector2, length)) { // compare the vectors
cout << example << endl;
}
counter++;
}
to
while (counter < 109582) {
getline(wordList, example); // Get word, put it in example variable
vector<char> vector2(stringToVector(example)); // Make word from list a vector
vector2.erase(vector2.end() - 1); // Erase escape character from end of word
if(compareVectors(vector1, vector2, length)) { // compare the vectors
cout << example << endl;
}
counter++;
}
It seems I was getting some sort of overflow error by trying to read in more lines than were available in the file.
Input: 3 Books
Substrings should be: Boo, ook, oks
I want to add them in the substring array but only "Boo" is added..
Also how can I cout the most repeated string in that array?
#include <iostream>
#include <string>
using namespace std;
int main ()
{
int n;
int sub_index=0;
string input;
string substrings [1000];
while ( cin >> n >> input != NULL )
{
for(int i=0; i<= input.size()-n ; i++)
{
string sub = input.substr(i,n);
substrings [sub_index]= sub;
sub_index += n+1;
}
//cout the most repeated in substrings array
}
getchar();
return 0;
}
If you add a debugging print in your loop, you can see the problem immediately. This change:
string sub = input.substr(i,n);
std::cout << "storing \"" << sub << "\" at index "
<< sub_index << std::endl;
substrings [sub_index]= sub;
sub_index += n+1;
generates this output:
storing "Boo" at index 0
storing "ook" at index 4
storing "oks" at index 8
I'm not sure why you're incrementing your index the way you are, but that's likely the problem you're hitting.
To determine the most repeated string, you'll need to store both the substring and a count. I suggest you look into using a std::map with the string as a key and the count as a value, and once you have all your input, iterate through the map to find the key/value pair with the highest count.