Strings & Pattern Basics
স্ট্রিং ও প্যাটার্ন
1. What Is a String, Really?
A string is just an array of characters with a special "I am done" marker.
In C, that marker is the null byte '\0'; in C++ std::string stores its
length explicitly so it does not need a terminator.
Everything text-related — your bKash SMS, a Codeforces problem statement, the URL bar of your browser —
is internally a string.
'\0'; কিন্তু C++-এর std::string length আলাদাভাবে রাখে — তাই terminator লাগে না। আপনার bKash SMS, Codeforces-এর প্রশ্ন, browser-এর URL — সবই ভেতরে ভেতরে string।
2. char[] vs std::string
A C-style string char s[] = "hello"; is 6 bytes: 'h','e','l','l','o','\0'.
Functions like strlen count bytes until they see the null terminator — that is O(n).
By contrast, std::string s = "hello"; s.size(); is O(1) because the length is stored.
char s[] = "hello"; = 6 byte (শেষে '\0' সহ)। strlen '\0' পর্যন্ত গুনে চলে — O(n)। কিন্তু std::string::size() O(1), কারণ length আগেই সংরক্ষিত আছে। প্রতিদিনের কোডে std::string ব্যবহার করুন; C-style শুধু low-level কাজে।
| Operation | char[] | std::string |
|---|---|---|
| length | O(n) (strlen) | O(1) (.size()) |
| append | manual + bounds risk | +=, amortised O(1) per char |
| compare | strcmp | == operator |
| safety | buffer overflow risk | auto-resize, safe |
3. Naive Pattern Matching
Given a text T of length n and a pattern P of length m, we want every index in T where P matches. The naive method slides P over T one position at a time and compares character-by-character — worst-case O(nm).
4. Demo 1 — All Match Positions (Naive)
#include <bits/stdc++.h>
using namespace std;
vector<int> naiveMatch(const string& T, const string& P) {
vector<int> pos;
int n = T.size(), m = P.size();
for (int i = 0; i + m <= n; i++) {
int j = 0;
while (j < m && T[i + j] == P[j]) j++;
if (j == m) pos.push_back(i);
}
return pos;
}
int main() {
string T = "ABCABABCABABABABCABAB", P = "ABAB";
auto r = naiveMatch(T, P);
cout << "Matches at: ";
for (int p : r) cout << p << " ";
cout << "\n";
return 0;
}
5. Demo 2 — Anagram Check & Longest Common Prefix
Two strings are anagrams if one is a rearrangement of the other. The fastest way: count character frequencies in a 26-element array. LCP (longest common prefix) of an array of strings is found by scanning columns.
#include <bits/stdc++.h>
using namespace std;
bool isAnagram(const string& a, const string& b) {
if (a.size() != b.size()) return false;
int f[26] = {0};
for (char c : a) f[c - 'a']++;
for (char c : b) f[c - 'a']--;
for (int i = 0; i < 26; i++) if (f[i]) return false;
return true;
}
string longestCommonPrefix(vector<string>& v) {
if (v.empty()) return "";
string p = v[0];
for (int i = 1; i < (int)v.size(); i++) {
int k = 0;
while (k < (int)p.size() && k < (int)v[i].size() && p[k] == v[i][k]) k++;
p = p.substr(0, k);
if (p.empty()) break;
}
return p;
}
int main() {
cout << isAnagram("listen", "silent") << "\n";
vector<string> v = {"flower", "flow", "flight"};
cout << longestCommonPrefix(v) << "\n";
return 0;
}
6. Palindromes & the Bangla UTF-8 Trap
A palindrome reads the same forwards and backwards: "madam", "racecar". The check is a two-pointer walk.
But beware — Bangla text in UTF-8 uses multiple bytes per visual character.
"কথা" is 9 bytes, not 3! Walking it byte-by-byte will produce nonsense.
"কথা" প্রকৃত পক্ষে 9 byte! তাই Bangla string-কে byte-by-byte না ঘুরে UTF-8 codepoint হিসেবে decode করতে হয় (পরে আমরা ICU/codecvt দেখব)।
s.size() on a Bangla string returns byte count, not character count.
For competitive programming, this is usually fine because problems use ASCII. But for real apps (bKash, Pathao SMS templates), use a UTF-8 aware library.
7. std::string Toolbox
Extract a slice — O(len)।
First occurrence or
npos।Concatenate, amortised O(n)।
Sort characters — O(n log n)।
In-place reverse — O(n)।
Lexicographic compare — O(min(n,m))।
8. Practice Problems
-
Count the number of vowels in a string.একটি string-এ vowel-এর সংখ্যা গুনুন।
✨ Show Answer (উত্তর দেখুন)
ans1.cpp#include <bits/stdc++.h> using namespace std; int main() { string s = "Bangladesh University of Engineering and Technology"; int c = 0; for (char ch : s) { char x = tolower(ch); if (x=='a'||x=='e'||x=='i'||x=='o'||x=='u') c++; } cout << c << "\n"; } -
Reverse the words in a sentence (e.g., "I love DSA" → "DSA love I").একটি বাক্যের শব্দগুলো reverse করুন (যেমন "I love DSA" → "DSA love I")।
✨ Show Answer (উত্তর দেখুন)
ans2.cpp#include <bits/stdc++.h> using namespace std; int main() { string s = "I love DSA from Dhaka"; stringstream ss(s); vector<string> w; string tok; while (ss >> tok) w.push_back(tok); reverse(w.begin(), w.end()); for (int i = 0; i < (int)w.size(); i++) cout << w[i] << (i+1<(int)w.size()?" ":"\n"); } -
Check if a string is a palindrome ignoring spaces, punctuation and case.Space, punctuation ও case উপেক্ষা করে palindrome কিনা যাচাই করুন।
✨ Show Answer (উত্তর দেখুন)
ans3.cpp#include <bits/stdc++.h> using namespace std; int main() { string s = "A man, a plan, a canal: Panama"; int l = 0, r = s.size() - 1; bool ok = true; while (l < r) { while (l < r && !isalnum(s[l])) l++; while (l < r && !isalnum(s[r])) r--; if (tolower(s[l]) != tolower(s[r])) { ok = false; break; } l++; r--; } cout << (ok ? "YES" : "NO") << "\n"; } -
Find the longest palindromic substring (brute-force O(n³)).Longest palindromic substring বের করুন (brute-force O(n³))।
✨ Show Answer (উত্তর দেখুন)
ans4.cpp#include <bits/stdc++.h> using namespace std; bool isPal(const string& s,int l,int r){while(l<r){if(s[l++]!=s[r--]) return false;}return true;} int main() { string s = "babad", best = ""; int n = s.size(); for (int i = 0; i < n; i++) for (int j = i; j < n; j++) if (isPal(s, i, j) && j - i + 1 > (int)best.size()) best = s.substr(i, j - i + 1); cout << best << "\n"; } -
Find the first non-repeating character in a string.String-এ প্রথম non-repeating character খুঁজুন।
✨ Show Answer (উত্তর দেখুন)
ans5.cpp#include <bits/stdc++.h> using namespace std; int main() { string s = "leetcode"; int f[256] = {0}; for (char c : s) f[(int)c]++; char ans = '?'; for (char c : s) if (f[(int)c] == 1) { ans = c; break; } cout << ans << "\n"; } -
Check whether two strings are anagrams using a 26-int frequency array.26-int frequency array দিয়ে দুটি string anagram কিনা যাচাই করুন।
✨ Show Answer (উত্তর দেখুন)
ans6.cpp#include <bits/stdc++.h> using namespace std; int main() { string a = "anagram", b = "nagaram"; if (a.size() != b.size()) { cout << "NO\n"; return 0; } int f[26] = {0}; for (char c : a) f[c-'a']++; for (char c : b) f[c-'a']--; bool ok = true; for (int i = 0; i < 26; i++) if (f[i]) ok = false; cout << (ok ? "YES" : "NO") << "\n"; } -
Implement
strStr(return index of first occurrence of needle in haystack, or -1).strStrবানান — haystack-এ needle প্রথম যেখানে আছে সেই index, না থাকলে -1।✨ Show Answer (উত্তর দেখুন)
ans7.cpp#include <bits/stdc++.h> using namespace std; int strStr(const string& H, const string& N) { int n = H.size(), m = N.size(); if (m == 0) return 0; for (int i = 0; i + m <= n; i++) { int j = 0; while (j < m && H[i+j] == N[j]) j++; if (j == m) return i; } return -1; } int main() { cout << strStr("sadbutsad", "sad") << "\n"; cout << strStr("hello", "world") << "\n"; }
Summary — Module 07
Strings are arrays of characters; std::string tracks length explicitly so most operations
are convenient and fast. Naive pattern matching is simple but O(nm) — fine for short patterns,
disastrous for long ones. Frequency arrays solve anagrams and many counting problems in O(n).
For Bangla text, remember UTF-8 multi-byte encoding — byte-level loops will mis-handle characters.
std::string length আলাদা রাখে — তাই দ্রুত। Naive pattern matching সরল হলেও O(nm), বড় pattern-এ TLE। Frequency array দিয়ে anagram ও counting সমস্যা O(n)-এ সমাধান হয়। Bangla text-এ UTF-8 multi-byte — byte-loop বিভ্রান্ত করবে, সাবধান।