Vzhľadom na pole reťazcov (všetky malé písmená) je úlohou ich zoskupiť tak, aby všetky reťazce v skupine boli navzájom posunutými verziami.
Dve struny s1 a s2 sa nazývajú posunuté, ak sú splnené tieto podmienky:
- s1.dĺžka sa rovná s2.dĺžka
- s1[i] sa rovná s2[i] + m pre všetky 1<= i <= s1.length for a konštantný celé číslo m. Posúvanie považujte za cyklické, teda ak s2[i] + m > 'z', potom začnite od 'a' alebo ak s2[i] + m< 'a' then start from 'z'.
Príklady:
Vstup: arr[] = ['acd' 'dfg' 'wyz' 'yab' 'mop' 'bdfh' 'a' 'x' 'moqs']
výstup: [ ['acd' 'dfg' 'wyz' 'yab' 'mop'] ['bdfh' 'moqs'] ['a' 'x'] ]
Vysvetlenie: Všetky posunuté reťazce sú zoskupené.
Vstup: arr = ['geek' 'for' 'geeks']
výstup: [['for'] ['geek'] ['geeks']]
Prístup: Použitie Hash Map
C++Cieľom je vytvoriť jedinečný hash pre každú skupinu podľa normalizácia struny. Tu normalizácia znamená, že prvý znak každého reťazca bude rovný „a“ vypočítaním požadovaného smeny a jednotne ho aplikovať na všetky znaky v cyklická móda .
Príklad: s = 'dca' posuny = 'd' - 'a' = 3
normalizované znaky: 'd' - 3 = 'a' 'c' - 3 = 'z' a 'a' - 3 = 'x'
normalizovaný reťazec = 'azx'The normalizovaný reťazec (hash) predstavuje posunový vzor tak, že reťazce s rovnakým vzorom majú rovnaký hash. Na sledovanie týchto hashov a ich mapovanie do zodpovedajúcich skupín používame hašovaciu mapu. Pre každý reťazec vypočítame hash a použijeme ho na vytvorenie novej skupiny alebo na pridanie reťazca do existujúcej skupiny v jednom prechode.
// C++ program to print groups of shifted strings // together using Hash Map #include #include #include using namespace std; // Function to generate hash by shifting and equating // the first character string getHash(string s) { // Calculate the shift needed to normalize the string int shifts = s[0] - 'a'; for (char &ch : s) { // Adjust each character by the shift ch = ch - shifts; // Wrap around if the character goes below 'a' if (ch < 'a') ch += 26; } return s; } // Function to group shifted string together vector<vector<string>> groupShiftedString(vector<string> &arr) { vector<vector<string>> res; // Maps hash to index in result unordered_map<string int> mp; for (string s : arr) { // Generate hash representing the shift pattern string hash = getHash(s); // If new hash create a new group if (mp.find(hash) == mp.end()) { mp[hash] = res.size(); res.push_back({}); } // Add string to its group res[mp[hash]].push_back(s); } return res; } int main() { vector<string> arr = {'acd' 'dfg' 'wyz' 'yab' 'mop' 'bdfh' 'a' 'x' 'moqs'}; vector<vector<string>> groups = groupShiftedString(arr); for (vector<string> &group : groups) { for (string &s : group) { cout << s << ' '; } cout << endl; } return 0; }
Java // Java program to print groups of shifted strings // together using Hash Map import java.util.*; class GfG { // Function to generate hash by shifting and equating the // first character static String getHash(String s) { // Calculate the shift needed to normalize the string int shifts = s.charAt(0) - 'a'; char[] chars = s.toCharArray(); for (int i = 0; i < chars.length; i++) { // Adjust each character by the shift chars[i] = (char) (chars[i] - shifts); // Wrap around if the character goes below 'a' if (chars[i] < 'a') chars[i] += 26; } return new String(chars); } // Function to group shifted strings together static ArrayList<ArrayList<String>> groupShiftedString(String[] arr) { ArrayList<ArrayList<String>> res = new ArrayList<>(); // Maps hash to index in result HashMap<String Integer> mp = new HashMap<>(); for (String s : arr) { // Generate hash representing the shift pattern String hash = getHash(s); // If new hash create a new group if (!mp.containsKey(hash)) { mp.put(hash res.size()); res.add(new ArrayList<>()); } // Add string to its group res.get(mp.get(hash)).add(s); } return res; } public static void main(String[] args) { String[] arr = {'acd' 'dfg' 'wyz' 'yab' 'mop' 'bdfh' 'a' 'x' 'moqs'}; ArrayList<ArrayList<String>> groups = groupShiftedString(arr); for (ArrayList<String> group : groups) { for (String s : group) { System.out.print(s + ' '); } System.out.println(); } } }
Python # Python program to print groups of shifted strings # together using Hash Map # Function to generate hash by shifting and equating the first character def getHash(s): # Calculate the shift needed to normalize the string shifts = ord(s[0]) - ord('a') hashVal = [] for ch in s: # Adjust each character by the shift newCh = chr(ord(ch) - shifts) # Wrap around if the character goes below 'a' if newCh < 'a': newCh = chr(ord(newCh) + 26) hashVal.append(newCh) return ''.join(hashVal) # Function to group shifted strings together def groupShiftedString(arr): res = [] # Maps hash to index in result mp = {} for s in arr: # Generate hash representing the shift pattern hashVal = getHash(s) # If new hash create a new group if hashVal not in mp: mp[hashVal] = len(res) res.append([]) # Add string to its group res[mp[hashVal]].append(s) return res if __name__ == '__main__': arr = ['acd' 'dfg' 'wyz' 'yab' 'mop' 'bdfh' 'a' 'x' 'moqs'] groups = groupShiftedString(arr) for group in groups: print(' '.join(group))
C# // C# program to print groups of shifted strings // together using Hash Map using System; using System.Collections.Generic; class GfG { // Function to generate hash by shifting and equating the first character static string getHash(string s) { // Calculate the shift needed to normalize the string int shifts = s[0] - 'a'; char[] chars = s.ToCharArray(); for (int i = 0; i < chars.Length; i++) { // Adjust each character by the shift chars[i] = (char)(chars[i] - shifts); // Wrap around if the character goes below 'a' if (chars[i] < 'a') chars[i] += (char)26; } return new string(chars); } // Function to group shifted strings together static List<List<string>> groupShiftedString(string[] arr) { List<List<string>> res = new List<List<string>>(); // Maps hash to index in result Dictionary<string int> mp = new Dictionary<string int>(); foreach (string s in arr) { // Generate hash representing the shift pattern string hash = getHash(s); // If new hash create a new group if (!mp.ContainsKey(hash)) { mp[hash] = res.Count; res.Add(new List<string>()); } // Add string to its group res[mp[hash]].Add(s); } return res; } static void Main(string[] args) { string[] arr = { 'acd' 'dfg' 'wyz' 'yab' 'mop' 'bdfh' 'a' 'x' 'moqs' }; var groups = groupShiftedString(arr); foreach (var group in groups) { Console.WriteLine(string.Join(' ' group)); } } }
JavaScript // JavaScript program to print groups of shifted strings // together using Hash Map // Function to generate hash by shifting and equating the first character function getHash(s) { // Calculate the shift needed to normalize the string const shifts = s.charCodeAt(0) - 'a'.charCodeAt(0); let chars = []; for (let ch of s) { // Adjust each character by the shift let newChar = String.fromCharCode(ch.charCodeAt(0) - shifts); // Wrap around if the character goes below 'a' if (newChar < 'a') newChar = String.fromCharCode(newChar.charCodeAt(0) + 26); chars.push(newChar); } return chars.join(''); } // Function to group shifted strings together function groupShiftedString(arr) { const res = []; // Maps hash to index in result const mp = new Map(); for (let s of arr) { // Generate hash representing the shift pattern const hash = getHash(s); // If new hash create a new group if (!mp.has(hash)) { mp.set(hash res.length); res.push([]); } // Add string to its group res[mp.get(hash)].push(s); } return res; } // Driver Code const arr = ['acd' 'dfg' 'wyz' 'yab' 'mop' 'bdfh' 'a' 'x' 'moqs']; const groups = groupShiftedString(arr); groups.forEach(group => console.log(group.join(' ')));
Výstup
acd dfg wyz yab mop bdfh moqs a x
Časová zložitosť: O(n*k) kde n je dĺžka poľa reťazcov a k je maximálna dĺžka reťazca v poli reťazcov.
Pomocný priestor: O(n*k) v najhoršom prípade môžeme vygenerovať n rôznych hash reťazcov pre každý vstupný reťazec. Takže v hašovacej mape máme n rôznych záznamov s dĺžkou k alebo menšou.