Palindrome C++ (strcpy) - c++

I tried to find a solution on internet but couldnt find anything similar to this. I am using strcpy and iteration to make a palindrome function in c++ everything is working fine but the strcpy section. I dont know how to solve it or what other alternative to use. Thank you.
#include <iostream>
#include <cstring>
using namespace std;
void palindrom(char[]);
int main()
{
char binput[100];
cout << "Hello please enter your word here: " << endl;
cin >> binput;
palindrom(binput);
system("pause");
return 1;
}
void palindrom(char binput[])
{
int max= strlen(binput);
char cinput[100];
char dinput[100];
for (int i=max, n=0; i>=0, n<=max; i--, n++)
strcpy(dinput[n],binput[i]);
cout << dinput << endl;
if (strcmp(binput,dinput)==true)
cout << "Is palindrome " << endl;
else
cout << "Is not " << endl;
}

Hope this solves.Basically first just check the first letter of the word and the last. If they are not equal then they are not palindrome. If they are equal then proceed on by comparing from the front end character with their respective back ends.
#include<iostream>
#include<cstring>
using namespace std;
int CheckPalindrome(char input[],int len);
int main()
{
char input[100];
int result,inpLen;
cout<<"Enter Word:"<<endl;
cin>>input;
cout<<"Entered Word:"<<input<<endl;
cout<<"Checking....."<<endl;
inpLen=strlen(input);
result=CheckPalindrome(input,inpLen);
if(result == 1)
{
cout<<"Entered Word:"<<input<<" is a palindrome!"<<endl;
}
else
{
cout<<"Entered Word:"<<input<<" is not a palindrome!"<<endl;
}
return 0;
}
int CheckPalindrome(char input[],int len)
{
int result;
if(input[0] != input[len-1])
{
result = 0;
}
else
{
for(int i=0 ; i<len ; i++)
{
if(input[i] == input[len-1-i])
{
result = 1;
}
else
{
result = 0;
break;
}
}
}
return result;
}

Looks like you are not clear one what strcpy does. It copies an entire string from a source to a destination. You don't need that here. You need to make simple assignments.
Let's say your input is "abc". I assume you want to create the string "abccba" from it.
Given the characters in the input:
+---+---+---+
| a | b | c |
+---+---+---+
you need to map them to the output array as:
binput[0]
| binput[len-1]
| | binput[len-1]
| .... | | binput[0]
| | | .... |
v v v v
+---+---+---+---+---+---+
| a | b | c | c | b | a |
+---+---+---+---+---+---+
Now, translate that logic into code:
int len= strlen(binput);
char dinput[100];
for (int i = 0; i < len; ++i )
{
dinput[i] = binput[i]; // Takes care of the left side of the palindrome.
dinput[2*len-i-1] = binput[i]; // Takes care of the right side of the palindrome
}
// Make sure to null terminate the output array.
dinput[2*len] = '\0';
Update, in response to OP's comment
You need:
for (int i = 0; i < len; ++i )
{
dinput[len-i-1] = binput[i];
}
dinput[len] = '\0';

if(strcmp(word,strrev(word)==0)
Pallindrome

You should initialize i to max-1 instead of max, the way you have it now it will copy the NULL terminator character '\0' to the first element of dinput which results in a 0 length string.
You will also need to make sure to NULL terminate dinput. Try:
for (int i=max-1, n=0; i>=0, n<=max; i--, n++)
dinput[n] = binput[i];
dinput[max] = '\0';

Related

What is wrong with my program to find the longest word in a sentence?

#include <iostream>
using namespace std;
int main() {
char a[101]{0};
cin>>a;
cin.getline(a,101);
cin.ignore();
int currLen{0};
int maxLen{0};
int startInd{-1};
int endInd{-1};
for(int i=0; i<101; i++) {
if(a[i]!=' ' ) {
++currLen;
} else if(a[i]==' '||a[i]=='\0') {
if(currLen>maxLen) {
maxLen=currLen;
startInd=i-currLen;
endInd=i-1;
}
if(a[i]=='\0')
break;
currLen=0;
}
}
cout<<maxLen<<endl;
if(startInd==-1)
cout<<-1;
else
for(int i=startInd; i<=endInd; i++)
cout<<a[i];
return 0;
}
If I take an input here, for example, "My name is Manav Kampani"
It will output 5
Manav instead of 7
Kampani
But if I write "My name is Manav Kampani ", with space after the last word
than it is considering Kampani too printing Kampani.
Also when I input "Kampani Manav is my name" then too it's displaying the wrong output. That means it is not considering the first word of the sentence.
if(a[i]!=' ' )
{
++currLen;
}
else if(a[i]==' '||a[i]=='\0')
{
....
}
Consider the case of a[i] == 0. Which of these if-statements will apply.
Answer: the first one. Which means you'll never look at the final word in the string. You also don't exit at the end of the string, but instead loop through whatever is in your string all the way out to character 101.
As a general structure, be very, very careful with this:
if (condition)
else if (condition)
// without a final else section
If you do that, you need to think about what you're doing. In this particular case, you can have:
if (a[i] != 0 && a[i] != ' ')
else
It may not solve all your issues, but it should solve some.
A nice sliding window pattern implementation.
You have 3 problems in your code
You must not write cin >> a;
You must not write cin.ignore();
You need to modify your if statement like so: if (a[i] != ' ' && a[i] != '\0') Otherwise you will not detect the last word.
Your complete working code with that minor fixes will lokk like that.
int main()
{
char a[101]{ 0 };
//cin >> a;
cin.getline(a, 101);
//cin.ignore();
int currLen{ 0 };
int maxLen{ 0 };
int startInd{ -1 };
int endInd{ -1 };
for (int i = 0; i < 101; i++)
{
if (a[i] != ' ' && a[i] != '\0')// Add comparison
{
++currLen;
}
else if (a[i] == ' ' || a[i] == '\0')
{
if (currLen > maxLen)
{
maxLen = currLen;
startInd = i - currLen;
endInd = i - 1;
}
if (a[i] == '\0')
break;
currLen = 0;
}
}
cout << maxLen << endl;
if (startInd == -1)
cout << -1;
else
for (int i = startInd; i <= endInd; i++)
cout << a[i];
return 0;
}
Additionally. You should not use C-Style arrays in C++. And please use std::string
There is a couple of things here:
1- You don't need to do a cin>>a this is actually consuming the first word, and afterwards the content is overrided by cin.getline(). So removing the firsst cin>>ayou'll be fine.
2- The last word is not read because there isn't any if condition that matches the condition aka.
if(a[i]!=' ' ) case of not a space
//not end of word
else if(a[i]==' '||a[i]=='\0') case of space or null
//end of word
So your last character is not a space nor null, that means you don't detect the last word.

How can I print only consonants?

I have been asked to write a code to print only consonants using a dynamic array. I wrote a code to do that but it prints exactly the input without canceling out the vowels.
#include <iostream>
#include<string>
using namespace std;
int main()
{
int len,i;
cin>>len;
char* pArray=new char[len];
char ch[len];
for(i=0;i<len;i++)
cin>>ch[i];
for(i =0;i<len;i++){
if(ch[i]=='a' && ch[i]=='e' && ch[i]=='i' && ch[i]=='o' && ch[i]=='u')
break;
else
pArray[i]=ch[i];
}
for( i=0;i<len;i++)
cout<<(pArray[i]);
return 0;
}
If I write the input ample, it should print only mpl.
Your program isn't working because of logic error. You have used && operator between each logical expression. So, whenever the compiler come across a character it checks whether the character is 'a' and 'e' and 'i' and 'o' and 'u', which is obviously not possible simultaneously at the same time. Use "||" operator instead of "&&". Also for entering character in pArray you need to define another integer for its index .
int k=0;
for(i =0;i<len;i++){
if(ch[i]=='a' || ch[i]=='e' || ch[i]=='i' || ch[i]=='o' || ch[i]=='u')
break;
else
{pArray[k]=ch[i]; k++;}
doing
for(i =0;i<len;i++){
if(ch[i]=='a' && ch[i]=='e' && ch[i]=='i' && ch[i]=='o' && ch[i]=='u')
break;
else
pArray[i]=ch[i];
}
the test ch[i]=='a' && ch[i]=='e' && ch[i]=='i' && ch[i]=='o' && ch[i]=='u' is always false because a character cannot be several at the same time.
you also need a dedicated index to write in pArray and not print after based on len but that additional index.
Also check cin>>len; success (and other use of >>) else you do with len is 0 and none of the next read success because you do not clear the error flag nor bypass the invalid input.
Note also there are not only vowel and consonant, so when a character is not vowel that does not means it is a consonant, what must be done for other characters ?
Do not use variable length arrays as you did for ch.
Out of that, why are you using array of characters rather than std::string, is it required by statement ?
based on your code minimal changes also managing uppercase character can be :
#include <iostream>
#include <ctype.h>
using namespace std;
int main()
{
int len;
if (!(cin>>len))
cerr << "len is not a number" << endl;
else if (len <= 0)
cerr << "len must be > 0" << endl;
else {
char* pArray = new char[len];
char* ch = new char[len];
int i;
for (i=0;i<len;i++){
if (!(cin>>ch[i])) {
cerr << "EOF, abort" << endl;
return -1;
}
if (!isalpha(ch[i])) {
cerr << "invalid character, abort" << endl;
return -1;
}
}
int j = 0;
for(i =0;i<len;i++) {
switch (ch[i]) {
case 'a':
case 'A':
case 'e':
case 'E':
case 'i':
case 'I':
case 'o':
case 'O':
case 'u':
case 'U':
case 'y': // is vowel no ?
case 'Y': // is vowel no ?
break;
default:
// suppose only consonant and vowel
pArray[j++]=ch[i];
}
}
for( i=0;i<j;i++)
cout<<(pArray[i]);
cout << endl;
}
return 0;
}
Compilation and execution :
pi#raspberrypi:/tmp $ g++ -Wall c.cc
pi#raspberrypi:/tmp $ ./a.out
5
ample
mpl
pi#raspberrypi:/tmp $
There's a few mistakes in your code. I'm feeling generous, see how you get on with this
int main()
{
// read the word
int length;
cin >> length;
char* word = new char[length];
for (int i = 0; i < length; ++i)
cin >> word[i];
// allocate enough space for the word without vowels
char* no_vowels = new char[length];
// copy the non-vowels
int no_vowels_length = 0;
for (int i = 0; i < length; ++i)
{
if (word[i] != 'a' && word[i] != 'e' && word[i] != 'i' && word[i] != 'o' && word[i] != 'u')
{
// found a non-vowel, copy it to the end of the no-vowel word
no_vowels[no_vowels_length] = word[i];
// and increase the length of the no vowel word
++no_vowels_length;
}
}
// write out the word without vowels
for (int i = 0; i < no_vowels_length; ++i)
cout << no_vowels[i];
}
I think the idea you are missing is that you need two variables for the lengths of your two different strings
Quickly fixing the code inline:
every warning(1) error(4) is commented inline.
#include <iostream>
#include<string>
using namespace std;
int main()
{
int len, i;
cin >> len;
char* pArray = new char[len];
char* ch = new char[len];
for (i = 0; i < len; i++)
cin >> ch[i];
//WARNING: please note that pArray NOR ch isn't NULL terminated
int j = 0; //ERROR 1: you need to count the inserted char
for (i = 0; i < len; i++) {
//ERROR 2: you need an OR in order to check for vowels, not an AND
if (ch[i] == 'a' || ch[i] == 'e' || ch[i] == 'i' || ch[i] == 'o' || ch[i] == 'u')
//ERROR 3: if found, do not break, instead skip the vowels...
continue;
else
pArray[j++] = ch[i]; //ERROR 1bis: so you increment the j every time you insert a char
}
for (i = 0; i < j; i++) //ERROR 4: print out only the added lettere, indeed pArray is longer than needed (space for further improvement?)
cout << (pArray[i]);
return 0;
}
Hope it helps,
Stefano
I believe there is a hole in your logic. IMHO, you can't have the same index for the ch (source) array and the pArray (target or destination) array.
Draw out the source and target arrays:
Source (example):
+---+---+---+---+---+
| H | e | l | l | o |
+---+---+---+---+---+
Target:
+---+---+---+---+---+
| | | | | |
+---+---+---+---+---+
After ignoring the e, your Source will be pointing at the first 'l' and your target will be pointing at the 3rd slot in pArray:
Source (example):
+---+---+---+---+---+
| H | e | l | l | o |
+---+---+---+---+---+
0 1 2 3 4
Target:
+---+---+---+---+---+
| H | | l | | |
+---+---+---+---+---+
0 1 2 3 4
In the simple version you will need to have one index that represents the "next" available slot in the target array, and one index that represents the current letter in the source array.
(Or you could use another pointer to the target array and increment that)
char * p_target_slot = pArray;
int target_index = 0;
for(i =0;i<len;i++)
{
if( ch[i]=='a'
|| ch[i]=='e'
|| ch[i]=='i'
|| ch[i]=='o'
|| ch[i]=='u')
continue;
else
{
*p_target_slot++ = ch[i];
// Or you can use this:
pArray[target_index] = ch[i];
++target_index;
}
}

my code doesn't run some thing wrong about strings, c++

I was training on solving algorithms, I wrote a code but it won't compile
in (if) I can not check s[i]=='S' .
I'm trying to if s[i] is S character or not but I don't know where my problem is.
If I can't use this syntax, what could be a solution?
#include<iostream>
#include<string>
using namespace std;
int main()
{
double v_w=25,v_s=25,d_w=25,d_s=25;
int n;
cin>>n;
string s[]={"WSSS"};
int i ;
for (i=0; i<n; i++)
{
if( s[i] == "W" )
{
v_s += 50;
d_w = d_w + (v_w/2);
d_s = d_s + (v_s/2);
cout<<"1 \n";
}
if(s[i]=='W')
{
v_w +=50;
d_w = d_w + (v_w/2);
d_s = d_s + (v_s/2);
cout<<"2 \n";
}
return 0;
}
cout<< d_w<<endl<<d_s;
}
string s[]={"WSSS"}; means an array of strings which the first one is "WSSS".
What you need is:
std::string s="WSSS";
string s[] = {"Hello"} is an array of strings (well, of one string).
If you iterate over it, or index into it s[0] is "Hello".
Whereas
string s{"Hello"} is one string, which is made up of characters.
If you iterate over it, or index into it s[0], you will get 'H'.
To pre-empt all the other things that are going to go wrong when the string versus character problem is sorted, lets move the return 0; from the middle of the for loop.
Then let's think about what happens if the number n entered is larger than the length of the string:
int n;
cin>>n; //<- no reason to assume this will be s.length (0 or less) or even positive
string s{"WSSS"}; //one string is probably enough
int i ;
for(i=0;i<n;i++)
{
if( s[i] == 'W' ) //ARGGGGGGG may have gone beyond the end of s
{
In fact, let's just drop that for now and come back to it later. And let's use a range based for loop...
#include<iostream>
#include<string>
using namespace std;
int main()
{
double v_w = 25, v_s = 25, d_w = 25, d_s = 25;
string s{ "WSSS" };
for (auto && c : s)
{
if (c == 'W')
{
v_w += 50;
d_w = d_w + (v_w / 2);
d_s = d_s + (v_s / 2);
cout << "2 \n";
}
}
cout << d_w << '\n' << d_s << '\n'; //<- removed endl just because...
return 0;
}
s is an array of strings in this case it has only element:
string s[] = {"WSSS"};
so writing s[2]; // is Undefined behavior
your code will produce a UB if the user enters n greater than the number of elements in s:
n = 4;
for(i = 0; i < n; i++) // s[3] will be used which causes UB
{
if( s[i] == 'W' ) // s[i] is a string not just a single char
{
}
}
also as long as s is an array of strings then to check its elements check them as strings not just single chars:
if( s[i] == "W" ) // not if( s[i] == 'W' )
I think you wanted a single string:
string s = {"WSSS"};
because maybe you are accustomed to add the subscript operator to character strings:
char s[] = {"WSSS"};
if so then the condition above is correct:
if( s[i] == 'W' )

producing all anagrams in a string c++

I saw this problem online, and I was trying to solve it in C++. I have the following algorithm:
char permutations( const char* word ){
int size = strlen( word );
if( size <= 1 ){
return word;
}
else{
string output = word[ 0 ];
for( int i = 0; i < size; i++ ){
output += permutations( word );
cout << output << endl;
output = word[ i ];
}
}
return "";
}
For example, if I have abc as my input, I want to display abc, acb, bac, bca, cab, cba.
So, what I'm trying to do is
'abc' => 'a' + 'bc' => 'a' + 'b' + 'c'
=> 'a' + 'c' + 'b'
so I need o pass a word less char every function call.
Could someone please help how to do it?
I suggest doing it using the algorithm header library in C++, much easier; and as a function can be written like this:
void anagram(string input){
sort(input.begin(), input.end());
do
cout << input << endl;
while(next_permutation(input.begin(), input.end()));
}
However since you want it without the STL, you can do it like so:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void swap (char *x, char *y)
{
char ch = *x;
*x = *y;
*y = ch;
};
void permutate_(char* str, size_t index )
{
size_t i = 0;
size_t slen = strlen(str);
char lastChar = 0;
if (index == slen )
{
puts(str);
return;
}
for (i = index; i < slen; i++ )
{
if (lastChar == str[i])
continue;
else
lastChar = str[i];
swap(str+index, str+i);
permutate_(str, index + 1);
swap(str+index, str+i);
}
}
// pretty lame, but effective, comparitor for determining winner
static int cmpch(const void * a, const void * b)
{
return ( *(char*)a - *(char*)b );
}
// loader for real permutor
void permutate(char* str)
{
qsort(str, strlen(str), sizeof(str[0]), cmpch);
permutate_(str, 0);
}
Which you can call by sending it a sorted array of characters,
permutate("Hello World");
The non-STL approach was gotten from here.
The STL is wonderful:
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
void permutations(const char *word) {
string s = word;
sort(s.begin(), s.end());
cout << s << endl;
while(next_permutation(s.begin(), s.end()))
cout << s << endl;
}
int main() {
permutations("abc");
return 0;
}
Now, next_permutation can be implemented quite simply. From the end of the string, iterate backwards until you find an element x which is less than the next element. Swap x with the next value larger than x in the remainder of the string, and reverse the elements coming afterwards. So, abcd becomes abdc since c < d; cdba becomes dabc since c < d and we flip the last three letters of dcba; bdca becomes cabd because b < d and we swap b for c.

Strange output after reading from a file

Using this code, the following execution yields strange results:
C 100
R
W
The text file's first line defines the number of elements to read from it, and it contains a few values under 15, but every time I run this, the first value in my array is always printed out as 87 (the ASCII value for 'W'). If I change the 'W' functionality to 'X', then the first result in the array is 88.
#include <iostream>
#include <fstream>
using namespace std;
int arrayLength;
class ELEMENT
{
public:
int key;
};
class HEAP
{
public:
int capacity;
int size;
ELEMENT H [];
};
HEAP initialize(int n)
{
HEAP h;
h.capacity = n;
h.size = 0;
return h;
}
void buildHeap(HEAP &h, ELEMENT *a)
{
h.size = arrayLength;
for (int i = 1; i <= arrayLength; i++)
{
h.H[i] = a[i];
}
for (int i = h.size/2; i >= 1; i--)
{
// HEAPIFY HERE
}
}
void printHeap(HEAP &h)
{
cout << "Capacity:\t" << h.capacity << endl;
cout << "Size:\t\t" << h.size << endl;
cout << "|";
for (int i = 1; i <= h.size; i++)
{
cout << " ";
cout << h.H[i].key << " |";
}
cout << endl;
}
int main()
{
char c;
int val;
HEAP h;
while (c != 'S')
{
cin >> c;
switch (c)
{
case 'S':
break;
case 'C':
cin >> val;
h = initialize(val);
break;
case 'W':
printHeap(h);
break;
case 'R':
{
ifstream infile;
infile.open("HEAPinput.txt");
infile >> arrayLength;
ELEMENT* a = new ELEMENT[arrayLength];
for (int i = 1; i <= arrayLength; i++)
infile >> a[i].key;
infile.close();
buildHeap(h, a);
}
break;
}
}
return 0;
}
It is being compiled using g++ on a Unix server.
EDIT:
To clarify:
With a text file with the following contents (space = new line):
12 9 10 11 12 8 7 6 5 4 3 2 1
The output is:
Capacity: 100
Size: 12
| 87 | 10 | 11 | 12 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 |
So it's working except for that first element.
Whatever you think
ELEMENT H [];
is doing, it probably isn't. C++ does not support dynamic arrays - you need to use the std::vector class.
And BTW, C++ by convention uses UPPERCASE to name pre-processor macros and constants. You should use mixed case to name your classes.
In addition to the wrong use of arrays: it would not be a bad idea to make initialize(), buildHeap(), and printHeap() member functions of heap.
It might be because when you say
cout << h.H[i].key <<
H[] is an array of ELEMENTs and the key is an int. If key was a char or cast to char in the cout statement, you'll see the char representation of the int.
What Neil said. Also, arrays in C++ are zero-based. So for example your loop in main():
for (int i = 1; i <= arrayLength; i++)
Should probably be:
for (int i = 0; i < arrayLength; i++)
It could be that the algorithm for binary heap construction just happens to be simpler to implement if you use one-based arrays -- in that case, you'll need to allocate enough space:
ELEMENT* a = new ELEMENT[arrayLength + 1]; // Note the "+ 1"
Currently, the last loop iteration is writing past the end of the array.