Find Longest common Substring - c++

I need to find longest common substring from two DNA strings.
I have first string "CGATAC", and second: "GACAGTC"
With my code my result is: "GAC", but you can get longer substring, i mean "GATC". What i need to change to get longer substring ?
int k = 0;
for (int i = 0; i < substring1.length(); i++) {
char znak = substring1[i];
for (int j = k; j < substring2.length(); j++) {
char znak2 = substring2[j];
if (znak == znak2) {
end_substring += znak;
k = j;
break;
}
}
}
cout << end_substring;

You can improve your code with some basic ideas. I understand you want one of the longest strings, not all, then you can store the length of the longest string until each moment in the program, and use this length for search string at least of length+1. But the bes solution is use dynamic porgramming, you can read this solution here: https://www.geeksforgeeks.org/longest-common-substring-dp-29/

Related

Return string with some sort of pointers

So I have a code to decode an encoded string. The function has a list of numbers and another list with randomized letters.
The number list is a pointer that indicates which letter is first in an order. The problem is that the numbers are built using this code -
for (int i = 0; i < count; i++)
{
Random r = new Random();
int removeIndex = r.Next(0, splited.Count);
result.Add(splited[removeIndex]);
splited.RemoveAt(removeIndex);
pointers.Add(removeIndex);
}
So basically what happens for example :
Letters = { a, b, c, d}
Pointer = { 2, 0, 1, 0}
Result = { c, a, b, d}
The thing I want to happen is something like in
this example
or in this example
(Result is the requested return. Remaining code is what left in the randomized list.
Initial number and onward is the list generation process.)
What I've tried -
List<char> encodedToChar = new List<char>(encodedText);
List<char> encodedResult = new List<char>();
List<int> whereToRemove = new List<int>();
for (int i = 0; i < length; i++)
{
encodedResult.Add('☺');
}
Console.WriteLine();
Console.WriteLine();
for (int i = 0; i < length; i++)
{
whereToRemove.Add(pointerToInt[i]);
int addCurrentPos = -1;
for (int a = 0; a < whereToRemove.Count; a++)
{
if (pointerToInt[i] >= whereToRemove[a])
{
addCurrentPos++;
}
}
encodedResult[pointerToInt[i] + addCurrentPos] = encodedToChar[i];
Console.Write(" ' " + (int)(pointerToInt[i] + addCurrentPos) + " ' ");
for (int k = 0; k < length; k++)
Console.Write(" " + encodedResult[k]);
Console.Write(" : ");
}
This is the code in action.
which almost works. (Top numbers are pointers and below each pointer is the letter which should be in that position)
I've tried multiple solutions but can't figure one that works.
since the encoded code is made whilst removing the letter, one thing I can think of on how to get the exact position is to somehow count how many letters were removed but there are more problems, for example, if the last 2 remaining letters are the first letter and the last letter (which it is possible) , the pointer can show 0 , 0. and therefor you cant know which one is the last and which one is the first unless you use some kind of a trick which I cant figure out..
(Or maybe it's just not possible and I should change the code generation method)

looking for a faster way to help reduce/create a huge list of strings

I tried to write an algorithm to guess correctly in the game "Masterminds",
it works the average number of guesses is 6, but it takes a lot of time to calculate the best guess.
I used the idea of Knuth the algorithm works as follows:
Create the set S of 1296 possible codes (1111, 1112 ... 6665, 6666).
Start with initial guess 1122 (Knuth gives examples showing that other first guesses such as 1123, 1234 do not win in five tries on
every code).
Play the guess to get a response of colored and white pegs.
If the response is four colored pegs, the game is won, the algorithm terminates.
Otherwise, remove from S any code that would not give the same response if the current guess were the code.
In my code step 2 is to take random number.
I used vector<string> for this.
AllPoss is the vector full of strings, I guess is the last guess that was used. answer is the count of bulls and cows looks like "x,y" (where x and y are numbers)
void bullpgia::SmartGuesser::remove(string guess, string answer)
{
for (auto i= AllPoss.begin();i != AllPoss.end();i++){
string token = *i;
if (calculateBullAndPgia(token, guess) != answer)
AllPoss.erase(i--);
}
}
this is the part it take a lot of time to calculate is there any way of improvement?
to creating the list i used :
void bullpgia::SmartGuesser::All() {
/**
* creates a pool of all the possibilities strings
* we then delete the ones we dont need
* #param length is the length of the word we need to guess
*/
for(int i=0;i<pow(10,length);i++){
stringstream ss;
ss << setw(length) << setfill('0') << i;
string s = ss.str();
AllPoss.push_back(s);
}
}
the function calculateBullAndPgia(string , string) is:
string calculateBullAndPgia(const string &choice, const string &guess) {
string temp = choice;
string temp2 = guess;
unsigned int bull = 0;
unsigned int pgia = 0;
for (int i = 0; i < temp.length(); i++) {
if (temp[i] == temp2[i]) {
bull++;
temp[i] = 'a';
temp2[i] = 'z';
}
}
for (int i = 0; i < temp.length(); i++) {
for (int j = 0; j < temp2.length(); j++) {
if (i != j && temp[i] == temp2[j]) {
pgia++;
temp[i] = 'a';
temp2[j] = 'z';
}
}
}
return to_string(bull) + "," + to_string(pgia);
}
Erasing a single element in the middle of a vector is O(n). My guess is that you wind up doing it O(n) times per call to SmartGuesser::remove. Then you loop over that so you probably have a O(n^3) algorithm. You instead could use std::remove_if, which is O(n), to move all the to-be-erased elements to the end of the vector where they can be cheaply erased.:
AllPoss.erase(std::remove_if(AllPos.begin(), AllPos.end(), [&](const std::string& token, const std::string& guess) { return calculateBullAndPgia(token, guess) != answer; }), AllPos.end());

Having Trouble With The Reversal of a String

class Solution {
public:
string reverseWords(string s) {
int previousWhiteSpace = 0;
for(int i = 0; i <= s.size(); i ++){
if(isspace(s[i]) || i == s.size()){
for(int j = previousWhiteSpace; j < i/2; j++){
char temp = s[j];
s[j] = s[i-1-j];
s[i-1-j] = temp;
}
previousWhiteSpace = i + 1;
}
}
return s;
}
};
Hi. So the goal of my function is to reverse the input of a string. So for example, if I am given "Let's take LeetCode contest" , my function should return "s'teL ekat edoCteeL tsetnoc" . However, currently my function is ONLY returning
"s'teL take LeetCode contest" . I have a counter which I indicate as previousWhiteSpace to keep track of the start of every new word that seems to work for the first word, but not the rest. Any help would be appreciated.
You can simply assign " " to the variable previousWhiteSpace and no need to increment. thus your code will detect white space automatically till the end of the string and will run the code after every white space. As you have assigned value 0 to it will only perform the result for the first word and it will terminate.

Convert a string into a char array

New to C++ and So here is part of a project I'm working on, taking a string and printing the most commonly used number along with how many times it was used. i thought this was right, but for some reason my char array wont be read in. any tips or suggestions on how to fix?
#include <string>
#include <iostream>
using namespace std;
char getMostFreqLetter(string ss);
int main() {
string s; //initilizing a variable for string s
s = ("What is the most common letter in this string "); // giving s a string
getMostFreqLetter(s); // caling the function to print out the most freq Letter
return 0;
}
char getMostFreqLetter(string ss) {
int max, index, i = 0;
int array[255] = {0};
char letters[];
// convert all letters to lowercase to make counting letters non case sensative
for (int i = 0; i < ss.length(); i ++){
ss[i] = tolower(ss[i]);
}
//read each letter into
for (int i = 0; i < ss.length(); i ++){
++array[letters[i]];
}
//
max = array[0];
index = 0;
for (int i = 0; i < ss.length(); i ++){
if( array[i] > max)
{
max = array[i];
index = i;
}
}
return 0;
}
If you are not considering white space as letter.
Then more efficient way could have been
vector<int> count(26,0);
for (int i = 0; i < s.length(); i++) {
int range = to_lower(s[i])-'a';
if ( range >= 0 && range < 26)
count[range]++;
}
// Now you can do fix the max while iterating over count;
Use string::c_str().
It converts a string to a character array.
You have a few errors in your code.
Firstly, the array of chars letters is completely unused. You should disregard it and iterate over the string ss instead which is what I think you intended to do.
This would change your second for loop from ++array[letters[i]]; to ++array[ss[i]];.
Secondly, your last for loop is buggy. You are using i as the index to look for the frequency in array whereas you need to use the ascii value of the character (ss[i]) instead. Here is a fixed version with comments:
index = ss[0];
max = array[index];
for (int i = 0; i < ss.length(); i ++){
if(!isspace(ss[i]) && array[ss[i]] > max)
{
max = array[ss[i]]; // you intended to use the ascii values of the characters in s to mark their place in array. In you code, you use i which is the just the index of the character in s as opposed to the ascii value of that character. Hence you need to use array[ss[i]].
index = ss[i];
}
}
return index;
Once you make the above changes you get the following output when run on your string:
Most freq character: t

c++: string.replace inserting too many characters

I'm trying to step through a given string with a for loop, replacing one character per iteration with a character from a vector[char].
Problem is that the replace inserts the entire vector-k instead of the character at place k and I cannot figure out what I've done wrong.
Any and all help is appreciated.
(alphabet is a const string a-z, FirstWord is the given string).
vector<char> VectorAlphabet;
for (int i=0; i<alphabet.length(); ++i)
{
VectorAlphabet.push_back(alphabet.at(i));
}
for (int i = 0; i < FirstWord.length(); ++i )
{
for (int k = 0; k < VectorAlphabet.size(); ++k)
{
string TempWord = FirstWord;
TempWord.replace(i, 1, &VectorAlphabet[k]);
if (CheckForValidWord(TempWord, WordSet))
{
if(CheckForDuplicateChain(TempWord, DuplicateWordSet))
{
DuplicateWordSet.insert(TempWord);
stack<string> TempStack = WordStack;
TempStack.push(TempWord);
WordQueue.push(TempStack);
}
}
}
}
e.g TempWord = tempword, then after TempWord.replace() on the first iteration it is abcde...zempWord. and not aempword. On the second to last iteration of the second for loop it is yzempword.
What have I missed?
Problem solved, thanks to Dieter Lücking.
Looking closer at the string.replace reference, I see that I tried to use a replace which takes strings as the input, and then the vector[char] is interpreted as a c-string, starting from the k-position.
By using the fill-version of replace the vector position is correctly used as a char instead.
New code is:
for (int i = 0; i < FirstWord.length(); ++i )
{
for (int k = 0; k < VectorAlphabet.size(); ++k)
{
string TempWord = WordStack.top();
// Change:
TempWord.replace(i, 1, 1, VectorAlphabet[k]);
if (CheckForValidWord(TempWord, WordSet))
{
if(CheckForDuplicateChain(TempWord, DuplicateWordSet))
{
DuplicateWordSet.insert(TempWord);
stack<string> TempStack = WordStack;
TempStack.push(TempWord);
WordQueue.push(TempStack);
}
}
}
}