Get Palindrome of a String with replacement - string

Elina has a string S, consisting of lowercase English alphabetic letters(ie. a-z). She can replace any character in the string with any other character, and she can perform this replacement any number of times. she wants to create a palindromic string, p , from s such that string p contains the sub string linkedin . it is guaranteed that Elina can create palindromic string p from S.
find the minimum number of operation required to create palindromic string p from S.
Sample test case are:
First test case: S="linkedininininin"
explanation :
linkedin (i) (n) (i) (n) (i) ni (n)
(n) (i) (d) (e) (k) (l)
p = "linkedinnideknil"
output is 6
Second test case: S="fulrokxeuolnzxltiiniabudyyozvulqbydmaldbxaddmkobhlplkaplgndnksqidkaenxdacqtsskdkdddls"
output is 46
here i was unable to get second test case output, how it's getting output 46.
Third Test Case:
S="linkaeiouideknil"
P="linkedinnideknil"
Output = 4

Here is code with time complexity of O(n).
import java.io.*;
import java.util.*;
class TestClass {
public static void main(String args[] ) throws Exception {
Scanner sc = new Scanner(System.in);
String input = sc.next();
String ln = "linkedin";
String rln= "nideknil";
int limit, limit2;
int len = input.length();
if(len%2==0){
limit=len/2-7;
limit2=len/2-1;
}else{
limit=(len+1)/2-7;
limit2= (len-1)/2 -1;
}
int max=0,index=0;
boolean rev=false;
for(int i = 0; i<=len-8;i++){
int count1=0, count2=0;
if(i==limit){
if(len%2==0){
i=len/2;
}else{
i=(len-1)/2;
}
}
String temp=input.substring(i,i+8);
for(int j=0;j<8;j++){
if(ln.charAt(j)==temp.charAt(j)){
count1++;
}
if(rln.charAt(j)==temp.charAt(j)){
count2++;
}
int temp2 = count1 > count2 ? count1 : count2;
if(temp2>max){
index=i;
max=temp2;
if(temp2==count2){
rev=true;
}
else
rev=false;
}
}
}
int replace=0;
char in[]= input.toCharArray();
int i,j;
for(i= index,j=0;i<index+8;j++,i++){
if(rev){
if(rln.charAt(j)!=in[i]){
replace++;
in[i]=rln.charAt(j);
}
} else{
if(ln.charAt(j)!=in[i]){
replace++;
in[i]=ln.charAt(j);
}
}
}
for(j=0,i = len-1; j<=limit2 ;i--,j++){
if(in[i]!=in[j]){
replace++;
}
}
System.out.println(replace);
}
}

Related

How to remove K characters from a string such that there is a minimum of each character

I want to remove K characters from a string such that the occurrence of each character is at a minimum.
For example:
String: abcdefghijkllllll
K: 5
Answer: 12 (abcdeghijkl)
String: ababac
K: 4
Answer: 3 (aac)
String: aaaab
K: 4
Answer: 1(b)
I want to remove 5 characters. Those characters would be 5 l's
What I've done so far is count the occurence of each character using a map
But I'm stuck as to what to do next.
#include <bits/stdc++.h>
using namespace std;
string s;
int l, k;
map<char, int> m;
int main() {
getline(cin, s);
scanf("%d %d", &l, &k);
for(int i=0; i<s.length(); i++) {
m[s[i]]++;
}
for(auto &x : m) {
cout << x.second << "\n";
}
return 0;
}
The expected result is the minimum length of a string after removing the characters of any given string (can be sorted or unsorted).
You can remove any character in the String
Update:
#include <bits/stdc++.h>
using namespace std;
string s;
int l, k;
map<char, int> m;
int main() {
getline(cin, s);
cin >> l >> k;
for(int i = 0; i < s.length(); i++) {
m[s[i]]++;
}
for(auto it = m.end(); it != m.begin(); it--) {
// cout << it->second << "\n";
}
vector<pair<int, int>> pairs;
for (auto itr = m.begin(); itr != m.end(); itr++) {
pairs.push_back(*itr);
}
sort(pairs.begin(), pairs.end(), [=](pair<int, int>& a, pair<int, int>& b) { return a.second < b.second; } );
for(auto it = m.end(); it != m.begin(); it--) {
if(it->second - k >= 1) {
it->second-=k;
k -= it->second;
}
}
int sum = 0;
for(auto it = m.end(); it != m.begin(); it--) {
sum += it->second;
// cout << it->second << "\n";
}
cout << sum << "\n";
return 0;
}
The current problem with this is that it doesn't read all the characters and map them correctly to the map.
I'm uncertain from your description and test cases what you're looking for. Your answer is returning the number of characters remaining in the string, and your updated function returns the sum variable. If that's the case why not just return the length of the string minus k?
Your second test case is:
String: ababac
K: 4
Answer: 3 (aac)
Removing 4 characters from "ababac" (length 6) would give it a length of 2, not 3. How does this work?
Can the characters be removed in any order? For the third test case you have:
String: aaaab
K: 4
Answer: 1(b)
Given the description: I want to remove K characters from a string such that the occurrence of each character is at a minimum. Removing 3 characters gives the result "ab". Removing the 4th could result in either "a" or "b". What do you do in this case?
There's a lot of ambiguity in this question, and the test cases are a bit confusing. For example, given "aabbccdddd" k=3, what would be the accepted answer? "abcdddd" or "aabbccd"? "abcdddd" would increase the number of characters that are at a minimum whereas "aabbccd" would reduce the number of the most frequently occurring character.
I've put together an answer using a max priority queue / max-heap (in Java) with the later example from above. This assumes that all your input is good.
import java.util.*;
public class SO {
//Helper class to put in the priority queue.
class CharInt {
char c;
int count;
public CharInt(char c) {
this.c = c;
this.count = 1;
}
void increment() {
this.count++;
}
void decrement() {
this.count--;
}
}
public int minChar(String s, int k) {
Map<Character, CharInt> map = new HashMap<Character, CharInt>();
for (Character c : s.toCharArray()) {
if (map.get(c) == null) {
map.put(c, new CharInt(c));
}else {
map.get(c).increment();
}
}
//Makes a Max-Heap from a PriorityQueue object. The comparator makes sure the top of the PriorityQueue is the character with the highest count.
PriorityQueue<CharInt> maxHeap = new PriorityQueue<CharInt>(new Comparator<CharInt>() {
#Override
public int compare(CharInt o1, CharInt o2) {
return - Integer.compare(o1.count, o2.count);
}
});
//Add all values to the heap.
for (CharInt c : map.values()) {
maxHeap.add(c);
}
//Take the top value off, decrement its count, add it back to the heap. Do this k times.
while (k-- > 0) {
CharInt c = maxHeap.poll();
c.decrement();
maxHeap.add(c);
}
StringBuilder builder = new StringBuilder(); // Used to make output string. Can be left out.
int sum = 0;
//Remove every element from the heap and get its count value.
while(!maxHeap.isEmpty()) {
CharInt c = maxHeap.poll();
for (int i = 0; i < c.count; i++) {
sum += c.count;
builder.append(c.c); // Used to make output string. Can be left out.
}
}
char[] chars = builder.toString().toCharArray(); // Used to make output string. Can be left out.
Arrays.sort(chars); // Used to make output string. Can be left out.
System.out.println(chars); // Used to make output string. Can be left out.
return sum;
}
public static void main(String...bannaa) {
int s = new SO().minChar("abcdefghijkllllll", 5);
int s2 = new SO().minChar("ababac", 4);
int s3 = new SO().minChar("aaaab", 4);
int s4 = new SO().minChar("abbbccc", 4);
System.out.println(s + " " + s2 + " " + s3 + " " + s4);
}
}
Output:
abcdefghijkl
ac
a
abc
12 2 1 3

java program to return the characters which occurs more than 3 times in a string using only string functions

java program to return the characters which occurs more than 3 times in a string using only string functions
use only charAt and length functions to get solution
import java.util.*;
public class StringExample {
public static void main(String args[]) {
String str = "sofiiiffjjjh";
Map < Character, Integer > charFreq = new HashMap < Character, Integer > ();
if (str != null) {
for (Character c: str.toCharArray()) {
Integer count = charFreq.get(c);
int newCount = (count == null ? 1 : count + 1);
charFreq.put(c, newCount);
if (newCount >= 3) {
System.out.println(c);
}
}
}
}
}
This solution first sorts the character in the input string. It loops through the characters in the string, comparing the current character with the previous character
1. If they are the same, it increments the count
2. If not, it checks the number of times previousChar has occurred and prints it if it is more than 3 and continues.
char [] strAsArray = s.toCharArray();
Arrays.sort(strAsArray);
String sorted = new String(strAsArray);
System.out.println(sorted);
if (sorted.length() > 0) {
char previousChar = s.charAt(0);
int count = 1;
for (int i = 1; i < sorted.length(); i++) {
if (sorted.charAt(i) == previousChar) {
count++;
} else { // encountered new character
if (count >= 3) {
//if the previous character has appeared more than 3 times
System.out.println(sorted.charAt(i - 1));
}
count = 1;
previousChar = sorted.charAt(i);
}
}
//To handle case where the String has only one character any number of times
if (count >= 3) {
System.out.println(sorted.charAt(sorted.length() - 1));
}
}

Reduce a string when it has a pair

Shil has a string S , consisting of N lowercase English letters. In one operation, he can delete any pair of adjacent letters with same value. For example, string "aabcc" would become either "aab" or "bcc" after operation.
Shil wants to reduce S as much as possible. To do this, he will repeat the above operation as many times as it can be performed. Help Shil out by finding and printing 's non-reducible form!
If the final string is empty, print Empty String; otherwise, print the final non-reducible string.
Sample Input 0
aaabccddd
Sample Output 0
abd
Sample Input 1
baab
Sample Output 1
Empty String
Sample Input 2
aa
Sample Output 2
Empty String
Explanation
Sample Case 0: Shil can perform the following sequence of operations to get the final string:
Thus, we print .
Sample Case 1: Shil can perform the following sequence of operations to get the final string: aaabccddd -> abccddd
abccddd -> abddd
abddd -> abd
Thus we print abd
Sample case 1: baab -> bb
bb -> Empty String.
in my code in the while loop when i assign s[i] to str[i].the value of s[i] is not getting assigned to str[i].the str[i] has a garbage value.
my code :
int main() {
/* Enter your code here. Read input from STDIN. Print output to STDOUT */
string s;
cin>>s;
int len = s.length();
int len1 = 0;
string str;
for(int i = 0;i < len-1;i++){
if(s[i]!= '*'){
for(int j=i+1;j < len;j++){
if(s[j] != '*'){
if(s[i] == s[j]){
s[i] = s[j] = '*';
}
}
}
}
}
int i = 0;
while(i<len){
if(s[i] != '*'){
str[len1] = s[i];
len1++;
}
i++;
}
if(len1 != 0){
cout<<str;
}
else{
cout<<"Empty String";
}
return 0;
}
#include <iostream>
using namespace std;
int main(){
string s,tempS;
bool condition = false;
cin >> s;
tempS = s;
while(condition==false){
for(int i=1; i<s.size(); i++){
if(s[i]==s[i-1]){
s.erase(s.begin()+i-1, s.begin()+i+1);
}
}
if(tempS == s){
condition = true;
} else{
tempS = s;
}
}
if(s.size()==0){
cout << "Empty String" ;
} else{
cout << s;
}
return 0;
}
the first while loop keeps on modifying the string until and unless it becomes equal to temp (which is equal to the string pre-modification)
It is comparing the adjacent elements if they are equal or not and then deleting them both.
As soon as string becomes equal to temp after modifications, string has reached it's most reduced state !

how to get partial string seperated by commas?

I have a string:
string mystring="part1, part2, part3, part4, part5";
How can I just return the first 3 elements without splitting them up first?
so like this:
string newstring="part1, part2, part3";
You could get the first three using:
RegEx r = new RegEx(#"(\S+, \S+, \S+), \S+");
I'm sure there is a better way to write the regex, but I think that would do it for basic inputs.
Try to find Index of 3rd Comma, and then get the substring.
Example
void Main()
{
string mystring="part1, part2, part3, part4, part5";
int thirdCommaIndex = IndexOf(mystring, ',', 3);
var substring = mystring.Substring(0,thirdCommaIndex-1);
Console.WriteLine(substring);
}
int IndexOf(string s, char c, int n)
{
int index = 0;
int count = 0;
foreach(char ch in s)
{
index++;
if (ch == c)
count++;
if (count == n )
break;
}
if (count == 0) index = -1;
return index;
}
This will parse the string trying to find the third comma and throwing it and everything after it away.
string mystring = "part1, part2, part3, part4, part5";
UInt16 CommasFound = 0;
UInt16 Location = 0;
for (Location = 0; (CommasFound < 3) &&
(Location < mystring.Count()); Location++)
if (mystring[Location].Equals(','))
CommasFound++;
if (CommasFound == 3)
{
string newstring = mystring.Substring(0, Location-1);
}
else { // Handle the case where there isn't a third item
}

Square Subsequence

A string is called a square string if it can be obtained by concatenating two copies of the same string. For example, "abab", "aa" are square strings, while "aaa", "abba" are not. Given a string, how many subsequences of the string are square strings? A subsequence of a string can be obtained by deleting zero or more characters from it, and maintaining the relative order of the remaining characters.The subsequence need not be unique.
eg string 'aaa' will have 3 square subsequences
Observation 1: The length of a square string is always even.
Observation 2: Every square subsequence of length 2n (n>1) is a combination of two shorter subsequences: one of length 2(n-1) and one of length 2.
First, find the subsequences of length two, i.e. the characters that occur twice or more in the string. We'll call these pairs. For each subsequence of length 2 (1 pair), remember the position of the first and last character in the sequence.
Now, suppose we have all subsequences of length 2(n-1), and we know for each where in the string the first and second part begins and ends. We can find sequences of length 2n by using observation 2:
Go through all the subsequences of length 2(n-1), and find all pairs where the first item in the pair lies between the last position of the first part and the first position of the second part, and the second item lies after the last position of the second part. Every time such a pair is found, combine it with the current subsequence of length 2(n-2) into a new subsequence of length 2n.
Repeat the last step until no more new square subsequences are found.
Psuedocode:
total_square_substrings <- 0
# Find every substring
for i in 1:length_of_string {
# Odd strings are not square, continue
if((length_of_string-i) % 2 == 1)
continue;
for j in 1:length_of_string {
# Remove i characters from the string, starting at character j
substring <- substr(string,0,j) + substr(string,j+1,length_of_string);
# Test all ways of splitting the substring into even, whole parts (e.g. if string is of length 15, this splits by 3 and 5)
SubstringTest: for(k in 2:(length_of_substring/2))
{
if(length_of_substring % k > 0)
continue;
first_partition <- substring[1:partition_size];
# Test every partition against the first for equality, if all pass, we have a square substring
for(m in 2:k)
{
if(first_partition != substring[(k-1)*partition_size:k*partition_size])
continue SubstringTest;
}
# We have a square substring, move on to next substring
total_square_substrings++;
break SubstringTest;
}
}
}
Here's a solution using LINQ:
IEnumerable<string> input = new[] {"a","a","a"};
// The next line assumes the existence of a "PowerSet" method for IEnumerable<T>.
// I'll provide my implementation of the method later.
IEnumerable<IEnumerable<string>> powerSet = input.PowerSet();
// Once you have the power set of all subsequences, select only those that are "square".
IEnumerable<IEnumerable<string>> squares = powerSet.Where(x => x.Take(x.Count()/2).SequenceEqual(x.Skip(x.Count()/2)));
Console.WriteLine(squares);
And here is my PowerSet extension method, along with a "Choose" extension method that is required by PowerSet:
public static class CombinatorialExtensionMethods
{
public static IEnumerable<IEnumerable<T>> Choose<T>(this IEnumerable<T> seq, int k)
{
// Use "Select With Index" to create IEnumerable<anonymous type containing sequence values with indexes>
var indexedSeq = seq.Select((Value, Index) => new {Value, Index});
// Create k copies of the sequence to join
var sequences = Enumerable.Repeat(indexedSeq,k);
// Create IEnumerable<TypeOf(indexedSeq)> containing one empty sequence
/// To create an empty sequence of the same anonymous type as indexedSeq, allow the compiler to infer the type from a query expression
var emptySequence =
from item in indexedSeq
where false
select item;
var emptyProduct = Enumerable.Repeat(emptySequence,1);
// Select "Choose" permutations, using Index to order the items
var indexChoose = sequences.Aggregate(
emptyProduct,
(accumulator, sequence) =>
from accseq in accumulator
from item in sequence
where accseq.All(accitem => accitem.Index < item.Index)
select accseq.Concat(new[] { item }));
// Select just the Value from each permutation
IEnumerable<IEnumerable<T>> result =
from item in indexChoose
select item.Select((x) => x.Value);
return result;
}
public static IEnumerable<IEnumerable<T>> PowerSet<T>(this IEnumerable<T> seq)
{
IEnumerable<IEnumerable<T>> result = new[] { Enumerable.Empty<T>() };
for (int i=1; i<=seq.Count(); i++)
{
result = result.Concat(seq.Choose<T>(i));
}
return result;
}
}
I initially derive all possible sub-sequences and then i will check if the derived sub-sequence is a square sub-sequence or not
import java.io.*;
import java.util.*;
public class Subsequence {
static int count;
public static void print(String prefix, String remaining, int k) {
if (k == 0) {
//System.out.println(prefix);
if(prefix.length() %2 == 0 && check(prefix) != 0 && prefix.length() != 0)
{
count++;
//System.out.println(prefix);
}
return;
}
if (remaining.length() == 0)
return;
print(prefix + remaining.charAt(0), remaining.substring(1), k-1);
print(prefix, remaining.substring(1), k);
}
public static void main(String[] args)
{
//String s = "aaa";
Scanner sc = new Scanner(System.in);
int t=Integer.parseInt(sc.nextLine());
while((t--)>0)
{
count = 0;
String s = sc.nextLine();
for(int i=0;i<=s.length();i++)
{
print("",s,i);
}
System.out.println(count);
}
}
public static int check(String s)
{
int i=0,j=(s.length())/2;
for(;i<(s.length())/2 && j < (s.length());i++,j++)
{
if(s.charAt(i)==s.charAt(j))
{
continue;
}
else
return 0;
}
return 1;
}
}
import java.io.*;
import java.util.*;
public class Solution {
/*
Sample Input:
3
aaa
abab
baaba
Sample Output:
3
3
6
*/
public static void main(String[] args) {
//Creating an object of SquareString class
SquareString squareStringObject=new SquareString();
Scanner in = new Scanner(System.in);
//Number of Test Cases
int T = in.nextInt();
in.nextLine();
String[] inputString=new String[T];
for(int i=0;i<T;i++){
// Taking input and storing in String Array
inputString[i]=in.nextLine();
}
for(int i=0;i<T;i++){
//Calculating and printing the number of Square Strings
squareStringObject.numberOfSquareStrings(inputString[i]);
}
}
}
class SquareString{
//The counter maintained for keeping a count of Square Strings
private int squareStringCounter;
//Default Constructor initialising the counter as 0
public SquareString(){
squareStringCounter=0;
}
//Function calculates and prints the number of square strings
public void numberOfSquareStrings(String inputString){
squareStringCounter=0;
//Initialising the string part1 as a single character iterated over the length
for(int iterStr1=0;iterStr1<inputString.length()-1;iterStr1++){
String str1=""+inputString.charAt(iterStr1);
String str2=inputString.substring(iterStr1+1);
//Calling a recursive method to generate substring
generateSubstringAndCountSquareStrings(str1,str2);
}
System.out.println(squareStringCounter);
}
//Recursive method to generate sub strings
private void generateSubstringAndCountSquareStrings(String str1,String str2){
for(int iterStr2=0;iterStr2<str2.length();iterStr2++){
String newStr1=str1+str2.charAt(iterStr2);
if(isSquareString(newStr1)){
squareStringCounter++;
}
String newStr2=str2.substring(iterStr2+1);
generateSubstringAndCountSquareStrings(newStr1,newStr2);
}
}
private boolean isSquareString(String str){
if(str.length()%2!=0)
return false;
String strPart1=str.substring(0,str.length()/2);
String strPart2=str.substring(str.length()/2);
return strPart1.equals(strPart2);
}
}

Resources