string definition problem - string

int main()
{
int score;
string scoreLetter;
char A, B, C, D, F;
cout<<"Enter the grade: ";
cin>> score;
void letterGrade (int score);
void gradeFinal (int score);
cout<<"The letter grade is "<< scoreLetter<<".";
}
void letterGrade (int score)
{
if (score >= 90) {
string scoreLetter = 'A'
} else if (score >= 80) {
scoreLetter = 'B'
} else if (score >= 70)
-When compiling, I am getting an error for the line scoreLetter = 'A', etc. What is wrong with this? Error states 'scoreLetter' undefined. Do I need to define scoreLetter in the function not the main?

Single quotes in C/C++ are used to define a character, not a String. Use double quotes instead. string scoreLetter = "A". Also you need to include the header if std::string is what you are trying to use: #include <string> and using std::string.

You'll want to return whatever value your function determines scoreLetter should be, and in main have a line like scoreLetter = letterGrade(score);. You can't set local variables from another function, unless the caller passed them to you by reference, which isn't happening here (and, in most cases, shouldn't be abused like that).
Aside from that, it looks like you're mixing up declarations and invocations. void letterGrade (int score); doesn't actually call letterGrade; it just says that there is a letterGrade function that takes an int, which we'll call "score". (The score there is just a name that's part of the prototype; it has no connection to your score variable.) So you'll likely find that if you managed to get your code to compile, it'd do something quite different than you're expecting it to do.
To call a function, you'd do something like letterGrade(score);, or if you followed my first suggestion, scoreLetter = letterGrade(score);.
string letterGrade (int score);
// void gradeFinal (int score); // not used in this snippet
int main()
{
int score;
string scoreLetter;
char A, B, C, D, F;
cout<<"Enter the grade: ";
cin>> score;
scoreLetter = letterGrade(score);
cout<<"The letter grade is "<< scoreLetter<<".";
}
string letterGrade (int score)
{
string grade;
if (score >= 90) {
grade = "A";
} else if (score >= 80) {
grade = "B";
} else if (score >= 70)
...
return grade;
}

Your code is cut off there but I think from what is available you are not calling the functions properly.
You should also try to be more specific about what language you are talking about, i.e. C in this case I believe.
A correct call to the functions would be:
letterGrade(score);
And yes, you need to define the string variable at global scope, so just move it out of main and above it.
string scoreLetter;
int main()
{
int score;
char A, B, C, D, F;
cout<<"Enter the grade: ";
cin>> score;
letterGrade (score);
gradeFinal (score);
cout<<"The letter grade is "<< scoreLetter<<".";
}
void letterGrade (int score)
{
if (score >= 90) {
scoreLetter = "A"
} else if (score >= 80) {
scoreLetter = "B"
} else if (score >= 70)

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

Minimum number of swaps to convert a string to palindrome

We are given a string and we have to find out the minimum number of swaps to convert it into a palindrome.
Ex-
Given string: ntiin
Palindrome: nitin
Minimum number of swaps: 1
If it is not possible to convert it into a palindrome, return -1.
I am unable to think of any approach except brute force. We can check on the first and last characters, if they are equal, we check for the smaller substring, and then apply brute force on it. But this will be of a very high complexity, and I feel this question can be solved in another way. Maybe dynamic programming. How to approach it?
First you could check if the string can be converted to a palindrome.
Just have an array of letters (26 chars if all letters are latin lowercase), and count the number of each letter in the input string.
If string length is even, all letters counts should be even.
If string length is odd, all letters counts should be even except one.
This first pass in O(n) will already treat all -1 cases.
If the string length is odd, start by moving the element with odd count to the middle.
Then you can apply following procedure:
Build a weighted graph with the following logic for an input string S of length N:
For every element from index 0 to N/2-1:
- If symmetric element S[N-index-1] is same continue
- If different, create edge between the 2 characters (alphabetic order), or increment weight of an existing one
The idea is that when a weight is even you can do a 'good swap' by forming two pairs in one swap.
When weight is odd, you cannot place two pairs in one swap, your swaps need to form a cycle
1. For instance "a b a b"
One edge between a,b of weight 2:
a - b (2)
Return 1
2. For instance: "a b c b a c"
a - c (1)
b - a (1)
c - b (1)
See the cycle: a - b, b - c, c - a
After a swap of a,c you get:
a - a (1)
b - c (1)
c - b (1)
Which is after ignoring first one and merge 2 & 3:
c - b (2)
Which is even, you get to the result in one swap
Return 2
3. For instance: "a b c a b c"
a - c (2)
One swap and you are good
So basically after your graph is generated, add to the result the weight/2 (integer division e.g. 7/3 = 3) of each edge
Plus find the cycles and add to the result length-1 of each cycle
there is the same question as asked!
https://www.codechef.com/problems/ENCD12
I got ac for this solution
https://www.ideone.com/8wF9DT
//minimum adjacent swaps to make a string to its palindrome
#include<bits/stdc++.h>
using namespace std;
bool check(string s)
{
int n=s.length();
map<char,int> m;
for(auto i:s)
{
m[i]++;
}
int cnt=0;
for(auto i=m.begin();i!=m.end();i++)
{
if(i->second%2)
{
cnt++;
}
}
if(n%2&&cnt==1){return true;}
if(!(n%2)&&cnt==0){return true;}
return false;
}
int main()
{
string a;
while(cin>>a)
{
if(a[0]=='0')
{
break;
}
string s;s=a;
int n=s.length();
//first check if
int cnt=0;
bool ini=false;
if(n%2){ini=true;}
if(check(s))
{
for(int i=0;i<n/2;i++)
{
bool fl=false;
int j=0;
for(j=n-1-i;j>i;j--)
{
if(s[j]==s[i])
{
fl=true;
for(int k=j;k<n-1-i;k++)
{
swap(s[k],s[k+1]);
cnt++;
// cout<<cnt<<endl<<flush;
}
// cout<<" "<<i<<" "<<cnt<<endl<<flush;
break;
}
}
if(!fl&&ini)
{
for(int k=i;k<n/2;k++)
{
swap(s[k],s[k+1]);
cnt++;
}
// cout<<cnt<<" "<<i<<" "<<endl<<flush;
}
}
cout<<cnt<<endl;
}
else{
cout<<"Impossible"<<endl;
}
}
}
Hope it helps!
Technique behind my code is Greedy
first check if palindrome string can exist for the the string and if it can
there would be two cases one is when the string length would be odd then only count of one char has be odd
and if even then no count should be odd
then
from index 0 to n/2-1 do the following
fix this character and search for this char from n-i-1 to i+1
if found then swap from that position (lets say j) to its new position n-i-1
if the string length is odd then every time you encounter a char with no other occurence shift it to n/2th position..
My solution revolves around the palindrome property that first element and last element should match and if their adjacent elements also do not match then its not a palindrome. Keep comparing and swapping till both reach the same element or adjacent elements.
Written solution in java as below:
public static void main(String args[]){
String input = "natinat";
char[] arr = input.toCharArray();
int swap = 0;
int i = 0;
int j = arr.length-1;
char temp;
while(i<j){
if(arr[i] != arr[j]){
if(arr[i+1] == arr[j]){
//swap i and i+1 and increment i, decrement j, swap++
temp = arr[i];
arr[i] = arr[i+1];
arr[i+1] = temp;
i++;j--;
swap++;
} else if(arr[i] == arr[j-1]){
//swap j and j-1 and increment i, decrement j, swap++
temp = arr[j];
arr[j] = arr[j-1];
arr[j-1] = temp;
i++;j--;
swap++;
} else if(arr[i+1] == arr[j-1] && i+1 != j-1){
//swap i and i+1, swap j and j-1 and increment i, decrement j, swap+2
temp = arr[j];
arr[j] = arr[j-1];
arr[j-1] = temp;
temp = arr[i];
arr[i] = arr[i+1];
arr[i+1] = temp;
i++;j--;
swap = swap+2;
}else{
swap = -1;break;
}
} else{
//increment i, decrement j
i++;j--;
}
}
System.out.println("No Of Swaps: "+swap);
}
My solution in java for any type of string i.e Binary String, Numbers
public int countSwapInPalindrome(String s){
int length = s.length();
if (length == 0 || length == 1) return -1;
char[] str = s.toCharArray();
int start = 0, end = length - 1;
int count = 0;
while (start < end) {
if (str[start] != str[end]){
boolean isSwapped = false;
for (int i = start + 1; i < end; i++){
if (str[start] == str[i]){
char temp = str[i];
str[i] = str[end];
str[end] = temp;
count++;
isSwapped = true;
break;
}else if (str[end] == str[i]){
char temp = str[i];
str[i] = str[start];
str[start] = temp;
count++;
isSwapped = true;
break;
}
}
if (!isSwapped) return -1;
}
start++;
end--;
}
return (s.equals(String.valueOf(str))) ? -1 : count;
}
I hope it helps
string s;
cin>>s;
int n = s.size(),odd=0;
vi cnt(26,0);
unordered_map<int,set<int>>mp;
for(int i=0;i<n;i++){
cnt[s[i]-'a']++;
mp[s[i]-'a'].insert(i);
}
for(int i=0;i<26;i++){
if(cnt[i]&1) odd++;
}
int ans=0;
if((n&1 && odd == 1)|| ((n&1) == 0 && odd == 0)){
int left=0,right=n-1;
while(left < right){
if(s[left] == s[right]){
cnt[left]--;
cnt[right]--;
mp[s[left]-'a'].erase(left);
mp[s[right]-'a'].erase(right);
left++;
right--;
}else{
if(cnt[left]&1 == 0){
ans++;
int index = *mp[s[left]-'a'].rbegin();
mp[s[left]-'a'].erase(index);
mp[s[right]-'a'].erase(right);
mp[s[right]-'a'].insert(index);
swap(s[right],s[index]);
cnt[left]-=2;
}else{
ans++;
int index = *mp[s[right]-'a'].begin();
mp[s[right]-'a'].erase(index);
mp[s[left]-'a'].erase(left);
mp[s[left]-'a'].insert(index);
swap(s[left],s[index]);
cnt[right]-=2;
}
left++;
right--;
}
}
}else{
// cout<<odd<<" ";
cout<<"-1\n";
return;
}
cout<<ans<<"\n";

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 !

Vigenere.c CS50 Floating Point Exception (Core Dumped)

I am working on the Vigenere exercise from Harvard's CS50 (in case you noticed I'm using string and not str).
My program gives me a Floating Point Exception error when I use "a" in the keyword.
It actually gives me that error
when I use "a" by itself, and
when I use "a" within a bigger word it just gives me wrong output.
For any other kind of keyword, the program works perfectly fine.
I've run a million tests. Why is it doing this? I can't see where I'm dividing or % by 0. The length of the keyword is always at least 1. It is probably going to be some super simple mistake, but I've been at this for about 10 hours and I can barely remember my name.
#include <stdio.h>
#include <cs50.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
int main (int argc, string argv[])
{
//Error message if argc is not 2 and argv[1] is not alphabetical
if (argc != 2)
{
printf("Insert './vigenere' followed by an all alphabetical key\n");
return 1;
}
else if (argv[1])
{
for (int i = 0, n = strlen(argv[1]); i < n; i++)
{
if (isalpha((argv[1])[i]) == false)
{
printf("Insert './vigenere' followed by an all alphabetical key\n");
return 1;
}
}
//Store keyword in variable
string keyword = argv[1];
//Convert all capital chars in keyword to lowercase values, then converts them to alphabetical corresponding number
for (int i = 0, n = strlen(keyword); i < n; i++)
{
if (isupper(keyword[i])) {
keyword[i] += 32;
}
keyword[i] -= 97;
}
//Ask for users message
string message = GetString();
int counter = 0;
int keywordLength = strlen(keyword);
//Iterate through each of the message's chars
for (int i = 0, n = strlen(message); i < n; i++)
{
//Check if ith char is a letter
if (isalpha(message[i])) {
int index = counter % keywordLength;
if (isupper(message[i])) {
char letter = (((message[i] - 65) + (keyword[index])) % 26) + 65;
printf("%c", letter);
counter++;
} else if (islower(message[i])) {
char letter = (((message[i] - 97) + (keyword[index])) % 26) + 97;
printf("%c", letter);
counter++;
}
} else {
//Prints non alphabetic characters
printf("%c", message[i]);
}
}
printf("\n");
return 0;
}
}
This behavior is caused by the line keyword[i] -= 97;, there you make every 'a' in the key stream a zero. Later you use strlen() on the transformed key. So when the key starts with an 'a', keywordLength therefor is set to zero, and the modulo keywordLength operation get into a division by zero. You can fix this by calculating the keyword length before the key transformation.

Sub sequence occurrence in a string

Given 2 strings like bangalore and blr, return whether one appears as a subsequence of the other. The above case returns true whereas bangalore and brl returns false.
Greedy strategy should work for this problem.
Find the first letter of the suspected substring (blr) in the big string (*b*angalore)
Find the second letter starting at the index of the first letter plus one (anga*l*ore)
Find the third letter starting at the index of the second letter plus one (o*r*e)
Continue until you can no longer find the next letter of blr in the string (no match), or you run out of letters in the subsequence (you have a match).
Here is a sample code in C++:
#include <iostream>
#include <string>
using namespace std;
int main() {
string txt = "quick brown fox jumps over the lazy dog";
string s = "brownfoxzdog";
int pos = -1;
bool ok = true;
for (int i = 0 ; ok && i != s.size() ; i++) {
ok = (pos = txt.find(s[i], pos+1)) != string::npos;
}
cerr << (ok ? "Found" : "Not found") << endl;
return 0;
}
// Solution 1
public static boolean isSubSequence(String str1, String str2) {
int i = 0;
int j = 0;
while (i < str1.length() && j < str2.length()) {
if (str1.charAt(i) == str2.charAt(j)) {
i++;
j++;
} else {
i++;
}
}
return j == str2.length();
}
// Solution 2 using String indexOf method
public static boolean isSubSequenceUsingIndexOf(String mainStr, String subStr) {
int i = 0;
int index = 0;
while(i<subStr.length()) {
char c = subStr.charAt(i);
if((index = mainStr.indexOf(c, index)) == -1) {
return false;
}
i++;
}
return true;
}
O(N) solution, where N is the length of the substring.
bool subsequence( string s1, string s2 ){
int n1 = s1.length();
int n2 = s2.length();
if( n1 > n2 ){
return false;
}
int i = 0;
int j = 0;
while( i < n1 && j < n2 ){
if( s1[i] == s2[j] ){
i++;
}
j++;
}
return i == n1;
}
Find the length of the longest common subsequence. If it is equal to the length of small string, return true

Resources