重新排列给定的字符串,使所有质数倍数指标具有相同字符
字符串是一系列字符、数字、字母数字字符和特殊字符。字符串的长度是其中包含的字符数。质数是只能被 1 和自身整除的数。
在这篇文章中,我们给出了一个长度为 n 的示例输入字符串。我们将开发一个代码,其思想是在任意位置 p 替换相同的字符,以便从 1 到 n/p 范围内的字符位置重合。
下面是一些说明问题陈述的示例 −
示例示例
示例 1 - alphaaa
输出 - haaalap
解释 - 质数索引 2、4、6 和索引 3、6 包含相同的字符“a”。
示例 1 - alphaa
输出 - -1
解释 - 只要我们从字符串中减少一个字符“a”,所有必需的
位置不能容纳相同的字符。因此,返回的输出是 -1。
算法
步骤 1 − 初始化一个映射来记录字符串中出现的字符数。
步骤 2 − 地图包含一个类型元组
用于存储字符及其各自的频率。 步骤 3 − 每次遇到一个字符时,它的频率都会增加 1。
步骤 4 − 向量 vec 也被初始化以保持反向形式的地图条目,性质如下:
其中将计数和与其关联的相应字符推入向量。 步骤 5 − 然后对向量进行排序,以便按其频率对字符进行排序。
步骤 6 − 位置数组 pos 声明为与可能的最大值等效的大小。
步骤 7 − 使用 C++ STL 中提供的 fill() 方法对其初始化为值 1。
步骤 8 − 使用指针 i,从整数值 2 开始启动字符串的迭代,如果此位置的 pos 数组包含一个值,那么使用指针 j 评估所有素数倍数。
步骤 9 − 对于所有有效位置,填充有相同字符的位置的计数器都会递增。
步骤 10 − 否则,评估 i*j 索引的 pos 值。
步骤 11 − 然后存储出现次数最多的字符的频率,把它认为是很多。
步骤 12 − 如果占用的位置数大于出现最多的字符频率,则返回 -1,因为这是一个不可能的操作。
步骤 13 − 否则,最初所有素数倍数索引(即理想位置)都由出现次数最多的字符填出。
步骤 14 − 然后填充剩余位置。
步骤 15 − 每次从向量中取出一个字符并填充在剩余位置。
步骤 16 − 此字符的频率递减。
步骤 17 − 当某个特定字符的所有出现都被用完时,则从向量中获取下一个字符。
步骤 18 − 最后交换字符后打印输出数组字符串。
示例
以下 C++ 代码片段采用一个示例输入字符串,然后将相同字符(如果可能)放入所有素数倍数索引中。
//including the required libraries #include <bits/stdc++.h> using namespace std; //rearranging prime indexes to store same character void primeindx(string str){ // To store the result after transformation char res[100005]; int pos[100005]; //calculating the size of string int len = str.size(); //counter of same elements int cnt = 0; //maintaining map to store the number of occurrences of characters in string map<char, int> map; for (auto ch : str){ //incrementing count of character map[ch]+=1; } //maintaining a vector to store the different characters in map and their respective counts to sort them according to the frequency vector<pair<int, char> > vec; for (auto entry : map) vec.push_back({ entry.second, entry.first }); //sorting the vector according to the frequencies sort(vec.begin(), vec.end()); //fill the positions of the array pos with 1 fill(pos + 1, pos + len + 1, 1); //storing indices correctly in the pos array for (int i = 2; i <= len / 2; i++) { //check if the value at pos[i] is equivalent to 1 if (pos[i]) { //getting all multiples of i for (int j = 1; i*j<= len; j++) { int val = i*j; if (pos[val]) //incrementing the number of same characters is value is contained in the multiple cnt++; //else storing 0 in the pos vector at that position pos[val] = 0; } } } //getting the occurrence of the character occurring the maximum number of times int mch = vec.back().first; if ( mch < cnt) { //not possible cout << -1; return; } for (int i = 2; i <= len; i++) { if (!pos[i]) { //storing the character at the prime indexes is the count of the same character satisfies res[i] = vec.back().second; } } //fetching characters after prime indexes have been filled out int k = 0; for (int i = 1; i <= len; i++) { //if ith index contains 1 if (pos[i]) { //get the character in the result array res[i] = vec[k].second; //decrement the count available for the character that has been substitutes vec[k].first-=1; //if there are no more occurrences of that particular character, skip to next one if (vec[k].first == 0) k++; } } //printing the final result array for(int i =1;i<=len;i++){ cout << res[i]; } } //calling the main method int main(){ //declaring a sample string string str = "codeeee"; //prime multiple indexes arrangement of character primeindx(str); return 0; }
输出
ceeedeo
结论
字符计数是 C++ 字符串的一个重要方面。基于字符串中可用的字符频率,可以做出大量决策。映射是存储数据对的一种有效方式,例如字符及其各自的计数,并且非常直观。