Longest palindrome in a string? - c++

I want to print the longest palindrome in a string , I have written the code but this is giving wrong answer for some test cases . I am not able to find the error in my code .
Anyone help me with this , Anyhelp would be appreciated.
Input
vnrtysfrzrmzlygfv
Output
v
Expected output
rzr
Code:
class Solution {
public:
int ispalindrome(string s)
{
string rev = "";
int n = s.size();
for (int i = n - 1; i >= 0; i--) {
rev = rev + s[i];
}
if (rev == s) {
return 1;
}
return 0;
}
string longestPalin(string S)
{
// code here
int size = S.size();
int size_of_substr = 0;
string ans;
for (int i = 0; i < size; i++) {
for (int j = i + 1; j < size; j++) {
string s2 = S.substr(i, j);
if (ispalindrome(s2)) {
if (s2.size() > size_of_substr) {
ans = s2;
size_of_substr = s2.size();
}
else {
continue;
}
}
else {
continue;
}
}
}
return ans;
}
};

You are using substr(.) incorrectly. The second argument is the size of the substring.
string s2 = S.substr(i, j); should be replaced by string s2 = S.substr(i, j-i+1);
Moreover, this code will not be very efficient. To speed it up, I modified your code in the following way:
I pass the string by reference to the ispalindromefunction
I modified the algorithm to check if the substring is a palindrome. It returns false after the first mismatch
I don't build each substring explicitly. I only pass the start and beginning of the substring to the helper function
I start by checking if there exists a palindrome of the maximum size, and then I decrease its length. As soon as a palindrome is found, we know it has the maximum size, and we can stop the search
#include <iostream>
#include <string>
class Solution {
public:
int ispalindrome(const std::string& S, int i, int j) {
while (i < j) {
if (S[i++] != S[j--]) return 0;
}
return 1;
}
std::string longestPalindrome(const std::string& S) {
int size = S.size();
int imax = 1;
for (int size_of_substr = size; size_of_substr > 0; size_of_substr--, imax++) {
int j = size_of_substr - 1;
for (int i = 0; i < imax; i++, j++) {
if (ispalindrome(S, i, j)) {
std::string ans = S.substr(i, size_of_substr);
return ans;
}
}
}
return "";
}
};
int main() {
Solution sol;
std::string S;
std::cin >> S;
auto ans = sol.longestPalindrome(S);
std::cout << ans << "\n";
return 0;
}

Related

How to structure my for-loop correctly so my program runs?

So i have a function, string update_name(string names[], int size), which I wanted to let the user pick one of the three names they previously inputted, and change one of the name (picked by the user). However, when I try to run this program, it does ask me which name i wish to change, i type a name, but then it goes to the print_summary function again (as seen by the main function at the bottom). Not sure how to fix this. Thnanks
The function is the second last one in the code, just before the int (main), i put *** between it to help make it clearer.
#include "splashkit.h"
#include <vector>
using std ::vector;
#define SIZE 3
string read_string(string prompt)
{
string result;
write(prompt);
result = read_line();
return result;
}
int read_integer(string prompt)
{
string line;
int result;
line = read_string(prompt);
result = convert_to_integer(line);
return result;
}
double read_double(string prompt)
{
string line;
double result;
line = read_string(prompt);
result = convert_to_double(line);
return result;
}
int total_length(string names[], int size)
{
int result = 0;
for (int i = 0; i < size; i++)
{
string name = names[i];
result += name.length();
}
return result;
}
bool contains(string names[], int size, string name)
{
for (int i = 0; i < size; i++)
{
if (to_lowercase(names[i]) == to_lowercase(name))
{
return true;
}
}
return false;
}
string shortest_name(string names[], int size)
{
string min;
min = names[0];
for (int i = 1; i < size; i++)
{
if (min.length() > names[i].length())
{
min = names[i];
}
}
return min;
}
string longest_name(string names[], int size)
{
string max;
max = names[0];
for (int i = 1; i < size; i++)
{
if (max.length() < names[i].length())
{
max = names[i];
}
}
return max;
}
int index_of(string names[], int size, string name)
{
int blah = 0;
for (int i = 0; i < size; i++)
{
if (to_lowercase(names[i]) == to_lowercase(name))
{
blah = i + 1;
}
}
if (blah == 0)
{
blah = blah -1;
}
return blah;
}
void print_summary(string names[], int size)
{
write_line(" ");
write_line(" ~ Names List ~ ");
write_line(" ");
for (int i = 0; i < size; i++)
{
write_line(names[i]);
}
write_line(" ");
int total;
total = total_length(names, size);
write("The total length is ");
write_line(total);
write_line("The shortest name is " + shortest_name(names, size));
write_line("The longest name is " + longest_name(names, size));
bool has_me;
has_me = contains(names, size, "John");
if (has_me)
{
write("This list contains the name John, at the index of: ");
int index = index_of(names, size, "John");
write_line(index);
}
else write("This list does not contain the name John");
write_line(" ");
}
*************************
string update_name(string names[], int size)
{
string name_change;
string result;
write_line(" ");
name_change = read_string("Choose a name you wish to update (enter
the name): ");
for(int i=0; i;)
{
if(to_lowercase(name_change) == to_lowercase(names[i]))
{
string newname = read_string("What is the new name?: ");
names[i]=newname;
break;
}
}
return result;
}
*****************************
int main()
{
#define SIZE 3
string names[SIZE];
string newname;
string data[SIZE];
int i;
i = 0;
while (i < SIZE)
{
names[i] = read_string("Enter a name: ");
i++;
}
print_summary(names, SIZE);
update_name(names, SIZE);
print_summary(names, SIZE);
write_line(" ~ Goodbye! ~ ");
write_line(" ");
return 0;
}
The problem lies with the for(int i=0; i;) but I cannot figure out what the problem is and how to fix it.
To fix your for-loop you need to have a correct condition statement and increment expression. To loop from 0..=3 you would structure the for-loop as:
for (int i = 0; i < 4; ++i)
{ ... }
In general:
You have a init-statement that initializes a variable that will exist only for the scope of the for-loop. eg: int i = 0 - An integer i initialized to 0.
A condition statement that ensures some condition is true and breaks out of the loop once it no longer holds. eg: i < 4 - While i is less-than 4.
And finally, a increment expression that is run at the end of each iteration in the loop. eg: ++i - Increment i by 1.
Generic structure of a for-loop
for (init-statement; condition; increment-expression)
{ ... }
See: for-loops

MayI know why this code is not giving any output?

Please help me to solve the query that this code runs infinitely at a particular line.
It does not give any output as at the end of the code I write the code to print the vector. Even after I assign any value to vector "result" manually still it is not giving any output. why is it so?
#include<bits/stdc++.h>
using namespace std;
bool authorize(int strValue, int value, int M)
{
long int newValue = (strValue - (value * 131) % M);
if (newValue >= 48 && newValue <= 57)
return true;
if (newValue > 65 && newValue <= 90)
return true;
if (newValue >= 97 && newValue <= 122)
return true;
return false;
}
int hashingfunct(string str, int M)
{
long int P, F, sum = 0;
int len = str.length();
for (int i = 0; i < len; i++)
{
P = pow(131, len - i - 1);
F = (int)str[i];
sum += (F * P) % M;
}
sum = sum % M;
return sum;
}
int main()
{
int n = 5;
string str1, str2;
vector<vector<string> > events;
for (int i = 0; i < n; i++) {
cin >> str1 >> str2;
vector<string > temp;
temp.push_back(str1);
temp.push_back(str2);
events.push_back(temp);
}
for (int i = 0; i < n; i++) {
cout << events[i][0] << events[i][1];
}
/*
INPUT FORMAT:
setpassword 1
setpassword 2
setpassword 3
authorize 49
authorize 50
*/
vector<int> result;
int j = 0;
long int m = pow(10, 9);
long int M = m + 7;
long int value, strValue;
for (int i = 0; i < events.size(); i++)
{
strValue = stoi(events[i][1]);
if (events[i][0] == "setPassword") {
value = hashingfunct(events[i][1], M);
}
else if (strValue == value)
result[j++] = 1;
else if (authorize(strValue, value, M))
result[j++] = 1;
else
result[j++] = 0;
}
for (int i = 0; i < result.size(); i++) {
cout << result[i];
}
}
Your program has complete Undefined Behaviour.
Let's get started with the first problem. In the following check code
long int value, strValue; // not initialised
for (int i = 0; i < events.size(); i++)
{
// ...
// here it should have been "setpassword" (i.e. all are small letters)
if (events[i][0] == "setPassword")
{
// if the check fails the `value` never get initialised!
value = hashingfunct(events[i][1], M);
}
// If the `value` not been initialised, check happens with any garbage value here!
else if (strValue == value)
// ...other code
}
You are checking whether the string is "setPassword" instead of "setpassword" (i.e. see in the events vector, all the strings are small letters).
If that goes wrong, the value will never get initialized, meaning it holds any garbage value and hence conducting this check else if (strValue == value) can cause any behaviour to your program (aka Undefined Behaviour).
Secondly, the vector<int> result; is empty at the beginning. Therefore accessing elements via std::vector::operator[] later
result[j++] = 1;
// ...
result[j++] = 1;
// ...
result[j++] = 0;
triggers the access out of bounds (UB). There you need just result.emplace_back(/*value*/); or result.push_back(/*value*/);, and no need of redutant variable j.
In short, you need
#include <iostream>
#include <vector>
#include <string>
// ..other functions
int main()
{
std::vector<std::vector<std::string> > events {
{"setpassword", "1"}, // can be also user input, like in your example
{"setpassword", "2"},
{"setpassword", "3"},
{"authorize", "49" },
{"authorize", "50" }
};
std::vector<int> result;
const long int M = pow(10, 9) + 7;
long int value{ 0 }, strValue{ 0 }; // default initialization
for (const std::vector<std::string> row: events) // better use range-based loop
{
strValue = std::stoi(row[1]);
if (row[0] == "setpassword") {
value = hashingfunct(row[1], M);
if (strValue == value)
result.emplace_back(1);
else if (authorize(strValue, value, M))
result.emplace_back(1);
}
else
result.emplace_back(0);
}
}
As a side note,
Please do not use using namespacestd;
Why should I not #include <bits/stdc++.h>?
Corrected code
#include<bits/stdc++.h>
using namespace std;
bool authorize(long int strValue,long int value,int M){
long int value1=value*131;
long int newValue=(strValue-(value1%M))%M;
if(newValue>=48 && newValue<=57)
return true;
if(newValue>=65 && newValue<=90)
return true;
if(newValue>=97 && newValue<=122)
return true;
return false;
}
int hashingfunct(string str,int M){
long int P,F,sum=0;
int len=str.length();
for(int i=0;i<len;i++){
P=pow(131,len-i-1);
F=(int)str[i];
sum+=(F*P)%M;
}
sum=sum%M;
return sum;
}
int main(){
int n=5;
string str1,str2;
vector<vector<string> > events;
for (int i=0;i<n;i++){
cin>>str1>>str2;
vector<string > temp;
temp.push_back(str1);
temp.push_back(str2);
events.push_back(temp);
}
/*
setPassword cAr1
authorize 223691457
authorize 303580761
setPassword d
authorize 100
*/
vector<int> result;
int j=0;
long int m=pow(10,9);
long int M=m+7;
long int value,strValue;
for(int i=0;i<events.size();i++){
if(events[i][0]=="setPassword"){
value=hashingfunct(events[i][1],M);
continue;
}
strValue=stoi(events[i][1]);
if(strValue==value)
result.push_back(1);
else if(authorize(strValue,value,M))
result.push_back(1);
else
result.push_back(0);
}
for(int i=0;i<result.size();i++){
cout<<result[i];
}
}

Longest Palindrome in integer array

I want to find the largest palindrome in an integer array. I tried making my own algorithm and not looking at the online ones. But this is not working. I tried doing debugging but couldn't get it to work.
Sample input:
"1367611342142412431113424823782"
Output: 113421424124311
void palindrome()
{
int max = 0;
int len;
int start;
int end;
int st=0,en=0;
bool palin = false;
for(int i=0;i<size;i++)
{
for(int j=size-1; j>=0;j--)
{
if(array[i] == array[j])
{
start = i;
end = j;
while(j==i+1 || j+1 == i || j == i )
{
if(array[i] == array[j])
{
i++;
j--;
palin = true;
}
else
{
palin = false;
break;
}
}
i= start;
j= end;
}
if(palin == true)
{
len = end - start;
if(len>max)
{
cout<<" "<<st<<" "<<en<<endl;
st=i;
en =j;
max = len;
}
}
}
}
cout<<endl;
cout<<st<<" "<<en<<endl;
ofstream file("output.txt");
for(int i=st;i<=en;i++)
{
file<<array[i];
}
}
There is solution
#include <iostream>
#include <string>
struct Result
{
int fromIndex, toIndex;
Result(int fromIndex, int toIndex){
this->fromIndex = fromIndex;
this->toIndex = toIndex;
}
int length(){
return toIndex - fromIndex;
}
};
bool isPalindrome(std::string &s, int left, int right){
while(left <= right){
if(s[left] != s[right]){
return false;
}
left ++;
right --;
}
return true;
}
std::string solve(std::string &s){
int startIndex = 0;
int toIndex = s.size() - 1;
Result result(0,0);
while(true){
if(isPalindrome(s, startIndex, toIndex)){
if(result.length() < (toIndex - startIndex)){
result.fromIndex = startIndex;
result.toIndex = toIndex;
}
}
toIndex --;
if(toIndex <= startIndex){
toIndex = s.size() - 1;
startIndex++;
}
if(startIndex == s.size() - 1){
break;
}
}
std::string str = "";
for (int i = result.fromIndex; i <= result.toIndex; ++i)
{
str += s[i];
}
return str;
}
int main()
{
std::string s = "1367611342142412431113424823782";
std::string result = solve(s);
std::cout << "Longest palindrome is: "<< result;
return 0;
}
You need to think in more structural way. Split your task in to sub-tasks first. In this case there are to sub-tasks:
1. go over all possible combinations
2. check if this combination is a palindrome.
Each task is another function - this way it is easier to think, read code and debug.
(In case you want to write it to file - it is a third task!)
Here is the code for the "go over all possible combinations". I guess you will find yourself how to check a single array if it is a palindrome.
#include <iostream>
using namespace std;
bool isPalindrome(int* arr, int size);
bool findLargestPalindrome(int* arr, int size);
int main()
{
int arr[] = { 1,3,6,7,6,1,1,3,4,2,1,4,2,4,1,2,4,3,1,1,1,3,4,2,4,8,2,3,7,8,2 };
int arrSize = 31;
findLargestPalindrome(arr, arrSize);
}
bool findLargestPalindrome(int* arr, int size)
{
for (int testSize = size; testSize > 0; testSize--)
{
int startIndex = 0;
while (testSize + startIndex <= size)
{
int* arrayToTest = &(arr[startIndex]);
if (isPalindrome(arr, testSize))
{
//TODO: you found it - do with it whatever you want
return true;
}
startIndex++;
}
}
return false;
}
bool isPalindrome(int* arr, int size)
{
//TODO: your code for single palindrome
return false;
}

C++ "terminating with uncaught exception of type std::out_of_range: vector" error in a merge sort algorithm

I have a c++ code which should use merge sort algorithm to sort a file containing 800,000+ words each on a new line.
What I did ?
To start off, I tried implementing the following merge sort algorithm and tried testing it on a small piece of input. I cannot figure out where I am getting index out of bounds error with the vector. If anyone could help me with this, I would really appreciate
#include <fstream>
#include <iostream>
#include <vector>
using namespace std;
vector<string> merge(const vector<string>& first,
const vector<string>& second) {
// Write your code to merge vectors first and
// second onto result.
vector<string> output;
int i = 0;
int j = 0 ;
int size_first = sizeof(first);
int size_second = sizeof(second);
while(i < size_first || j < size_second){
if (i < size_first && j < size_second){
if (first.at(i) < second.at(j)){
output.push_back(first.at(i));
i++;
}
else{
output.push_back(second.at(i));
j++;
}
}
else if (i < size_first){
output.push_back(first.at(i));
i++;
}
else{
output.push_back(second.at(j));
j++;
}
}
return output;
}
void mergeSort(vector<string>& words) {
if (words.size() <= 1)
{
return;
}
int n = words.size();
int middle = n/2;
vector<string> first_half(middle);
for (int i = 0; i < middle; ++i) {
first_half[i] = words[i];
}
vector<string> second_half(n - middle);
for (int i = middle; i < n; ++i) {
second_half[i - middle] = words[i];
}
words = merge(first_half, second_half);
}
void sort(vector<string>& words) {
// Invoke mergeSort here.
mergeSort(words);
}
int main(){
vector<string> names;
names.push_back("Smith");
names.push_back("Abinash");
names.push_back("Ciara");
names.push_back("Reeta");
sort(names);
return 0;
}
std::vector has a size() member function that returns the number of elements in vector. sizeof(first) returns size in bytes of object representation of the type std::vector<string>, and that's not what you need.
int size_first = sizeof(first);
int size_second = sizeof(second);
Should be replaced with
int size_first = first.size();
int size_second = second.size();
You have a typo in:
else {
output.push_back(second.at(i));
j++;
}
Should be
...
output.push_back(second.at(j))
And another one. You forgot about the main thing - calling mergeSort for the parts before calling merge. Should be:
mergeSort(first_half);
mergeSort(second_half);
words = merge(first_half, second_half);
you are determining the size of the vector wrong:
int size_first = sizeof(first);
int size_second = sizeof(second);
replace it by
size_t size_first = first.size();
size_t size_second = second.size();

Function not declared in the scope (C++)

I've been working on this Morris-Pratt algorithm to match substrings to a text, and I'm having trouble how to declare the failure function in the actual function so the compiler won't complain. I have like 2 hours to finish this. So please help me soon :/
int KMPmatch(const string& text, const string& pattern)
{
int n = text.size();
int m = pattern.size();
std::vector<int> fail = computeFailFunction(pattern);
int i = 0;
int j = 0;
while (i < n)
{
if (pattern[j] == text[i])
{
if (j == m-1) return i-m+1;
i++; j++;
}
else if (j > 0) j = fail[j-1];
else i++;
}
return -1;
}
//KMPFailure function
std::vector<int> computeFailFunction(const string& pattern)
{
std::vector <int> fail(pattern.size());
fail[0] = 0;
int m = pattern.size();
int j = 0;
int i = 1;
while (i < m)
{
if (pattern[j] == pattern[i])
{
fail[i] = j+1;
i++; j++;
}
else if (j > 0)
{
j = fail [j-1];
}
else
{
fail[i]= 0;
i++;
}
}
return fail;
}
Put std::vector<int> computeFailFunction(const string& pattern); ahead of int KMPmatch(const string& text, const string& pattern).
Or put function declaration into header file and included in source files, that is what project with multiple source files do.