কম্পিউটার টিউটোরিয়াল

C++-এ শর্টেস্ট সুপারস্ট্রিং খুঁজে বের করা

সমস্যা বিবরণ

স্ট্রিংসের অ্যারে A দেওয়া থাকলে, A-এর সব স্ট্রিং সাবস্ট্রিং হিসেবে ধারণকারী ন্যূনতম দৈর্ঘ্যের স্ট্রিং বের করতে হবে। ধরে নেওয়া হয় কোনো স্ট্রিং অন্য স্ট্রিংয়ের সাবস্ট্রিং নয়।

উদাহরণ

A = ["dbsh","dsbbhs","hdsb","ssdb","bshdbsd"] → আউটপুট = "hdsbbhssdbshdbsd"

সমাধান পদ্ধতি

  • গ্রাফ বানানো হয় যেখানে এজ ওয়েট = ওভারল্যাপ দৈর্ঘ্য।
  • ট্রাভেলিং সেলসম্যান প্রোবলেম (TSP) DP দিয়ে সমাধান করা হয়।
  • dp[mask][i] = mask ভিজিট করে i-তে শেষ হয় ন্যূনতম দৈর্ঘ্য।
  • পাথ রিকনস্ট্রাকশন দিয়ে ফাইনাল স্ট্রিং বানানো হয়।

C++ বাস্তবায়ন

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

class Solution {
    int calc(string& a, string& b) {
        for (int i = 0; i < a.size(); i++)
            if (b.find(a.substr(i)) == 0)
                return b.size() - a.size() + i;
        return b.size();
    }
    
public:
    string shortestSuperstring(vector<string>& A) {
        int n = A.size();
        vector<vector<int>> graph(n, vector<int>(n));
        for (int i = 0; i < n; i++)
            for (int j = 0; j < n; j++) {
                graph[i][j] = calc(A[i], A[j]);
                graph[j][i] = calc(A[j], A[i]);
            }
        
        vector<vector<int>> dp(1 << n, vector<int>(n, INT_MAX));
        vector<vector<int>> path(1 << n, vector<int>(n, -1));
        int minVal = INT_MAX, last = -1;
        
        for (int i = 1; i < (1 << n); i++) {
            for (int j = 0; j < n; j++) if (i & (1 << j)) {
                int prev = i ^ (1 << j);
                if (prev == 0) dp[i][j] = A[j].size();
                else {
                    for (int k = 0; k < n; k++)
                        if ((prev & (1 << k)) && dp[prev][k] != INT_MAX &&
                            dp[prev][k] + graph[k][j] < dp[i][j]) {
                            dp[i][j] = dp[prev][k] + graph[k][j];
                            path[i][j] = k;
                        }
                }
                if (i == (1 << n) - 1 && dp[i][j] < minVal) {
                    minVal = dp[i][j];
                    last = j;
                }
            }
        }
        
        string ret;
        stack<int> st;
        int curr = (1 << n) - 1;
        while (curr > 0) {
            st.push(last);
            int temp = curr;
            curr -= (1 << last);
            last = path[temp][last];
        }
        
        int i = st.top(); st.pop();
        ret += A[i];
        while (!st.empty()) {
            int j = st.top(); st.pop();
            ret += A[j].substr(A[j].size() - graph[i][j]);
            i = j;
        }
        return ret;
    }
};

int main() {
    Solution ob;
    vector<string> v = {"dbsh","dsbbhs","hdsb","ssdb","bshdbsd"};
    cout << ob.shortestSuperstring(v);
    return 0;
}

ইনপুট ও আউটপুট

ইনপুট: {"dbsh","dsbbhs","hdsb","ssdb","bshdbsd"}

আউটপুট: hdsbbhssdbshdbsd

  1. সি++-এ একটি রেখার মিড-পয়েন্ট বের করার প্রোগ্রাম

  2. সি++-এ ত্রিভুজের কেন্ড্রয়েড (Centroid) বের করার প্রোগ্রাম

  3. সি++-এ পেন্টাগনের ক্ষেত্রফল বের করার প্রোগ্রাম

  4. সি++-এ সমান্তরাল চতুর্ভুজের (Parallelogram) ক্ষেত্রফল বের করার প্রোগ্রাম