Printing all longest matching substrings - c++

I have an assignment for finding all of the longest matching sub-strings between the strings "B D C A B A" and "A B C B D A B". There are a lot of partial solutions to this online but none that do what I need them to. I created this to find one longest matching sub-string, but I need to be able to find all of them, there should be 6 in total.
#include <iostream>
#include <string>
#include <vector>
using namespace std;
void myLMS(string one, string two);
int main()
{
string s1 = "ABCBDAB";
string s2 = "BDCABA";
myLMS(s1, s2);
return 0;
}
void myLMS(string one, string two) {
vector<vector<char>> lms;
vector<char> one_lms;
for (int i = 0; i < two.length(); i++) {
for (int j = i + 1; j < one.length(); j++) {
if (two[i] == one[j]) {
one_lms.push_back(two[i]);
break;
}
}
}
lms.push_back(one_lms);
for (int i = 0; i < lms[0].size(); i++) {
cout << lms[0][i];
}
}
Is there a way for me to continue with this method and get the outcome I'm looking for or is another approach needed?
Edit: I found this solution https://www.geeksforgeeks.org/printing-longest-common-subsequence-set-2-printing/
but I'm not really interested in just copying from a program as that doesn't really help me. It also only accomplishes half of what I'm trying to do.
From the assignment prompt it looks like the first three strings printed from this example are there as well as the same three only backwards. Reversing the strings doesn't get those backwards sub-strings so how would they be calculated?

Your logic is incomplete by quite a bit. Here's some pseudo-code to help you get started.
for each character in string 1
for each character in string 2
if char_1 == char_2
possible substring match
do the next chars match?
yes
there is a substring - now find longest
no
no substring match, continue the loop

I can't understand what's the need to solve it in this manner since your input strings are fixed you run for loops from first char of one string to last -1 char and and run another nested for loop for each subsequent characters if a match is found like the program of finding out common substring that all of us have done in the beginning.

Related

Finding the longest palindromic substring (suboptimally)

I'm working on a coding exercise that asks me to find the longest palindromic substring when given an input string. I know my solution isn't optimal in terms of efficiency but I'm trying to get a correct solution first.
So far this is what I have:
#include <string>
#include <algorithm>
#include <iostream>
class Solution {
public:
string longestPalindrome(string s) {
string currentLongest = "";
for (int i = 0; i < s.length(); i++)
{
for (int j = i; j <= s.length(); j++)
{
string testcase = s.substr(i, j);
string reversestring = testcase;
std::reverse(reversestring.begin(), reversestring.end());
if (testcase == reversestring)
{
if (testcase.length() > currentLongest.length())
{
currentLongest = testcase;
}
}
}
}
return currentLongest;
}
};
It works for several test cases, but also fails on a lot of other test cases. I suspect something is going wrong in the most inner loop of my code, but am not sure exactly what. I'm attempting to generate all possible substrings and then check if they are palindromes by comparing them with their reverse; after I establish they are a palindrome I check if it's longer than the current longest palindrome I have found.
because you are not trying all the possible solution
in c++ , substr takes two parameters the first are the starting index , and the second is the length of the substring
how ever in you program you don't check for the string which starts at index 4 and have length of three for example
in the second for loop you shoud start from index 1 not from index i

Failed to generate executive file in Visual Studio Code 2019

I am new in C++.
I encountered in question to find the vowels(i.e. "a","e","i","o","u") in a sub string,
and then I was thinking about change the driver function to get user input.
Unfortunately, this code did not generate execution file in Visual Studio Code nor any error messages.
Any help would be highly appreciated.
FYI, the function code was from GeeksforGeeks.
Thanks!
#include <stdio.h>
#include <string>
using namespace std;
// return true if x is vowel
bool isVowel(char x){
// function to check if x is in vowel or not
return (x == 'a' || x == 'e' || x =='i' || x == 'o' || x=='u');
}
void(FindSubString(std::string str)){
set<char> hash; // to store vowel
// outer loop picks starting characters
// and inner loop picks for ending characters
int n = str.length();
for (int i =0; i<n; i++){
for (int j = i; j <n; j++){
// if current position is not vowel,
// then no more possible string starting from str[i]
if (isVowel(str[j])==false)
break;
// if vowel, insert into hash
hash.insert(str[j]);
//if all vowels are present in current substring
if (hash.size()==5)
cout << str.substr(i, j-i+1) << " ";
}
hash.clear();
}
int main()
{
string str = getstring("insert a string: %s\n", stdin);
FindSubString(str);
return 0;
}
}
So, as mentioned in the comments, there are a number of fatal compiler errors in your code (when I run it through Visual Studio's C++ compiler as is, I get 7 errors - so I'm not sure how you are seeing none).
First, you have a missing closing brace (}) at the end of that function (seemingly, it is after the body of main, instead). Moving the } from the very end of the code to its proper place at the end of the FindSubString function will fix that. (This may be a copy-paste error, or you may be trying to define main inside FindSubString, but that's not allowed in C++.)
Second, you have the wrong and missing header files. Generally, for C++ programs, you should use the <iostream> header rather than <stdio.h>. The latter is generally used for C programs; however, it can be used in C++, but you'll need <iostream> if you want to use std::cout and std::cin. (I'm not sure if this is part of the Standard, but many implementations automatically include stdio.h when you include iostream.) You also need to #include <set> to make use of the std::set container.
And, the last of the fatal errors is your call to getstring. This is not a standard library function. So, you can either define this yourself, or just use the code in the main function below:
int main()
{
string str;
cout << "insert a string: ";
cin >> str;
// string str = getstring("insert a string: %s\n", stdin);
FindSubString(str);
return 0;
}
There is also a 'peculiarity' (though not actually an error, as my first version of this answer suggested) in the way you define your FindSubString function, with the 'extra' (unneeded, and very confusing) set of parentheses. It should be just this:
void FindSubString(std::string str)
{
However, even with all these errors fixed, your code does not work! This is because of a flaw in your logic, in the inner for loop of your FindSubString function. As you have it, that loop will terminate (because of the break; statement) on the first occurrence of a non-vowel.
You should, instead, check if the test letter is a vowel, and insert into the hash set if so. I'm not entirely sure what your definition of a sub-string is, but this code does something approaching what I think you want (feel free to clarify your goal, or correct my assumption):
void FindSubString(std::string str)
{
set<char> hash; // to store vowel
int n = str.length();
for (int i = 0; i < n; i++) {
for (int j = i; j < n; j++) {
if (isVowel(str[j])) hash.insert(str[j]); // if vowel, insert into hash
//if all vowels are present in current substring
if (hash.size() == 5)
cout << str.substr(i, j - i + 1) << " ";
}
hash.clear();
}
}
The code shown will find all substrings containing the five vowels.
Sample input:
facetiously
Output:
facetiou facetious facetiousl facetiously acetiou acetious acetiousl acetiously

Backtracking of 'AABC' string in C++

I'm struggling with solving this problem in C++.
I have a string: {A,A,B,C} and I want to print all possible permutations for this.
This would be 12:
AABC, AACB, ABAC, ABCA, etc...
I've written the following piece of code in which I have:
- a string which contains the letters A,A,B,C.
- a result string in which I will print each permutation when base condition of recursivity is fullfilled
- an array of integers which represent counters values for each digit: counters[3] = {2,1,1} which means there can be 2 A's, 1 B and 1C in a permutation.
- a function which should solve the problem in a recursive manner like this:
Start from initial string. From left to right of string check if counter for each character is greater than 0. If it is put the character in result[lvl] where lvl is the depth of the recursion. Then decrement the counter for that character's position. Do that for all the elements to the right of the current element and then backtrack all the way up and start with next element(second A).
The base case would be when all counters are equal to 0 print the solution then return.
Here is the code:
#include <iostream>
using namespace std;
char theString[4] = {'A','A','B','C'};
char resultString[4]={};
int counters[3] = {2,1,1};
void printPermutation()
{
for(int i=0; i<4; i++)
{
cout << resultString[i];
}
cout << endl;
}
void solvePermutations(int *counters, int lvl)
{
if(lvl == 4)
{
printPermutation();
return;
}
for(int i=0; i<4; i++)
{
if(counters[i] == 0)
{continue;}
else
{
resultString[lvl] = theString[i];
counters[i]--;
solvePermutations(counters, lvl+1);
counters[i]++;
}
}
}
int main()
{
int *ptr;
ptr = counters;
solvePermutations(ptr, 0);
return 0;
}
When I run the code I get this output instead of what I'm expecting(12 distinct permutations):
ACAB
ACBA
BAAA
BAAC
BACA
etc
More than 12 and with no logic(to me :D)
Please help me correct this and tell me what is wrong in my algorithm and help me understand it. Thank you.
You have one small logical error in your algorithm. You are using a counter[3] and a theString[4]. The idea here is that each index of counter should correspond to one letter, and hold the amount of that letter used.
With your loop you are using i<4. When i is 3 in that loop, you are trying to access counter[3] which is out of bounds. This in undefined behavior and you could be reading any int value.
To correct this, you simply need to decrease the loop to go to max 2 (i < 3) and change theString to an array of 3 elements, {'A', 'B', 'C'}.
char theString[3] = {'A','B','C'};
//...
for(int i=0; i<3; i++)

C++, return duplicate instances from an array to a string

Background to this: This is not homework, it's completely optional review for a basic c++ class. As I want to pass, I'm going through each example the best I can, This one I'm super stuck on, and have been for about three hours now.
Problem: Write a function to return a string composed of the most frequent lowercase letter found in each row of a 10 x 10 array of lowercase alphabetic chars in the range a through z.
If there is more than one most frequent character, use the one that come first alphabetically.
Use neither cin nor cout.
#include <iostream>
#include <string>
using namespace std;
string mostFrequent(char c[10][10]){
// this is the function I need to create
}
int main(){
char c[10][10] = {
'a','b','f','d','e','f','g','h','i','j',
'a','b','c','r','c','r','g','h','r','j',
'a','b','c','d','e','f','g','h','o','o',
'z','w','p','d','e','f','g','h','i','j',
'o','d','o','d','o','b','o','d','o','d',
'a','l','l','d','e','f','f','h','l','j',
'a','b','c','d','i','f','g','h','i','j',
'a','b','z','v','z','v','g','g','v','z',
'a','b','c','d','e','f','g','h','i','e',
'a','b','s','d','e','f','g','h','s','j',
};
cout << mostFrequent(c) << endl;
return 0;
}
So in research for this I found some material that allows me to count how many times a specific int or char would appear inside the array, but it doesn't quite suit the needs of the problem as it needs to return a string composed of the most frequent character. See below.
int myints[] = {10,20,30,30,20,10,10,20};
int mycount = std::count (myints, myints+8, 10);
Because it doesn't work though, I was thinking a for loop, to go row to row, I'll mostly likely need to save things into an array to count, but I'm not sure at all how to implement something like that. I even considered a caesar shift with an array, but I'm not sure where to go if that is the solution.
If I understood the task correctly, you have a matrix 10x10 and you have to create a string of length 10, where character at position i is the one that is most frequent among characters in the row i.
string mostFrequent(char c[10][10]) {
// The idea here is to find the most common character in each row and then append that character to the string
string s = "";
for (int i = 0; i < 10; i++) s += findMostFrequentCharacter(c[i]);
return s;
}
Now we just have to implement a function char findMostFrequentCharacter(char c). We are going to do that by counting all of the characters and picking the one that is most frequent (or it comes alphabetically before if there is more than one most frequent character):
char findMostFrequentCharacter(char c[10]) {
int counts[256]; // Assuming these are ASCII characters, we can have max 256 different values
// Fill it with zeroes (you can use memset to do that, but for clarity I'll write a for-loop
for (int i = 0; i < 256; i++) c[i] = 0;
// Do the actual counting
for (int i = 0; i < 10; i++) // For each character
counts[ c[i] ]++; // Increase it's count by 1, note that c[i] is going to have values between 65 (upper case A) and 122 (lower case z)
char mostFrequent = 0;
// Find the one that is most frequent
for (char ch = 'A'; ch <= 'z' ch++) // This will ensure that we iterate over all upper and lower case letters (+ some more but we don't care about it)
if (counts[ch] > counts[c]) c = ch; // Take the one that is more frequent, note that in case they have the same count nothing will happen which is what we want since we are iterating through characters in alphabetical order
return c;
}
I have written the code out of my head so I'm sorry if there are any compile errors.

independent things influence each other (I have no idea what is going on)

Sorry for the title, but I really have no idea what the problem is. The code looks like that (here it has no sense, but in the bigger project is has, so please, do not ask "why do you want to do....")
#include <iostream>
#include <vector>
#include <fstream>
using namespace std;
string sort (string slowo){
string litery = slowo;
for (int i=0; i<litery.length()-1; i++)
for (int j=0; j<litery.length()-1; j++)
if (litery[j]>litery[j+1])
swap(litery[j], litery[j+1]); // (3)
return litery;
}
int main()
{
fstream wordlist;
wordlist.open("wordlist_test",ios::in);
vector<string> words;
while (!wordlist.eof()){ // (4)
bool ok = true;
string word;
getline(wordlist,word);
string sorted = sort(word);
if (ok){
cout<<word<<endl; // (1)
words.push_back(word);
}
}
for (int i = 0; i<words.size(); i++){
cout<<words[i]<<endl; // (2)
}
}
There are for words in file "wordlist_tests". Program at the end should just write them to vector and write what's in vector into standard output. The problem is:
however line(1) proves that all words are ok
vector appears to be
empty in line (2)
now iteresting (probably just for me) part:
there are two ways to make it right:
I can just remove line(3) (however, if I am right, as the variable is passed to sort function through the value, it just swap two letters in independent variable; it has nothing to do with my vector), or:
I can change condition in while loop (4).
for example just like this:
int tmp = 0;
while (tmp < 5){
tmp++;
/..../
What is wrong with this code? What should I do write these words down to vector but still sort them and using this while loop? I cannot find the connection between this things (ok, I see that connection is variable word, but I do not know in what way). Any help appreciate.
What happens in swap() if one of the words is the empty sting ""?
If this happens, litery = "".
The condition in the loops will be to iterate from 0 to (unsigned) 0 - 1, which is a very large number.
You'll then execute if (litery[0] > litery[1])
litery[1] will access beyond the end of the empty string, which causes undefined behavior.
Let's fix this:
The common fix for this, is to iterate from 1 to string.length(). Here's an example:
string sort (string litery){
for (int i=1; i<litery.length(); i++)
for (int j=1; j<litery.length(); j++)
if (litery[j-1]>litery[j])
swap(litery[j-1], litery[j]);
return litery;
}