-1

In this question, we take 2 strings as input say s1 and s2.

Now, first we need to check if s2 is a subsequence of s1. If not, print no.

But if it is, we need to print the minimum number of characters to be deleted from s1 to get s2.

Eg- thistext text

Here, text can be directly found without deleting any characters so the answer is 0.

Eg- cutefriendship crisp

In this case, the answer is 9.

What I've done so far,

#include <bits/stdc++.h>
using namespace std;

int checkIfSub(string s1, string s2, int m, int n)
{
    int j = 0;
    for(int i = 0; i < m && j < n; i++)
        if(s1[i] == s2[j])
            j++;
    if(j == n)
        return 0;
    else 
        return 1;
}
int check(string s1, string s2)
{
    int count = 0; string s3;
    if(checkIfSub(s1, s2, s1.length(), s2.length()) == 1 || s2.length() > s1.length())
    {
        cout << "NO\n"; return 0;
    }
    int j = 0;
    for(int i = 0; i < s1.length(); i++)
    {
        if(s1[i] == s2[j])
        {
            s3[j] = s1[j];
            j++; continue;
        }
        count++;
    }
    cout << "YES " << count << "\n";
    return 0;
}

int main() {

    string s1, s2;
    cin >> s1 >> s2;
    check(s1, s2);

    return 0;
}

My code works well for the second example, but fails the first case.

(This was a question asked in some interview I read online.)

  • Other issues aside, you create the empty string `s3`, appear to write to it invalidly with the statement `s3[j] = s1[j]`, and never use it other than that. Can you explain that part of the code? – scg Dec 12 '19 at 20:12
  • 2
    Unrelated, but you should take a look at [Why should I not #include ?](https://stackoverflow.com/questions/31816095/why-should-i-not-include-bits-stdc-h) and [Why is “using namespace std;” considered bad practice?](https://stackoverflow.com/questions/1452721/why-is-using-namespace-std-considered-bad-practice) to void potential problems. – churill Dec 12 '19 at 20:16
  • I think you just confused the return code `checkIfSub`. Should it really return 0 (false) when all characters of `s2` were matched? – churill Dec 12 '19 at 20:27
  • @FrançoisAndrieux OP is searching for a subsequence, not a substring, i.e. the question is, whether it is possible to delete characters from `s1` such that it becomes `s2`. Hence `crisp` is a subsequence of `CutefRIendShiP` (emphasis mine^^). – n314159 Dec 12 '19 at 20:28
  • OP: Regardless problems with the implementation, your algorithm is too simple to check what you want to check. What it does is to just calculate `s1.lenght() - s2.length()`. You either want to research a bit more about this problem or think for yourself about a different way approaching this. – n314159 Dec 12 '19 at 20:32
  • *Now, first we need to check if s2 is a subsequence of s1* -- A competent interviewer would keep a keen eye on how you solve this problem first. The [std::string::find](https://en.cppreference.com/w/cpp/string/basic_string/find) does this. – PaulMcKenzie Dec 12 '19 at 20:35
  • @PaulMcKenzie: I think the problem as stated refers to a possibly non-contiguous subsequence, and not strictly a substring, so I'm not sure find() is relevant here. – scg Dec 12 '19 at 20:40
  • @scg You can use `std::string::find()` for this, see the answer I just posted – Remy Lebeau Dec 13 '19 at 00:53
  • @Remy Lebeau: I see. I thought the previous poster meant using it to search for a complete substring rather than individual characters, but that was just an (unfounded) assumption. You can of course use it find individual characters. – scg Dec 13 '19 at 02:16

1 Answers1

0

Try something like this:

#include <iostream>
#include <string>
using namespace std;

bool check(const string &s1, const string &s2, int &minToDelete)
{
    minToDelete = 0;
    bool anySubSeqFound = false;

    if (s2.empty())
        return false;

    string::size_type first = 0;
    while ((first = s1.find(s2[0], first)) != string::npos)
    {
        int numDeleted = 0;
        bool isSubSeq = true;

        string::size_type next = first + 1;
        for(string::size_type j = 1; j < s2.size(); ++j)
        {
            string::size_type found = s1.find(s2[j], next);
            if (found == string::npos)
            {
                isSubSeq = false;
                break;
            }
            numDeleted += (found - next);
            next = found + 1;
        }

        if (isSubSeq)
        {
            if (anySubSeqFound)
            {
                if (numDeleted < minToDelete)
                    minToDelete = numDeleted;
            }
            else
            {           
                anySubSeqFound = true;
                minToDelete = numDeleted;
            }
        }

        ++first;
    }

    return anySubSeqFound;
}

int main()
{
    int minToDelete;

    if (check("thistext", "text", minToDelete))
        cout << "yes, delete " << minToDelete << endl;
    else
        cout << "no" << endl;

    if (check("cutefriendship", "crisp", minToDelete))
        cout << "yes, delete " << minToDelete << endl;
    else
        cout << "no" << endl;
}

Live Demo

Remy Lebeau
  • 454,445
  • 28
  • 366
  • 620