I am trying to understand how backtracking works. I am working on permutation of a string.
class Solution {
public:
void permute(string s,int count[], string res, int level, vector<string> &perS)
{
if( level == s.size())
{
//cout<<res<<endl;
perS.push_back(res);
return;
}
int i;
for(i=0; i<s.size(); i++)
{
if(count[i]==0)
{
continue;
}
res += s[i];
count[i]--;
permute(s, count, res, level+1, perS);
count[i]++;
//this line is problem I think?? how to handle if s1 contains duplicates??
res.erase(res.end()-1);
}
}
bool checkInclusion(string s1, string s2) {
map<char, int> mp;
for(int i=0; i<s1.size(); i++)
{
mp[s1[i]]++;
}
int *count = new int[mp.size()];
set<char> us;
//to generate the count array of all the characters
for(int i=0; i<s1.size(); i++)
{
us.insert(s1[i]);
}
auto it = us.begin();
for(int i=0; i<mp.size(); i++)
{
count[i] = mp[*it++]++;
}
string res;
vector<string> perS;
permute(s1, count, res, 0, perS);
//check if s2 contains in pers;
for(string x:perS)
{
if(s2.find(x)!=string::npos)
return true;
}
return false;
}
};
The above code works when I pass s1 as "helo" but give stackoverflow error if it has duplicates in it ex. "hello".
The algorithm I am trying to understand is very simple. we select a character from the string and traverse the other characters. once we reach the end we backtrack and check other options.
I tried but not able to understand why it fails for string having duplicates.
https://www.youtube.com/watch?v=nYFd7VHKyWQ&t=1346s
I am trying the same algo explained in the above url, but I am trying to code it in cpp language.
I would really appreciate any input on this. This is my first question so pardon me for any error. it will help me visualise the recursive flow for backtracking problem.
Related
I am unable to get why there is a space and it is getting me wrong.
Below is the code I wrote for the solution
Why there is blank space char at the end of the string at the end even after reversing my string.
Question
class Solution {
public:
string minRemoveToMakeValid(string s) {
string str = "";
int n = s.length();
int open=0;
for(int i=0;i<n;i++){
if(s[i]=='('){
open++;
}else if(s[i]==')'){
open--;
if(open<0){
open=0;
continue;
}
}
str+=s[i];
}
open=0;
string s2="";
for(int i=n-1;i>=0;i--){
if(str[i]==')'){
open++;
}else if(str[i]=='('){
open--;
if(open<0){
open=0;
continue;
}
}
s2=s2+str[i];
}
reverse(s2.begin(),s2.end());
return s2;
}
};
Leetcode Submission getting wrong
The length of str may be less than one of s, but you are using the length of s while iterating within str. You must use correct length.
string s2="";
n = str.length(); // add this
for(int i=n-1;i>=0;i--){
I am trying this Code
string str;
ll size=0;
vector<string> finalStr;
while(getline(cin, str))
{
for(int i=0; i<str.length(); i++)
{
if(count)
{
if(str[i]=='"')
{
str.erase(i, 1);
str.insert(i,"``");
count = false;
}
}
if(!count)
{
if(str[i]=='"')
{
str.erase(i, 1);
str.insert(i,"''");
count = true;
}
}
}
finalStr[size++] = str;
}
This Code doesn't work. I need reason why it is working when I am using finStr.push_back(str).
Above Code is working good Till I Assigned the input string to my vector of String using equals operator.
I am a beginner in solving algorithmic questions. Until now, I have only self-taught coding. So, I am not sure about the proper conventions.
I was trying to solve a question to reverse a string.There is some problem with the code but I am not sure what it is after debugging step-by-step.
class Solution {
public:
string reverseString(string s) {
int n = s.length();
string reverse;
for (int i=0;i<s.length();i++)
{
reverse[i] = s[n-1];
n=n-1;
}
return reverse;
}
};
Input: "Hello"
Output needed: "olleh"
My output: "olleh " (extra space)
Input: A man, a plan, a canal: Panama
Output: No output
I searched online for solutions. There were related to pointers. It would be great if someone helped me understand why this logic doesn't work and why using pointers is a better idea.
ALREADY GIVEN. CANNOT CHANGE:
string stringToString(string input) {
assert(input.length() >= 2);
string result;
for (int i = 1; i < input.length() -1; i++) {
char currentChar = input[i];
if (input[i] == '\\') {
char nextChar = input[i+1];
switch (nextChar) {
case '\"': result.push_back('\"'); break;
case '/' : result.push_back('/'); break;
case '\\': result.push_back('\\'); break;
case 'b' : result.push_back('\b'); break;
case 'f' : result.push_back('\f'); break;
case 'r' : result.push_back('\r'); break;
case 'n' : result.push_back('\n'); break;
case 't' : result.push_back('\t'); break;
default: break;
}
i++;
} else {
result.push_back(currentChar);
}
}
return result;
}
int main() {
string line;
while (getline(cin, line)) {
string s = stringToString(line);
string ret = Solution().reverseString(s);
string out = (ret);
cout << out << endl;
}
return 0;
}
As you create reverse, you have to pass the length of the string as an argument, else the created string will be of size 0. This could look like this:
string reverseString(string s) {
int n = s.length();
string reverse(n,'0');
for (int i=0;i<s.length();i++)
{
reverse[i] = s[n-1];
n=n-1;
}
return reverse;
}
Reversing a string is trivial. Just construct a new one from the reverse iterators:
std::string reverse_str(s.rbegin(), s.rend());
or
std::string reverse_str(s.crbegin(), s.crend());
Here's how I would write your function:
string reverseString(const string& s) {
return {s.crbegin(), s.crend()};
}
Try this out
class Solution {
public:
string reverseString(string s) {
//cout<<"inside func";
int n = s.length();
cout<<n<<endl;
char reverse[sizeof(char)*n];// reverse stores the reverse of original string s
int i= 0;
for ( i=0;i<s.length();i++)
{
reverse[i] = s[n-i-1];
}
return reverse;
}
}
int main()
{
string s,r;
Solution sol;
s= "hello";
r= sol.reverseString(s);
cout<<r<<endl;
cout<<r.length()<<endl;
return 0;
}
when i= 0, n-i-1= n-1 which is the last element of the original string s. So the first element of the reverse string is the last element of s. Next i becomes i+1 i.e 1. This time second element of the reverse string is the last but one element in string s. This procedure is repeated till i < s.length(). The element to get copied is for index i= n-1 and n becomes n-(n-1)-1= 0, so the last element of reverse string is the first element of s. After this the loop exists. No additional extra characters are added.
I am writing a program that will input an alphabetic message, and use the class to build the morse code string, and then output the string. I have written all the method and the program compiles fine. However when I enter the temp string and hit return. I am given a segmentation fault. I can't seem to find the problem. If anyone can see what the problem is I would greatly appreciate your help. Thanks.
#include <string>
#include <vector>
#include <fstream>
using namespace std;
class Code
{
public:
Code(); // Default constructor - loads and uses morse code
string decode(vector< string> message); // decodes a message
string encode(vector<char> message); // encodes a message
private:
vector<string> codewords; // this is a codeword vector parallel to A-Z
vector<char> alpha; // this is the vector for A-Z
vector<char> alphacode(); // function builds the vector alpha - A B C etc.
vector<string> morsecode(); // function builds the vector codewords containing morse code
char decode(string c); //returns the character for the codeword c.
string encode(char c);
};
Code::Code() {
alpha = alphacode();
codewords = morsecode();
}
string Code::decode(vector< string> message) {
string temp;
for (int i=0; i < message.size(); i++) {
temp += decode(message[i]);
}
return temp;
}
string Code::encode(vector<char> message)
{
string temp;
for (int i=0; i<message.size(); i++)
{
temp+=encode(message[i]);
}
return temp;
}
vector<string> Code::morsecode()
{ // This function returns a vector containing the morse code
vector<string> temp(28);
temp[0] =".-";
temp[1] ="-...";
temp[2] ="-.-.";
temp[3] ="-..";
temp[4] =".";
temp[5] ="..-.";
temp[6] ="--.";
temp[7] ="....";
temp[8] ="..";
temp[9] =".---";
temp[10] ="-.-";
temp[11] =".-..";
temp[12] ="--";
temp[13] ="-.";
temp[14] ="---";
temp[15] =".--.";
temp[16] ="--.--";
temp[17] =".-.";
temp[18] ="...";
temp[19] ="-";
temp[20] ="..-";
temp[21] ="...-";
temp[22] =".--";
temp[23] ="-..-";
temp[24] ="-.--";
temp[25] ="--..";
temp[26] =".......";
temp[27] ="x";
return temp;
}
vector<char> Code::alphacode()
{// This returns a vector containing the alphabet a-z and " "
vector<char> temp;
for (char c='A'; c<='Z'; c++)
temp.push_back(c);
temp.push_back(' ');
temp.push_back('.');
return temp;
}
char Code::decode(string c)
{
for (int i = 0; i < alpha.size(); i++) {
if(c == codewords[i]) {
return alpha[i];
}
}
}
string Code::encode(char c)
{
for (int i=0;i<codewords.size();i++)
{
if (c==alpha[i])
{
return codewords[i];
}
}
}
int main()
{
vector<char> message;
string temp;
getline(cin, temp);
for (int i=0; i <temp.length(); i++)
{
message.push_back(temp[i]);
}
Code C;
cout << C.encode(message) << endl;
}
Your alphacodes and morsecodes are only for Capital letters, so this function returns null resulting in problems.
string Code::encode(char c)
{
for (int i=0;i<codewords.size();i++)
{
if (c==alpha[i])
{
return codewords[i];
}
}
}
Your check for c==alpha[i] should either check ignoring the case or your alpha codes should have small alphabet codes as well. Your morsecodes should have the codes for small alphabets as well and your checks where you map A-Z to 0-28 should accommodate small letters.
Remember, small letters have different ASCII codes than Capital letters.
The following function does not have a return statement at the end.
string Code::encode(char c)
{
for (int i=0;i<codewords.size();i++)
{
if (c==alpha[i])
{
return codewords[i];
}
}
// What should happen if execution gets to this line?
}
If, per chance, your code reaches the end of the function, you will run into undefined behavior. That could be the source of your problem.
I'm a C# programmer that recently wanted to delve into something lower level so last week started learning C++ but have stumbled on something I thought would be fairly simple.
I enter the following string into my program:
"this is a test this test" and would expect the wordStructList to contain a list of 4 words, with occurrences of "test" and "this" set to 2. When debugging however, the string comparison (I've tried .compare and ==) always seems to increasing the value of occurrences no matter whether the comparison is true.
e.g. currentName = "is"
word = "this"
but occurrences is still been incremented.
#include "stdafx.h"
using std::string;
using std::vector;
using std::find;
using std::distance;
struct Word
{
string name;
int occurrences;
};
struct find_word : std::unary_function<Word, bool>
{
string name;
find_word(string name):name(name) { }
bool operator()(Word const& w) const
{
return w.name == name;
}
};
Word GetWordStruct(string name)
{
Word word;
word.name = name;
word.occurrences = 1;
return word;
}
int main(int argc, char argv[])
{
string s;
string delimiter = " ";
vector<string> wordStringList;
getline(std::cin, s);
do
{
wordStringList.push_back(s.substr(0, s.find(delimiter)));
s.erase(0, s.find(delimiter) + delimiter.length());
if (s.find(delimiter) == -1)
{
wordStringList.push_back(s);
s = "";
}
} while (s != "");
vector<Word> wordStructList;
for (int i = 0; i < wordStringList.size(); i++)
{
Word newWord;
vector<Word>::iterator it = find_if(wordStructList.begin(), wordStructList.end(), find_word(wordStringList[i]));
if (it == wordStructList.end())
wordStructList.push_back(GetWordStruct(wordStringList[i]));
else
{
string word(wordStringList[i]);
for (vector<Word>::size_type j = 0; j != wordStructList.size(); ++j)
{
string currentName = wordStructList[j].name;
if(currentName.compare(word) == 0);
wordStructList[j].occurrences++;
}
}
}
return 0;
}
I hope the question makes sense. Anyone shed any light on this? I'm also open to any tips about how to make the code more sensible/readable. Thanks
The problem is the semicolon after this if statement:
if(currentName.compare(word) == 0);
The semicolon terminates the statement, so the next line
wordStructList[j].occurrences++;
is not part of the if statement any more and will always be executed.