Help with strings,functions

hi, I am supposed to write a program that creates an array of strings called text, and a two-dimensional matrix of strings called dict.
I am supposed to also write a function checking if a sequence of words from text Is in the dictionary returning the index of where the word began as well as the length of the string. for example: if in the dictionary we had the words
"a","dan","boy","is","little".
and the text was :
Dan iS a nIcE little bOy \0
(pay attention that lower case will equal to upper case for example A=a)
(pay attention between the word 'a' and 'nice' there are two spaces)
the function is supposed to return 10 and 15 because the longest sequence of words that are contained in the dictionary starts at index 15 ('l')
and ends at 'y' from the word little to boy is a length of 15.
my program is below I commented to hopefully make it more understandable.

Input: aa bb cc dd ee ff gg hh ii .
tt Aa eE s hh Ii gg

output: 36 13

expected output: 11 8


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
 





#include <iostream>
#include <cstdlib>
#include <string.h>
#include <cctype>
#include <cstring>
#include <iomanip>

//------------------------------------using----------------------------------//

using std::cin;
using std::cout;
using std::endl;
using std::setw;


//------------------------------------const----------------------------------//

const int MAX_STRS=10;  //rows for dictionary
const int MAX_STR_LEN=8; //columns for dictionary
const int MAX_TEXT_LEN=100;  //columns for text

//------------------------------------prototype------------------------------//

void read_dataDict(char str[][MAX_STR_LEN]);   //read the dictionary
int find_word (char single_word [MAX_TEXT_LEN],char text[MAX_TEXT_LEN],int index);//find word within text
bool contains(char word[MAX_TEXT_LEN],char dict[MAX_STRS][MAX_STR_LEN]);//find if word is in the dictionary
char to_down(char c);//lower case a letter

//------------------------------------main-----------------------------------//

int main ()
{
	char dict[MAX_STRS][MAX_STR_LEN];    //initializing the dictionary
	char text[MAX_TEXT_LEN];            //initializing the text array
	char single_word [20];           //array that holds one word
	int index=0,i=0,j=0,sum=0,max=0;
	bool check=true;


	read_dataDict(dict);   //sending dictionary to function to be filled

	cin.getline(text,MAX_TEXT_LEN);  //receiving text
	cin.getline(text,MAX_TEXT_LEN);  //receiving the  /n



	for (i=0;i<MAX_STRS;i++)   //running through rows of dictionary
	{
		for(j=0;j<MAX_STR_LEN;j++)  //running through columns
		{
			dict[i][j]=to_down(dict[i][j]);  //sending char to be lower cased
		}
	}

	for (j=0; text[j] !='\0';j++)   //running through columns of text
	{
		text[j]=to_down(text[j]);  //sending char to be lower cased
	}



	index=find_word(single_word,text,index)+1; //giving index the last letter +1 of the word we found
	sum = strlen(single_word);                  //giving sum the length of the first word
	check=contains(single_word,dict);   //calling bool function and sending it the first word and the dictionary

	for(j=0;j<MAX_TEXT_LEN;j++)   //running through columns of text
	{
		if (check)
		{


		while(check)    //while contains function returns true
		{
			index=find_word(single_word,text,index)+1;  //we find the next single_word using find_word
			check=contains(single_word,dict);    		//and send it to see if the dictionary contains it
			sum+=strlen(single_word);            		//adding the length of the words that are valid into sum
		}
		}
		check=true;
		if(sum>max)                              //checking if sequence is bigger than past sequence
		{
			max=sum;                           //if it is then that will be the new biggest sequence
		}
		sum = 0;                     //resetting sum for the next sequence

	}
	cout<<index<<"\n"<<max;   //printing out the index and the length of single word


}

void read_dataDict(char dict[MAX_STRS][MAX_STR_LEN])  //function that reads dictionary
{
	int i;
	char temp[MAX_STR_LEN];  //using temporary array with same column length
	for(i=0;i<MAX_STRS;i++)  //going through the rows
	{
		cin>>setw(MAX_STR_LEN) >>temp;   //receiving values into temp
		if(strcmp(dict[i],".")==0)    //checking if we reached end of dict
			break;                //getting out
		strcpy(dict[i],temp);   //otherwise we copy the temporary row into the row of dict
	}
}

int find_word (char single_word[MAX_TEXT_LEN] ,char text[MAX_TEXT_LEN],int index)  //over here i made a function to find the word within the text array, do i need an & for index? because i am changing its value in the main function
{
	int i;
	char c;

	for (i=index; text[i]!= 32 && text[i] != '\0';i++)  //starting from the past index until i hit a whitespace
	{
		c=text[i];   //giving c the char
		single_word[i]=c;   //giving the assistance array that letter
	}
	return i;   //returning index
}

bool contains(char single_word[MAX_TEXT_LEN],char dict[MAX_STRS][MAX_STR_LEN]) //receiving word and full dictionary
{
	bool contains=true;
	int word_len,truth_counter=0,false_counter=0,i,length_of_dict=0;



	for( i=0;i<MAX_STRS&&strcmp(dict[i],".")!=0;i++)
	{
		length_of_dict++;

	}

	for( i=0; i< MAX_STRS && ( strcmp (dict[i],".")!=0 );i++)  //going through the rows of dictionary till we reach '.'
	{
		contains=true; //resetting contains to allow it to check next line,just because the word wasnt in the first doesnt mean it wont be in the second,third....
		word_len=strlen(dict[i]);  //giving word_len the length of the string on the current line of the dictionary


		for(int j=0;j<word_len&&contains;j++)  //running through letters of dictionary word
		{
			if(single_word[j]!=dict[i][j])  //if we find that the word we send is not equal to the dictionary word
			{
				contains=false; //becomes false,so we can go onto the next line
				break;           //break because if the first letters arent equal then they are not the same word, and we want to move onto the next line
			}
			else      //if the letters are equal
			{
				contains=true;    //change contain to true
				truth_counter++;          //advance count by one
			}
		}

		if(truth_counter==word_len)    //if at then end of checking the single_word with one of the words in the dictionary the count equals tothe length of that word it means all the letters are equal and that word is of course contained in the dictionary
		{
			contains = true;
			break;          //so we return true
		}


		false_counter++;  //advancing after each time we go down a line

	}

	if (false_counter==length_of_dict)  //checking if we checked all lines of the dict
	{
		contains = false;   //if we checked all lines and still didnt find the word it means its not in the dictionary and we return false
	}

	return contains;        //return bool

}

char to_down(char c)   //function that gets a letter and lower casses it
{
	if(isalpha(c)&&c!=32) //checking that it is a letter and not a whitespace
	{
		c=tolower(c);  //lower casing it
	}


	return c;   //returning the letter
}







Last edited on
First things first: do you have to use char arrays? std::strings would be easier and more flexible.

Lines 74, 75 & 84: You don't need these. If check is false then the code inside the while loop won't execute.

Your contains() function can be done much more easily if you use strcmp()
1
2
3
4
5
6
7
8
9
10
11
// Return true if single_word is in the dictionary
bool
contains(char single_word[MAX_TEXT_LEN], char dict[MAX_STRS][MAX_STR_LEN])
{
    for (size_t i = 0; i < MAX_STRS && strcmp(dict[i], ".") != 0; i++) {
        if (strcmp(single_word, dict[i]) == 0) {
            return true;
        }
    }
    return false;
}


Lines 118 and 119: is i the index within text, or within single_word? You're looking for a space, but like you said, what if there are multiple spaces together? And you need to null-terminate the string too.

All of these are reasons why you should use std::string instead.

I suggest that you use this prototype for find_word:
1
2
3
4
5
// Copy the next word in text starting at index into single_word.
// Null-terminate the word.  Update index to the character after the
// word.  Returns true if a word was found
bool
find_word(char single_word[MAX_TEXT_LEN], char text[MAX_TEXT_LEN], int &index)


Regarding your code in main() to find the longest run of words in the dictionary, the logic is flawed. You need to find a run of words, compare the length to the longest run seen so far, and remember the start/end points if the current run is longer. Then you need to find another run etc. etc.

For this sort of code you can quickly get bogged down in the logic so I'll tell you the easy way: use a "state machine". Create a loop that just reads through the words. Then add a boolean variable that says whether you're currently inside a run of words in the dictionary. In other words, it says whether the last word was in the dictionary. If you do this, then the code is pretty easy and looks sort of like this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
    bool inRun = false;  // currently in a run of dictionary words?
    while (find_word(single_word, text, index)) {
        bool inDict = contains(single_word, dict);
        if (inRun) {
            if (inDict) {
                // Found another word in the dict. Update end position of current run
            } else {
                // You hit the end of the run.  If that was the longest so far, then update
                // appropriate variables.
                inRun = false;  // indicate that you're no longer in a run
            }

        } else {
            if (inDict) {
                // start of a new run. Update variable to mark start of current run.
                inRun = true; // indicate you're now in a run.
            } else {
                // Just another word not in the dict. Do nothing
            }
        }
    }
    if (inRun) {
        // The last word was inside a run.  Do the check for longest run again.
    }

What is indict?
Also yes I have to use char arrays.
Could you possibly show me where in my program you meant for me to replace with what you recommended
inDict is a variable that says whether the current word is in the dictionary.

The code I suggest would replace your code at lines 68-92
You suggested a few codes. Which one are you referring to
could you possibly copy and paste it into my code so i can see where you meant to replace. also in the main how come you didn't use max or sum? how do you save the length of the last sequence of words?
Sorry, to me that's crossing the line between helping you and doing the work for you. I think I've given enough info for you to figure it out.
Topic archived. No new replies allowed.