Substring with maximum ASCII sum when some ASCII values are redefined

In this problem, we will find the substring of the given string whose character's ASCII value's sum is maximum when we redefine the ASCII values.

The naïve approach to solve the problem is to find the sum of all substring's character's ASCII value and get the substring having maximum sum.

Another approach to solving the problem is using Kadane's algorithm to find the maximum sub-array sum.

Problem statement - We have given a string alpha of size N containing the alphabetical characters. We have also given the chars[], and ASCII[] array of size M, where chars[] contains the characters, and Ascii[i] contains the updated ASCII value of the chars[i] character. Furthermore, consider that string is case-sensitive.

We need to find the substring whose character's ASCII value's sum is maximum.

Sample examples

Input

alpha = "apper"; chars[char_len] = {'p'}; Ascii[char_len] = {-800};


Output

'er'

Explanation - Here, the ASCII value of the 'p' is -800. So, the sum of ASCII values of 'er' is maximum.

Input

alpha = "accebd"; chars[char_len] = {'b'}; Ascii[char_len] = {-500};


Output

'acce'

Explanation - Here, we can't include the 'b' in the substring as its ASCII value is negative, which decreases the sum of the ASCII values of string characters.

Input

alpha = "ababc"; chars[char_len] = {'a', 'b', 'c'}; Ascii[char_len] = {100, -100, 200};


Output

'ababc'


Explanation - We can take a string as a substring, as it has the maximum sum of ASCII values of characters.

Approach 1

In this approach, we will find all substrings of the given string. After that, we will sum all character's ASCII values. We will use the updated ASCII value for the particular character if we have given it. Otherwise, we will use the original ASCII value.

Also, we will keep track of the substring with the maximum sum of ASCII values.

Algorithm

Step 1 - Initialize the 'temp' and 'result' strings to store the temporary substring and resultant string, respectively.

Step 2 - If the string length is '1', return the string itself.

Step 3 - Initialize the 'maxVal' variable with a minimum value to store the maximum sum and 'sum' with 0 to store the sum of the substring's character's ASCII value. Also, define the map to store the updated frequency of characters.

Step 4 - Add all characters with updated ASCII values in the map.

Step 5 - Start traversing the string. Also, use another nested loop to get a substring from the p to q index.

Step 6 - Inside the nested loop, use the substr() method to get a substring starting from the p index and the length equal to q - p + 1. Also, store it into the 'temp' string, and reinitialize the 'sum' variable with 0.

Step 7 - Traverse the temp string to get a sum of its character's ASCII value. If the current character exists in the map, add its value to the sum. Otherwise, add the original ASCII value of the current character.

Step 8 - If the sum is greater than 'maxVal', update the 'maxVal' with the sum and the 'result' with the 'temp'.

Step 9 - Return the result value.

Example

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

string getMaximumSum(string alpha, char chars[], int Ascii[], int chars_len) {
string temp = "", result = "";
// For string of size 1
if (alpha.length() == 1)
return alpha;
long long maxVal = INT_MIN, sum = 0;
unordered_map<char, int> charMap;
// Storing new ASCII values to map
for (int p = 0; p < chars_len; p++) {
charMap[chars[p]] = Ascii[p];
}
// Get all substrings and sum its characters ASCII values
for (int p = 0; p < alpha.length(); p++) {
for (int q = p; q < alpha.length(); q++) {
// Get substring
temp = alpha.substr(p, q - p + 1);
sum = 0;
// Traverse substring to count the sum of ASCII values
for (int r = 0; r < temp.length(); r++) {
// If Character exists in the map
if (charMap.find(temp[r]) != charMap.end()) {
sum += charMap[temp[r]];
} else {
// If the character doesn't exist in the map
sum += temp[r];
}
}
// Update maximum value if the sum is greater
if (sum > maxVal) {
maxVal = sum;
result = temp;
}
}
}
return result;
}

int main() {
string alpha = "apper";
int char_len = 1;
char chars[char_len] = {'p'};
int Ascii[char_len] = {-800};
cout << "The maximum sum of ASCII values of any substring of the given string is " << getMaximumSum(alpha, chars, Ascii, char_len) << endl;
return 0;
}


Output

The maximum sum of ASCII values of any substring of the given string is er


Time complexity - O(N*N*N) to get all substrings.

Space complexity - O(N + M), to store the substring in the 'temp' string and store updated the ASCII value in the map.

Approach 2

Kadane's algorithm is used to find the maximum sum of the sub-array. Here, we can consider string as an array of characters and find the substring with maximum ASCII value sum.

In Kadane's algorithm, when the sum becomes negative, we reinitialize it with 0 and start with a new substring.

Algorithm

Step 1 - If the string length is 1, return the string.

Step 2 - Store the updated ASCII value in the map.

Step 3 - Start traversing the string, and append the current character to the 'temp' string.

Step 4 - If the current character exists in the map, add its value to the sum. Otherwise, add the original ASCII value of the character.

Step 5 - If the sum is negative, reinitialize the sum with 0, and clear the temp string.

Step 6 - If the sum is greater than 'maxVal', update the 'maxVal' with sum and 'result' with the 'temp' string.

Step 7 - Return the result string.

Example

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

string getMaximumSum(string alpha, char chars[], int Ascii[], int chars_len) {
string temp = "", result = "";
// For string of size 1
if (alpha.length() == 1)
return alpha;
long long maxVal = INT_MIN, sum = 0;
unordered_map<char, int> charMap;
// Storing new ASCII values to map
for (int p = 0; p < chars_len; p++) {
charMap[chars[p]] = Ascii[p];
}
// Iterate the string
for (int p = 0; p < alpha.length(); p++) {
// Store the string in temp.
temp += alpha[p];
// To get updated ASCII value
if (charMap.find(alpha[p]) == charMap.end()) {
sum += alpha[p];
} else {
sum += charMap[alpha[p]];
}
// For negative sum, we make it 0 and clear the string
if (sum < 0) {
sum = 0;
temp.clear();
}
// When the sum is greater than maxVal, update it.
if (sum > maxVal) {
maxVal = sum;
result = temp;
}
}
return result;
}
int main() {
string alpha = "accebd";
int char_len = 1;
char chars[char_len] = {'b'};
int Ascii[char_len] = {-500};
cout << "The maximum sum of ASCII values of any substring of the given string is " << getMaximumSum(alpha, chars, Ascii, char_len) << endl;
return 0;
}


Output

The maximum sum of ASCII values of any substring of the given string is acce


Time complexity - O(N) to traverse the string.

Space complexity - O(N) to store the substring.

Kadane's algorithm is very useful when we need to get the sub-array with maximum sum as we can get the answer in O(N) time. The naïve approach takes the O(N^2) time.

Updated on: 29-Aug-2023

37 Views