Largest Palindrome 3 digits C++ - c++

I cannot figure out why this code isn't working. It doesn't even seem to be going through my for loops and nested loops. I'm very new to programing. I have been trying to answer Euler questions for practice. Sorry if my code is awful.
#include <iostream>
#include <string>
using namespace std;
bool isPalindrome(int x) {
string str = to_string(x);
for(string::reverse_iterator rit=str.rbegin(); rit!=str.rend(); ++rit) {
string pal = to_string(*rit);
if(pal == str) {
return true;
}else {
return false;
}
}
}
int main() {
int max[] = {0, 0};
for(int i=999; i>99; i--) {
for( int j =999; j>99; j--) {
int pal = i*j;
if(isPalindrome(pal) == true) {
max[1] = pal;
if(max[1] > max[0]){
max[0] = pal;
}
}
}
}
cout << max[0];
}

I think you need to return true in isPalindrome after comparing complete string. ie return true; should be outside for loop
And for checking largest 3 digit palindrome why are you passing int pal = i*j; ie for first iteration 999*999. Check this
bool isPalindrome(int x) {
string str = to_string(x);
string pal = str;
std::reverse(pal.begin(),pal.end());
if(pal == str) {
return true;
}else {
return false;
}
}

Related

Checking if a word is a palindrome by reversing a stack without using any prewritten functions

#include <iostream>
#include <string>
using namespace std;
#define Max 100000
class Stack {
private:
int top =-1;
char letters[Max];
public:
void setTop(int t) {
top = t;
}
int getTop() {
return top;
}
bool isEmptyStack() {
if (top == -1) {
return true;
}
else{ return false;
}
}
char push(char x,int s) {
if (top != s - 1){
top++;
x = letters[top];
return x;
}
}
char pop() {
if ((isEmptyStack())==false){
cout << "the deleted value is: " << l[top]<<endl;
top--;
return l[top];
}
}
};
void reverse(char letters[], char temp[], int size, Stack stack) {
int i=0;
for (i = 0; i < size; i++) {
stack.push(letters[i],size);
}
i = 0;
cout << temp<<endl;
while (stack.isEmptyStack() == false)
{
letters[-1] = stack.getTop();
stack.pop();
stack.push(letters[i],size);
i++;
}
/* for (int i = 0; i < size; i++) {
cout << temp[i];
}*/
}
int myStringLength(const char* letter)
{
for (int i = 0, c = 0; letter[i] != '\0'; i++, c++) {
if (letter[i] != '\0')
for (; letter[i] != '\0'; i++, c++)
if (letter[i] == '\0') break;
return c;
}
}
int main()
//initializes the main function
{
Stack stack;
string w;
std::cout << "Enter a Word: ";
getline(cin,w);
char* letters = &w[0];
// sets the character text array to set the number of characters equal to the size of the string
//calls the processData function
std::cout << letters<<endl;
int size = myStringLength(letters);
reverse(letters, letters, size, stack);
return 0;//returns the function at 0.
}
I set out to create a program that will check if a word is a palindrome(meaning it is spelled the same normally and if the word is reversed.) I am not yet at that point that is just the final objective. In my code, I have created a stack class because I wanted to feel the satisfaction of getting the same result using my own code. My problem is the stack is not reversing it is returning some weird characters that I don't have the keys on my keyboard to replicate.
The desired outcome should be word's reversed characters.
if the word is food the function should be returning doof. I have already compared the reversed stack to the original and printed the final statement. I fixed the char letters[];
If you're open to using a simple function instead of a Stack then you could use the following program since it is much more simple than your Stack version and hence less-error prone.
#include <iostream>
#include <string>
bool checkIfPalindroom(const std::string &str)
{
for(int i=0;i<(str.size()/2);i++)
{
if (str[i] != str[str.size() - i - 1])
{
return false;//if this if is satisfied even once, return false
}
}
return true;//if the control flow reaches here this will mean that no if was satisfied and hence return true
}
int main()
{
std::string myString = "Somearbitrarystring";
if(checkIfPalindroom(myString))//call the function
{
std::cout<<"The given string: "<<myString <<" is a palindrome"<<std::endl;
}
else
{
std::cout<<"The given string: "<<myString<<" is not a palindrome"<<std::endl;
}
return 0;
}

Dynamic programming - canSum memoization in C++

The objective is to return true if the sum can be made by adding up elements from a given vector. The vector elements maybe used and reused in any order.
Example:
sum = 7, list = [4,5]
return false because you can't use these list elements to make 7
sum = 9 or 5 or 20 or 8, list = [4,5]
return true because 9 = 4+5, 5 is in list already, 20 = 5+5+5+5, 8 = 4 + 4
I do not know why canSum is not returning anything. When targetSum reaches 0, canSum should return true, and then in memo we emplace (remainder, true). However, the program is not returning anything. Why is that?
#include <iostream>
#include <vector>
#include <map>
using namespace std;
bool canSum(int targetSum, vector<int> &vec, map<int, bool> &memo) {
int remainder;
if (memo[targetSum] == true)
return true;
else if (targetSum == 0)
return true;
else if (targetSum < 0)
return false;
else
for (auto i : vec) {
remainder = targetSum - i;
if (canSum(remainder, vec, memo)) {
memo.emplace(remainder, true);
return true;
}
}
memo.emplace(remainder, false);
return false;
}
int main() {
vector<int> vector1{7, 14};
int sum = 300;
map<int, bool> memo;
if (canSum(sum, vector1, memo))
cout << "true";
else
cout << "false";
}
The problem in your code is the way you handle the storing of sates in your memo table. You store only when the result is desired in the for loop and same problem is while returning using the memo table. So, the states which result in false are not stored in your memo until the complete recursive call ends and you are out of the loop. So, your recursion keeps on calculating the same states again and again. Your logic is correct but dynamic programming integration in recursive code is not proper. Your code will give an output, you just need to wait for a long time even for a small input. Below I have explained the above mentioned problems in detail.
You return from memo only if the result is true i.e. the if condition:
...
if(memo[remainder] == true)
return true;
...
is the problem. We use dynamic programming to save the result of a state that has been calculated so that if we come across the same problem in future, we don't have to recalculate it and we can return its result from saved memo table to avoid going into recursion again. We return the result from memo table irrespective of the result. But here you are returning only if the result was true. You should instead use this:
...
if (memo.find(targetSum)!=memo.end())
return memo[targetSum];
...
This is also the problem while you are storing the results in the memo table in the for loop. The if condition in the for loop:
for (auto i : vec) {
remainder = targetSum - i;
if (canSum(remainder, vec, memo)) {
memo.emplace(remainder, true);
return true;
}
}
is the problem. We store the result in the memo table irrespective of our desired result.
Here is the complete code with both problems fixed.
#include <iostream>
#include <vector>
#include <map>
using namespace std;
bool canSum(int targetSum, vector<int> &vec, map<int, bool> &memo) {
int remainder;
if (memo.find(targetSum)!=memo.end())
return memo[targetSum];
else if (targetSum == 0)
return true;
else if (targetSum < 0)
return false;
else{
bool ans = false;
for (auto i : vec) {
remainder = targetSum - i;
ans = ans || canSum(remainder, vec, memo);
if (ans) {
memo.emplace(targetSum, true);
return true;
}
}
memo.emplace(targetSum, false);
}
return false;
}
int main() {
vector<int> vector1{7, 14};
int sum = 300;
map<int, bool> memo;
if (canSum(sum, vector1, memo))
cout << "true";
else
cout << "false";
}
This is the answer to your question "I do not know why canSum is not returning anything."
Now, in general one should not use recursive DP as it is too much time consuming and iterative DP is best suited for competitive programming problems.
I think this code is from the freecodecamp video. I have solved the same question like below. Here, 0 means false and 1 means true. I hope you'll understand:
#include<bits/stdc++.h>
using namespace std;
vector<int>memo(1000,10);
bool canSum(int n, vector<int>v){
if(n==0){
return true;
}
if(n<0) return false;
if(memo[n]==1) return true;
if(memo[n]==0) return false;
for(int i = 0; i<v.size(); i++){
int rmndr = n-v[i];
bool x = canSum(rmndr,v);
if(x){
memo[n] = 1;
return true;
}
else{
memo[n] = 0;
}
}
return false;
}
int main() {
int n,x;
cin>>x;
vector<int>v(x);
for(int i = 0; i<v.size(); i++){
cin>>v[i];
}
cin>>n;
if(canSum(n,v)) cout<<"true"<<endl;
else cout<<"false"<<endl;
return 0;
}
This is what you are looking for
#include <vector>
#include <unordered_map>
using namespace std;
bool canSum(int target, vector<int> arr,unordered_map<int,bool> &mp){
if(target == 0)
return true;
if(target < 0)
return false;
if(mp.find(target)!=mp.end())
return mp[target];
for(auto x:arr){
int rem = target - x;
if(canSum(rem,arr,mp) == true){
mp[target] = true;
return true;
}
}
mp[target] = false;
return false;
}
int main(){
int target = 300;
unordered_map<int,bool> mp;
vector <int> arr = {7,14};
cout<<canSum(target,arr,mp);
return 0;
}```
// memoization for the canSum problem
#include <iostream>
#include <unordered_map>
#include <vector>
using namespace std;
bool canSum(int targetSum, vector <int> &numbers, unordered_map <int,int> &memo) {
int key = targetSum;
if(targetSum == 0) return true;
if(targetSum < 0) return false;
if(memo.find(key) != memo.end()) return memo[key]; // to avoid duplicate subtree calculations
else {
for(auto x:numbers) {
int rem = targetSum - x;
if( canSum(rem, numbers, memo) == true) {
memo[key] = true;
return true;
}
}
memo[key] = false;
return false;
}
}
int main() {
unordered_map <int,int> mp1;
unordered_map <int,int> mp2;
unordered_map <int,int> mp3;
unordered_map <int,int> mp4;
unordered_map <int,int> mp5;
vector <int> nums{2,3};
vector <int> nums1{7,14};
vector <int> nums2{5,3,4,7};
vector <int> nums3{2,4};
vector <int> nums4{2,3,5};
cout<<canSum(7,nums,mp1)<<"\n";
cout<<canSum(7,nums2,mp2)<<"\n";
cout<<canSum(7,nums3,mp3)<<"\n";
cout<<canSum(8,nums4,mp4)<<"\n";
cout<<canSum(300,nums1,mp5)<<"\n";
return 0;
}
Output of the code: 1 stands for 'true' and 0 stands for 'false'

How do I find if two strings is isomorphic of not?

#include <iostream>
#include <string>
#include <vector>
using namespace std;
bool is_isomorphic(string input1, string input2)
{
if(input1.length()!= input2.length())
return false;
vector<int> diff_arr(26, -40);//Initialise with some random value.
for(int i = 0 ; i < input1.length(); i++){
if(diff_arr[input1[i]-'a'] == -40)
diff_arr[input1[i]-'a'] = input1[i] - input2[i];
else{
if(diff_arr[input1[i]-'a'] != input1[i] - input2[i])
return false;
}
}
return true;
}
int main() {
cout<<is_isomorphic("abcd", "aabb");
return 0;
}
My logic is that if characaters could be replaced with exact same characters in the second string then the character-wise difference has to be the same throughout.
The logic is failing in the above case.
You also need to check if two characters from input1 do not map to same character in input2.
#include <iostream>
#include <string>
#include <map>
#include <set>
using namespace std;
bool is_isomorphic(string input1, string input2)
{
if(input1.length()!= input2.length())
return false;
set<char> usedLetters;
map<char, char> transformations;
for(int i = 0 ; i < input1.length(); i++) {
auto iter = transformations.find(input1[i]);
if (iter != transformations.end()) {
if (iter->second == input2[i]) continue;
else return false;
}
if (usedLetters.count(input2[i])) return false;
usedLetters.insert(input2[i]);
transformations[input1[i]] = input2[i];
}
return true;
}
int main() {
cout<<is_isomorphic("abcd", "aabb");
return 0;
}
You need 2 arrays, one to know which character of input2 correspond to a given character of input1, and a second to check if a character of input2 is not already affected to a character of input1.
#include <iostream>
#include <string>
using namespace std;
bool is_isomorphic(const string& input1, const string& input2)
{
if (input1.length() != input2.length()) {
return false;
}
char map[256]{};
bool used[256]{};
for (size_t i = 0; i < input1.length(); i++) {
unsigned char val1 = input1[i];
if (!map[val1]) {
unsigned char val2 = input2[i];
if (used[val2]) {
return false;
}
map[val1] = input2[i];
used[val2] = true;
} else
if (map[val1] != input2[i]) {
return false;
}
}
return true;
}
int main() {
cout << is_isomorphic("abcd", "aabb") << endl;
cout << is_isomorphic("abcdb", "zerte") << endl;
return 0;
}

Remove only one element to make a string palindrome

I will be given string. I can remove only 1 element from it. After removing it if the new string becomes palindrome I have to print "Yes" otherwise "No".
For example, I am given a string "abdbca". Here I can remove 5th index 'c' and make it palindrome and i have to print "Yes". On the other hand if the string is something like "abcd" I can not make it palindrome by removing only one character. Hence I have to print "No".
I tried to do it but my code is not efficient enough. Can anybody please suggest me a efficient way to do it? I have to check strings of 10^5 length in less than 2.5 seconds.
the way I tried to do it is shown bellow :
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#define REP(i,n) for(int i=0;i<n;i++)
#define MAX 100010
using namespace std;
bool isPalindrome(char abc[]){
int len = strlen(abc), lem = len/2;
for(int i=0,n=len-1;i<=lem;i++,n--) if(abc[i]!=abc[n]) return false;
return true;
}
int main()
{
int tc;
char str[MAX];
scanf("%d",&tc);
while(tc--){
scanf("%s", str);
int length = strlen(str), len = length - 1, z = length % 2, res = 0, ans = 0, b=0,lem = length / 2;
for(int i = 0;i<length;i++){
int n=0, m=1;
for(int x = 0, y = len;x<i && y!=i;x++,y--){
n++;
if(str[x]!=str[y]){
m=0; ++res;
break;
}
}
if(i>lem) for(int x=n,y=len-n-1;x<y;x++,y--){
if(str[x]!=str[y]){
m=0; ++res;
break;
}
}
else for(int x=n+1,y=len-n;x<y;x++,y--){
if(str[x]!=str[y]){
m=0; ++res;
break;
}
}
if(m==1) {printf("YES\n");b++;break;}
}
//if(length <= res) printf("NO\n");
if(b==0) printf("NO\n");
}
return 0;
}
Since you you only need to remove one character, you can do so in linear time by modifying palindrome checking. The idea is that you compare characters from the beginning to characters from the end and stop at the first mismatch. If you remove one character from the mismatching pair and get a palindrome, then return true, otherwise return false. I implemented the idea in C++ below.
#include<iostream>
#include<string>
using namespace std;
bool palindromeExists(string s)
{
int i = 0;
int j = s.length()-1;
while(i < j)
{
if(s[i] != s[j]) //first mismatch
break;
i++;
j--;
}
int tempj = j-1; //remove s[j]
int tempi = i;
while(tempi < tempj)
{
if(s[tempi] != s[tempj])
break;
tempi++;
tempj--;
}
if(tempi >= tempj) //palindrome found?
return true;
tempi = i+1; //remove s[i]
tempj = j;
while(tempi < tempj)
{
if(s[tempi] != s[tempj])
return false;
tempi++;
tempj--;
}
return true;
}
int main()
{
string s = "abca";
if(palindromeExists(s))
cout << "YES" << endl;
else
cout << "NO" << endl;
return 0;
}
This should return true if the string is already a palindrome, or if it can be a palindrome after the removal of one character. I hope I didn't miss any corner cases.
You can refer complete program in c++ here. Input the string to get the index of character to be removed. String reversal is performed in palim() function. It returns -1 if string is already palindrome.
#include <iostream>
#include <algorithm>
#include <string>
using namespace std;
bool palim(string s)
{
string s2;
s2=string(s.rbegin(),s.rend());
if(s2==s)
{
return true;
}
else
{
return false;
}
}
int check(string s)
{
int x;
if(s.length()%2==0)
{
for(int i=0,j=s.length()-1;i<s.length()/2,j>=s.length()/2;i++,j--)
{
if(s[i]!=s[j])
{
string s1=s;
s1.erase(j,1);
if(palim(s1))
{
x=j;
break;
}
else
{
string s1=s;
s1.erase(i,1);
if(palim(s1))
{
x=i;
break;
}
}
}
}
}
else
{
for(int i=0,j=s.length()-1;i<s.length()/2,j>s.length()/2;i++,j--)
{
if(s[i]!=s[j])
{
string s1=s;
s1.erase(j,1);
if(palim(s1))
{
x=j;
break;
}
else
{
string s1=s;
s1.erase(i,1);
if(palim(s1))
{
x=i;
break;
}
}
}
}
}
return x;
}
int main()
{
string s;
cin>>s;
if(palim(s))
{
cout<<"-1"<<endl;
}
else
{
cout<<check(s)<<endl;
}
return 0;
}
Similar to turingcomplete, but with sub functions:
bool isPalindrome(std::string::const_iterator& start, std::string::const_iterator& end)
{
while (start < end) {
--end;
if (*start != *end) {
return false;
}
++start;
}
return true;
}
bool test(const std::string& s)
{
auto start = s.begin();
auto end = s.end();
if (isPalindrome(start, end)) {
// If we remove the middle character of a palindrome,
// We still have a palindrome.
return true;
}
// Now test if there is a palindrome
// if we skip the mismatch char from the start or from the end.
auto start2 = start;
auto end2 = end;
++start2;
--end;
return isPalindrome(start, end) || isPalindrome(start2, end2);
}
Live example

How to check if parts of a single-string input are int or char?

I have to take a string i/p of length 15. First two letters should be alphabets, next 13 digits. Eg: AB1234567891234. How can I check if the first two are only alphabets and others are only digits?
#include <regex>
const std::regex e("^[a-zA-Z][a-zA-Z][0-9]{13}$");
std::string str = "ab1234567890123";
if (std::regex_match (s,e))
std::cout << "string object matched\n";
#include <cctype>
bool is_correct(std::string const& s) {
if (s.size() != 15) return false;
if (!std::isalpha(string[0]) || !std::isalpha(string[1]))
return false;
for (std::size_t i = 2; i < 13; ++i) {
if (!std::isdigit(string[i])) return false;
}
return true;
}
You can use the functions defined in the <cctype> header file like isalpha() and isdigit().
#include<iostream>
#include<string>
int main(int argc, char *argv[])
{
std::string n_s = "AB1234567896785";
bool res = true;
std::cout<<"Size of String "<<n_s.size()<<n_s.length()<<std::endl;
int i = 0, th = 2;
while(i < n_s.length())
{
if(i < th)
{
if(!isalpha(n_s[i]))
{
res = false;
break;
}
}
else
{
if(!isdigit(n_s[i]))
{
res = false;
break;
}
}
i++;
}
if(res)
{
std::cout<<"Valid String "<<std::endl;
}
else
{
std::cout<<"InValid Strinf "<<std::endl;
}
return 0;
}