Dynamic Programming - Word Break - c++

I am trying to solve this Problem.The question is as follows
Given an input string and a dictionary of words, find out if the input string can be segmented into a space-separated sequence of dictionary words.
Dictionary is an array of strings.
My Approach is the following recursive fn with storing of the results of recursive calls. The output is fine but I see that the stored result is never used.
My solution is hopefully correct as it passed the test cases.But I would be great if I know whether DP is used.
The code is:
#include <iostream>
#include <string.h>
using namespace std;
int r[100][100] = {0}; //To Store the calculated values
bool searchWord(char q[], char D[][20], int start, int end) {
cout << "In Search Word Loop with " << start << " " << end << endl;
char temp[end - start + 1];
int j = 0;
for (int i = start; i <= end ; ++i) {
//cout << "Looping i " << i << endl;
temp[j] = q[i];
j++;
}
// cout << "For Word " << temp << endl;
for (int i = 0; i < 12; ++i) {
// cout << "Comparing with " << D[i] << endl;
if (!strcmp(temp, D[i])) {
cout << "Found Word" << temp << " " << D[i] << endl;
return 1;
}
}
return 0;
}
bool searchSentence(char q[], char D[][20], int qstart, int qend) {
cout << "In Search Sentence Loop" << endl;
if (r[qstart][qend] != 0) {
cout << "DP Helped!!!" << endl;
return 1;
}
if (qstart == qend) {
if (searchWord(q, D, qstart, qstart))
return 1;
else return 0;
}
if (qstart > qend) return 1;
int i;
for (i = qstart; i <= qend; i++) {
if (searchWord(q, D, qstart, i)) {
r[i + 1][qend] = searchSentence(q, D, i + 1, qend);
if (r[i + 1][qend] == 1) return 1;
}
}
return 0;
}
int main() {
char D[20][20] = { "i", "like", "sam", "sung", "samsung", "mobile", "ice", "cream", "icecream", "man", "go", "mango"};
char q[100] = "samsungmango";
int index = 0; char ch;
ch = q[0];
while (ch != '\0') {
index++;
ch = q[index];
}
if (searchSentence(q, D, 0, index - 1))
cout << "Yes" << endl;
else cout << "No" << endl;
}

Is recursion mandatory? I see, iterative DP-solution is easiest and compact:
#include <stdio.h>
#include <string.h>
int main() {
const char *D[] = { "i", "like", "sam", "sung", "samsung", "mobile", "ice", "cream", "icecream", "man", "go", "mango", NULL};
const char q[] = "samsungmango";
char dp[100];
short d_len[20];
memset(dp, 0, sizeof(dp));
dp[0] = 1; // 0 element is always reacheable
int i, j;
// compute dict string lengths
for(i = 0; D[i]; i++)
d_len[i] = strlen(D[i]);
// Compute splits using DP array
for(i = 0; q[i] != 0; i++)
if(dp[i]) // this index is reacheable
for(j = 0; D[j]; j++) // try to make next reacheable indexes
if(strncmp(&q[i], D[j], d_len[j]) == 0)
dp[i + d_len[j]] = 1; // That position is reacheable, too
// if EOLN(q) is reached, then yes
printf("Answer is %s\n", dp[i]? "YES" : "NO");
} // main

Your code is actually wrong. To fail your code, try input like "likeman"
Note that there are two different return values possible from function searchSentence, 0 or 1. So if you initialize the r array with 0 there's no guarantee it's a new state when r[x][y] = 0. Initialize r array with some impossible value like -1 or 2 for this program and test again. Now you can easily confirm that if r[qbegin][qend] != -1 then this state has already been checked so you can return r[qbegin][qend] from here
Updated code :
#include <iostream>
#include <string.h>
using namespace std;
int r[100][100]; //To Store the calculated values
bool searchWord(char q[], char D[][20], int start, int end)
{
cout << "In Search Word Loop with " << start << " " << end << endl;
char temp[end - start + 1];
int j = 0;
for (int i = start; i <= end ; ++i)
{
//cout << "Looping i " << i << endl;
temp[j] = q[i];
j++;
}
temp[j] = '\0';
//cout << "For Word " << temp << endl;
for (int i = 0; i < 12; ++i)
{
// cout << "Comparing with " << D[i] << endl;
if (!strcmp(temp, D[i]))
{
cout << "Found Word" << temp << " " << D[i] << endl;
return 1;
}
}
return 0;
}
bool searchSentence(char q[], char D[][20], int qstart, int qend)
{
cout << "In Search Sentence Loop" << endl;
if (r[qstart][qend] != -1)
{
cout << "DP Helped!!!" << endl;
return r[qstart][qend];
}
if (qstart == qend)
{
if (searchWord(q, D, qstart, qstart))
return 1;
else return 0;
}
if (qstart > qend) return 1;
int i;
for (i = qstart; i <= qend; i++)
{
if (searchWord(q, D, qstart, i))
{
r[i + 1][qend] = searchSentence(q, D, i + 1, qend);
if (r[i + 1][qend] == 1) return 1;
}
}
return 0;
}
int main()
{
char D[20][20] = { "i", "like", "sam", "sung", "samsung", "mobile", "ice", "cream", "icecream", "man", "go", "mango"};
char q[100] = "ilike";
int index = 0; char ch;
ch = q[0];
memset(r, -1, sizeof(r));
while (ch != '\0')
{
index++;
ch = q[index];
}
if (searchSentence(q, D, 0, index - 1))
cout << "Yes" << endl;
else cout << "No" << endl;
}
P.S : There are some redundant lines of codes but I didn't change them and I added a null character in the end of the character array temp in function searchWord

Related

BinarySearch not working for reversed array

I am working on a project for school that tests Binary Search vs. Linear Search. My LinearSearch method seems to work fine when the array is in either increasing order or reversed. However, the BinarySearch only works when the array is in increasing order, but fails to work when the array is reversed. I am not sure what is causing this and would appreciate any suggestions/solutions.
Here is my code
/*
* SearchTest.cpp
*
* Created on: Oct 16, 2022
* Author: JH
*/
#include <iostream>
#include <time.h>
using namespace std;
//BinarySearch method
int BinarySearch(int numbers[], int numbersSize, int key) {
int mid;
int low;
int high;
low = 0;
high = numbersSize - 1;
while (high >= low) {
mid = (high + low) / 2;
if (numbers[mid] < key) {
low = mid + 1;
}
else if (numbers[mid] > key) {
high = mid - 1;
}
else {
return mid;
}
}
return -1; // not found
}
//LinearSearch method
int LinearSearch(int* array, int arraySize, int key) {
for (int i = 0; i < arraySize; i++) {
if (array[i] == key) {
return i;
}
}
return -1; // not found
}
//method to reverse array elements
void reverseArray(int arr[], int start, int end)
{
while (start < end)
{
int temp = arr[start];
arr[start] = arr[end];
arr[end] = temp;
start++;
end--;
}
}
int main() {
//declare array
int reverseArr[1000];
int size = sizeof(reverseArr)/sizeof(reverseArr[0]);
//initialize array
for (int i = 0; i < size; i++) {
reverseArr[i] = i;
}
//reverse array
reverseArray(reverseArr, 0, size-1);
//print array
for (int i = 0; i < size; i++) {
cout << reverseArr[i] << " ";
}
cout << endl;
cout << endl;
//generate random number
srand(time(NULL));
int randomNum = rand() % 1000;
//print statements
cout << "[Linear vs. Binary Search]" << endl;
cout << "The target value is " << reverseArr[randomNum] << endl;
cout << endl;
//call BinarySearch method for array
cout << "Binary Search Test: " << endl;
int key1 = reverseArr[randomNum];
int keyIndex1 = BinarySearch(reverseArr, size, key1);
if (keyIndex1 == -1) {
cout << key1 << " was not found." << endl;
}
else {
cout << "Found " << key1 << " at index " << keyIndex1 << "." << endl;
}
cout << endl;
//call LinearSearch method for array
cout << "Linear Search Test: " << endl;
int key2 = reverseArr[randomNum];
int keyIndex2 = LinearSearch(reverseArr, size, key2);
if (keyIndex2 == -1) {
cout << key2 << " was not found." << endl;
}
else {
cout << "Found " << key2 << " at index ";
cout << keyIndex2 << "." << endl;
}
}

Acessing elements of an array from another class

int main() {
int x;
const int Maxword = 5;
char Guess[Maxword] {};
std::string words[Maxword] = {
"Hello",
"World",
"Shift",
"Green",
"Seven"
};
srand(time(NULL));
int iSecret = rand() % Maxword;
std::string Word(words[iSecret]);
for (int i = 0; i < 5; i++) {
std::cout << Word[i] << std::endl;
}
for (int i = 0; i < 5; i++) {
std::cout << ("Please enter the letters you would like to guess") << std::endl;
std::cin >> Guess[i];
std::cout << Guess[i] << std::endl;
}
for (int i = 0; i < 5; i++) {
if (Guess[i] == Word[i]) {
std::cout << Guess[i] << "\t" << "Is in the right place" << std::endl;
} else if (Guess[i] != Word[i]) {
std::cout << Guess[i] << "\t" << "Isnt in the right place" << std::endl;
} else {
}
}
void InTheWord() {
for (int i = 0; i < 5; i++) {
}
}
I want to use elements of arrays Guess[] and Word[] how would I access them from the other function. So like I want to check if a letter from Guess[] is in the array of Word[] so id have to pass down each letter and check guess against every letter in word then return to the other function to then print out whether the letter that the person guessed was in the word that the program generated.

Why do I always return position 10 in my code?

In my program for sorting an array of strings, I always get a position of 10 when binary searching a name. Why does this occur?
#include <iostream>
#include <string>
#include <fstream>
using namespace std;
const int MAXNAMES = 20;
void readArray(string names[])
{
ifstream inFile("names.txt");
string line;
int counter = 0;
if (!inFile.is_open())
{
cout << endl << "Cannot locate file names.txt" << endl;
exit(0);
}
else
{
cout << "Succesfully opened \"names.txt\" file." << endl;
}
while (getline(inFile, line))
{
names[counter++] = line;
}
inFile.close();
}
void displayArray(string names[])
{
for (int i = 0; i < MAXNAMES; i++)
{
cout << names[i] << endl;
}
cout << endl;
}
void selectionSort(string names[])
{
int i, j, minIndex;
string minString;
for (i = 0; i < MAXNAMES - 1; i++)
{
minIndex = i;
minString = names[i];
for (j = i + 1; j < MAXNAMES; j++)
{
if (minString.compare(names[j]) > 0)
{
minString = names[j];
minIndex = j;
}
}
if (minIndex != i)
{
string temp = names[i];
names[i] = names[minIndex];
names[minIndex] = temp;
}
}
}
void sequentialSearch(string names[], string name)
{
bool found = false;
int index = 0;
for (int i = 0; i < MAXNAMES; i++)
{
if (name.compare(names[i]) == 0)
{
found = true;
index = i;
break;
}
}
if (!found)
cout << "The name is not found." << endl;
else
cout << endl << "The name is found at index: " << index + 1 << "." << endl;
}
void bubbleSort(string names[])
{
string temp;
for (int j = 0; j < MAXNAMES - 1; j++)
{
for (int i = j + 1; i < MAXNAMES; i++)
{
if (names[j].compare(names[i]) > 0)
{
temp = names[j];
names[j] = names[i];
names[i] = temp;
}
}
}
}
int binarySearch(string names[], string name)
{
int l = 0;
int r = MAXNAMES - 1;
while (l <= r)
{
int m = l + (r - l) / 2;
int res = 0;
if (name == names[m])
res = 0;
if (res == 0)
return m;
if (name > (names[m]))
l = m + 1;
else
r = m - 1;
}
return -1;
}
int main()
{
string names[MAXNAMES];
readArray(names);
cout << "Array before sort:" << endl << endl;
displayArray(names);
cout << "Array after selection sort is:" << endl << endl;
selectionSort(names);
displayArray(names);
string nameToSearch;
cout << "Enter a name to (sequential) search for: ";
std::getline(std::cin, nameToSearch);
sequentialSearch(names, nameToSearch);
string choice;
cout << endl << "Replace first element of the array \"" << names[0] << "\" with \"" << nameToSearch << "\" Yes or No: ";
std::getline(std::cin, choice);
if (choice.compare("Yes") == 0 || choice.compare("yes") == 0)
{
names[0] = nameToSearch;
}
bubbleSort(names);
cout << endl << "Array after Bubble Sort is:" << endl;
displayArray(names);
cout << "Enter a name to (binary) search for: ";
std::getline(std::cin, nameToSearch);
int index = binarySearch(names, nameToSearch);
if (index == -1)
cout << endl << "The name is not found." << endl;
else
cout << endl << "The name is found at position " << (index + 1) << endl;
return 0;
}
Here is the input file used for the code:
names.txt
Collins, Bill
Smith, Bart
Allen, Jim
Griffin, Jim
Stamey, Marty
Rose, Geri
Taylor, Terri
Johnson, Jill
Allison, Jeff
Looney, Joe
Wolfe, Bill
James, Jean
Weaver, Jim
Pore, Rob
Rutherford, Rose
Javens, Renee
Harison, Rose
Setzer, Cathy
Pike, Gordon
Holland, Beth
In binarySearch, you have this sequence:
int res = 0;
if (name == names[m])
res = 0;
if (res == 0)
return m;
Since res will always be zero when that 2nd if is reached, it will always return on the first time thru the loop.
You can remove res completely, and just replace all that with
if (name == names[m])
return m;

Easy C++ = array length and reverse WITHOUT <string>

I can't seem to get my array's length or to print backwards! ANY HELP PLEASE?!
the functions on the bottom for void GetStringLenght and Print Backwards aren't working
#include <iostream>
void ReadString(char* c, int maxLength);
void GetStringLength(char* c, int* length);
void PrintString(char* const c);
void PrintStringBackwards(char* const c);
int main()
{
const int SIZE = 50;
char ca[SIZE];
char* pc = ca;
int fPrints = 0;
int bPrints = 0;
int lengthChecks = 0;
char selection = 'z';
while (selection != 'Q') {
std::cout << "\n[ 1] Test ReadString\n";
std::cout << "[ 2] Test GetStringLength\n";
std::cout << "[ 3] Test PrintString\n";
std::cout << "[ 4] Test PrintStringBackwards\n";
std::cout << "[Q] Quit\n";
std::cout << "Selection: ";
std::cin >> selection;
std::cin.ignore();
std::cout << std::endl;
switch (selection) {
//Test ReadString
case '1':
ReadString(pc, SIZE);
break;
//Test GetStringLength
case '2': {
lengthChecks += 1;
int length = 0;
GetStringLength(pc, &length);
std::cout << "Length[" << lengthChecks << "]=" << length << std::endl;
break;
}
//Test PrintString
case '3':
fPrints += 1;
std::cout << "Foward[" << fPrints << "]=";
PrintString(pc);
std::cout << std::endl;
break;
//[ 4] Test PrintStringBackwards
case '4':
bPrints += 1;
std::cout << "Backwards[" << bPrints << "]=";
PrintStringBackwards(pc);
std::cout << std::endl;
break;
case 'Q':
break;
default:
break;
} //end switch
} //end while
std::cout << "Press ENTER";
std::cin.get();
return 0;
}
void ReadString(char* c, int maxLength)
{
std::cout << "Enter a string less than " << maxLength << " characters." << std::endl;
std::cin.getline(c, maxLength, '\n');
}
//BELOW THIS DOESNT WORK EITHER///
//////////////////////////////////////////
void GetStringLength(char* c, int* length)
{
for (int i = 0; i < *length; i++) {
if (c[i] == '\0')
*length = i - 1;
}
}
void PrintString(char* const c)
{
int counter = 0;
for (int i = 0; i < 100; i++) {
if (c[i] == '\0') {
counter = i;
break;
} //end if
} //end for
for (int j = 0; j < counter; j++) {
std::cout << c[j];
if (j == counter)
std::cout << '\0';
} //end for
std::cout << std::endl;
} //end void
void PrintStringBackwards(char* const c)
{
//this is where I’m lost! I’ve tried 25 different ways and everything is error.
}
Consider for (int i = 0; i < *length; i++) where both i and *length are 0, as in your case... will that loop ever execute? Nope... Consider a loop that starts with x set to 0 and return x; when str[x] is '\0'. i.e. the loop in strlen does this.
As for printing backwards, start at the highest index (returned by strlen or your function once fixed) and decrement until you reach 0, printing the characters at those offsets as you go.
strlen is available in <cstring>, by the way, not just <string>... and as it is a mandatory function it'll always be part of any C++ implementation. You should probably just use strlen...
To get a C string (char*)'s length you can use strlen(...).
To print backwards, do:
for(int i = strlen(str) - 1; i >= 0; --i)
std::cout << str[i];

power function no scope in function

#include<iostream>//Pls note:Only header allowed...
As this is the C++ i dont think so any other header is needed for that math function.
using namespace std;
int comparator(int audience[][2], int index1, int index2) {
int b1, e1;
int b2, e2;
b1 = audience[index1][1];
e1 = audience[index1][2];
b2 = audience[index2][1];
e2 = audience[index2][2];
double re1;
re1 = pow(b1, e1);
cout << re1 << endl;
double re2 = pow(b2, e2);
cout << re2 << endl;
if (re1 == re2)
{
return 0;
}
if (re1 > re2)
{
return -1;
}
if (re1 < re2)
{
return 1;
}
}
//Nothing has to be done with the rest of the two functions.
void sorting(int audience[][2], int N, int &i_index, int &j_index)
{
int i, j, temp;
for (i = 0; i<N - 1; i++)
{
if (audience[i][2] < audience[i + 1][2])
continue;
else
i_index = i;
break;
}
for (i = N; i > 1; i++)
{
if (audience[i][2]>audience[i - 1][2])
continue;
else
j_index = i;
break;
}
for (i = i_index + 1; i < j_index - 1; i++)
{
min = audience[i_index + 1][2];
for (i = )
if (audience[i_index][1] > audience[i_index + 1][1])
{
temp = audience[i_index + 1][1];
audience[i_index + 1][1] = audience[i_index][1];
audience[i_index][1] = temp;
}
}
for (i = i_index + 1; i <= j_index - 1; i++)
{
min = audience[i][2];
for (j = i_index + 2; j <= j_index - 1; j++)
{
if (min > audience[j][2])
{
temp = audience[i_index + 2][2];
audience[i_index + 1][2] = audience[i_index][2];
audience[i_index][2] = temp;
}
}
}
}
void merge(int audience[][2], int mergedarray[][2], int N, int i_index, int j_index)
{
}
int main()
{
int audience[100][2], mergedmarks[100][2];
int i, N;
int index1 = 0, index2 = 0;
int comp_result;
cout << "Enter the value of N : ";
cin >> N; // Enter size of the table
cout << "Enter the base and exponent for " << N << "rows " << endl;
for (i = 0; i < N; i++)
cin >> audience[i][0] >> audience[i][1]; //Enter numbers in the table
cout << endl << "Checking Function 1: Compare ecodes for 5 index pairs" << endl;
for (i = 0; i < 5; i++)
{
cout << "\nEnter indices of row1 and row2 that you want to compare: ";
cin >> index1 >> index2;
if (index1 < 0 || index2 < 0 || index1 >= N || index2 >= N)
continue;
comp_result = comparator(audience, index1, index2);
if (comp_result == -1)
cout << "ecode of index 1 is greater than ecode of index2" << endl;
else if (comp_result == 1)
cout << "ecode of index 1 is less than ecode of index2" << endl;
else if (comp_result == 0)
cout << "ecode of index 1 is equal to ecode of index2" << endl;
}
cout << endl;
int index_i = 0, index_j = N;
sorting(audience, N, index_i, index_j);
cout << "Checking Function 2: Printing sorted array " << endl;
for (i = 0; i < N; i++)
cout << audience[i][0] << " " << audience[i][1] << endl;
cout << endl;
cout << "index i: " << index_i << "\nindex j: " << index_j << endl;
cout << endl << "Checking Function 3: Printing Merged Array " << endl;
merge(audience, mergedmarks, N, index_i, index_j);
int merge_array_size = index_i + (N - (index_j + 1));
for (i = 0; i < N; i++)
cout << mergedmarks[i][0] << " " << mergedmarks[i][1] << endl;
cout << endl;
return 0;
}
This is the whole problem. I have to still edit the merge function. That is the whole problem.This is all.
You need to include the pow header, which is math.h, in order to use it.
add at the beginning of your file:
#include <math.h>
#include <iostream>
using namespace std;
POW is declared in math.h header file so use
#include<math.h>