Find all Palindromes in a String Using C - c

I am trying to use C to print all Palindromes in a string and return the total number.
My code is returning all sorts of substrings which are not palindromes and printing blanks.
I am off by at least one in my printf statement formatting, but also, in my array element comparisons, it is working the opposite as I intended.
Can anyone see where I am going wrong?
Here is my code:
#include<stdio.h>
#include<string.h>
char x[1000];
void getString(char *n)
{
printf("\nPlease enter your string: ");
scanf("%s", n);
}
int findPals(char *s)
{
int length = strlen(s);
int numPals = 0;
//find odd palindromes
for(int i = 0; i < length; i++)
{
for(int j = 0; j + i < length && i - j >= 0; j++)
{
if(s[i + j] != s[i - j])
continue;
else
{
numPals++;
printf("%.*s\n", (j - i),s + i);
}
}
}
//find even palindromes
for(int i = 0; i < length; i++)
{
for(int j = 0; j + i + 1 < length && i - j >= 0; j++)
{
if(s[i + j + 1] != s[i - j])
continue;
else
{
numPals++;
printf("%.*s\n", (j - i),s + i);
}
}
}
return numPals;
}
int main()
{
char inStr[1000];
int totalPals;
getString(inStr);
totalPals = findPals(inStr);
printf("I found %d palindromes.\n", totalPals);
return 0;
}

There are only 2 small corrections required in your code (given below) other than that everything is fine:-
1.Continue statement in the array checking should be changed to break:
for(int i = 0; i < length; i++)
{
for(int j = 0; j + i < length && i - j >= 0; j++)
{
if(s[i + j] != s[i - j])
break; // continue statement has been changed to break;
else
{
numPals++;
printf(".*s\n",(2*j)+1,&s[i-j]); // The length of the string has been modified
}
}
}
The string length in printf is incorrect.
For odd section use:
printf(".*s\n",(2*j)+1,&s[i-j]);
And for even section use:
printf(".*s\n",(2*j)+2,&s[i-j]);

Thanks for the help. Here is my final program.
#include<stdio.h>
#include<string.h>
char x[1000];
void getString(char *n)
{
printf("\nPlease enter your string: ");
scanf("%s", n);
}
int findPals(char *s)
{
int length = strlen(s);
int numPals = 0;
//find odd palindromes
for(int i = 0; i < length; i++)
{
for(int j = 0; j + i < length && i - j >= 0; j++)
{
if(s[i + j] != s[i - j])
break;
else
{
if ((j + j) > 1)
{
numPals++;
printf("%.*s\n", ((2 * j) + 1), &s[i - j]);
}
}
}
}
//find even palindromes
for(int i = 0; i < length; i++)
{
for(int j = 0; j + i + 1 < length && i - j >= 0; j++)
{
if(s[i + j + 1] != s[i - j])
break;
else
{
if ((j + j) > 1)
{
numPals++;
printf("%.*s\n", ((2 * j) + 2), &s[i - j]);
}
}
}
}
return numPals;
}
int main()
{
char inStr[1000];
int totalPals;
getString(inStr);
totalPals = findPals(inStr);
printf("I found %d palindromes.\n", totalPals);
return 0;
}

Related

Printing a christmas tree using stars and dots in C

I'm trying to write a program that prints out a christmas tree that looks like this:
The user inputs the height, in this example the height is 6. If the input is in range from 0 to 3, the height should be 3, because otherwise it's not printable, and if the input is less than 0, the program should terminate.
My code for some odd reason is infinitely printing the 'Input height'. Where is the error?
Here's my code snippet:
#include <stdio.h>
void main(){
int i, j, n, s;
while (1){
printf("Input height: ");
scanf("%d", &n);
if (n < 0) break;
if (n == 0 || n == 1 || n == 2 || n == 3)
s == 3;
else
s == n;
for (i = 0; i < s; i++){
for (j = 0; j < 2*s - 1; j++){
if (j > s - (i - 1) && j < (s + (i - 1)) - 1)
printf("*.");
if (j == s + (i - 1))
printf("*");
else
printf(" ");
}
printf("\n");
}
for (j = 0; j < 2*s - 1; j++){
if (j == s - 1 || j == s || j == s + 1)
printf("*");
else
printf(" ");
}
}
}
The lines: s == 3; and s == n; do absolutely nothing.
== is a comparison, not an assignment.
Here is much better code:
#include <stdio.h>
int main(void) {
int n = 8;
char row[2*n];
for( int i=0; i<2*n-1; i+=2 )
{
strcpy(row+i, "*.");
}
for(int i=0; i<n; ++i)
{
printf("%*.*s\n", n+i+1, 2*i+1, row);
}
printf("%*s\n", n+2, "***");
return 0;
}
Result:
Success #stdin #stdout 0s 5464KB
*
*.*
*.*.*
*.*.*.*
*.*.*.*.*
*.*.*.*.*.*
*.*.*.*.*.*.*
*.*.*.*.*.*.*.*
***
With a little creativity, I made the program even shorter with only a single for-loop.
#include <stdio.h>
int main(void) {
int n = 8;
char row[2*n];
strcpy(row, "*");
for( int i=0; i<n; ++i )
{
printf("%*s\n", n+i, row);
strcat(row, ".*");
}
printf("%*s\n", n+1, "***");
return 0;
}
As mentioned by others there are some issues with you mixing up == and =.
I will be posting a version that prints out the christmas tree but leaves out the . that you also want to include, as you should be able to finish it yourself.
#include <stdio.h>
int main()
{
int i, j, n, s;
while (1)
{
printf("Input height: ");
scanf("%d", &n);
// if input is negative, exit
if (n < 0)
{
break;
}
// if input is 0,1,2 or 3 change to 3
if (n == 0 || n == 1 || n == 2 || n == 3)
{
s = 3;
}
else
{
s = n;
}
// loop through each row
for (i = 0; i < s; i++)
{
// loop through each column
for (j = 0; j < 2 * s - 1; j++)
{
// if column is within the tree print a star
if (j >= s - i - 1 && j <= s + i - 1)
{
printf("*");
}
else
{
printf(" ");
}
}
printf("\n");
}
// print base of tree
for (j = 0; j < 2 * s - 2; j++)
{
// if column is part of base print star
if (j == s - 2 || j == s - 1 || j == s)
{
printf("*");
}
else
{
printf(" ");
}
}
printf("\n");
}
return 0;
}
A simple solution:
#include <stdio.h>
int main(){
int i=0, j=0, n=0, s=0;
while (1){
printf("Input height: ");
scanf("%d", &n);
printf("\n");
if (n < 0) break;
s = (n <= 3) ? 3 : n;
for (i=0; i < s; ++i){ // rows
for (j=0; j < s-i; ++j) // white spaces
printf(" ");
for (int k=0; k < i; ++k) // *.
printf("*.");
printf("*\n"); // always, unique or last *
}
for (i=0; i < s-1 ; ++i)
printf(" ");
printf("***\n\n");
}
return 0;
}

How to successfully take a step back and preserve the shape? C programming - loops

I wrote this code, but I have one error that I can't fix, the problem is that the code works well but actually what my program prints to the number n: 3 should be to n: 2 you can see it in the picture. when 5 is actually 4 etc... When I fix the loops I move the look of the lines and then it's no longer a diamond.
#include <stdio.h>
int main() {
int i, j, n;
printf("n: ");
scanf("%d", &n);
for (j = 1; j < n; j++) {
printf(" ");
}
printf("+");
printf(" \n");
for (i = 2; i < n; i++) {
for (j = 1; j <= n - 1; j++) {
if ((i + j) == (n + 1))
printf("/");
else
printf(" ");
}
for (j = 1; j < n; j++) {
if (i == j)
printf("\\");
else
printf(" ");
}
printf("\n");
}
for (i = 2; i < n; i++) {
for (j = 1; j < n; j++) {
if (i == j)
printf("\\");
else
printf(" ");
}
for (j = 1; j <= n - 1; j++) {
if ((i + j) == (n + 1))
printf("/");
else
printf(" ");
}
printf("\n");
}
for (j = 1; j < n; j++) {
printf(" ");
}
printf("+");
return 0;
}
A quick and dirty fix is adding 1 to n after the scanf("%d", &n);
Here is a modified version taking advantage of the printf width feature:
#include <stdio.h>
int main() {
int i, n;
printf("n: ");
if (scanf("%d", &n) != 1)
return 1;
printf("%*s\n", n, "+");
for (i = 1; i < n; i++) {
printf("%*s%*s\n", n - i, "/", i * 2, "\\");
}
for (i = 1; i < n; i++) {
printf("%*s%*s\n", i, "\\", (n - i) * 2, "/");
}
printf("%*s\n", n, "+");
return 0;
}
It seems that just adding 1 to n would solve your problem.

What is my C code not printing # in staircase pattern, this is from hackerrank, I did not pass all test cases, but i can't point out why?

Write a program that prints a staircase of size n.
I did not pass through all the test cases and don't understand where I made mistake.
This is my code:
void staircase(int n) {
char a[n][n];
for(int i = 0; i < n; i++) {
for(int j = 0; j < n; j++) {
if((i + j) > ((n / 2) + 1)) {
a[i][j] = '#';
printf("%c", a[i][j]);
} else {
printf(" ");
}
}
printf("\n");
}
}
Given Input
6
Expected Output
#
##
###
####
#####
######
Explanation:
The staircase is right-aligned, composed of # symbols and spaces, and has a height and width of n=6.
The problem is in the condition
if((i + j) > ((n / 2) + 1))
It should be
if(j >= n - i - 1) // or if(i + j >= n - 1)
To make this easier, I would create a helper function. Also, there's no need for the VLA a[n][n] that you don't even use for anything.
void repeat_char(int x, char ch) {
for(int i=0; i < x; ++i) putchar(ch);
}
void staircase(int n) {
for(int i = 1; i <= n; ++i) {
repeat_char(n - i, ' '); // or printf("%*s", n - i, "");
repeat_char(i, '#');
putchar('\n');
}
}
You do not need your a variable to do what you need. Here is a sample achieving what you want:
void staircase(unsigned n)
{
for (unsigned i = 0; i < n; ++i) {
for (unsigned j = 0; j < (n - i - 1); ++j)
printf(" ");
for (unsigned j = 0; j < (i + 1); ++j)
printf("#");
printf("\n");
}
}
The first loop is meant to cover every lines, then within it you make a loop which handles the spaces before the actual # symbols, and finally you make the loop handling the displaying of the symbols.
There is a much easier way of going about this than what you are trying to do:
#include <malloc.h>
#include <stdio.h>
#include <stdlib.h>
int main(void) {
const int n = 6;
char* str = malloc(sizeof(*str)*(n + 1));
if (str == NULL) {
printf("Somthing wrong with memory!\n");
return 1;
}
memset(str, ' ', n);
str[n] = '\0';
for(int i = n - 1; i > -1; i--) {
str[i] = '#';
puts(str); //or maybe printf who cares
}
free(str);
return 0;
}

Wrong output when printing a tent shape with stars

I'm trying to print out a hollow, open tent shape using asterisk stars "*". The code uses two for loops, the first for the rows, and the other for the columns.
following is my code:
void printTent(int n)
{
int j = 1;
int i = 1;
if (n == 1) {
printf("*");
} else {
for(i = 0; i < n; i++) {
for(j = 0; j < n; j++) {
printf(" ");
}
if(j == n) {
printf("*");
for(j = 1; j <= n; j++) {
printf(" ");
}
}
}
}
}
int main()
{
printTent(4);
}
Output obtained:
* * * *
Desired output:
*
* *
* *
* *
I don't think you will need that
if (n == 1) {
printf("*");
}
We can take care of that in what you've written in the else part.
For n=4, the number of spaces to be printed at the start of each line is 3, 2, 1 & 0.
You seem to be trying to accomplish that with your first inner loop. But
for(j = 0; j < n; j++) {
printf(" ");
}
will always print n spaces. We need to reduce the number of spaces printed by 1 on each iteration of the outer loop.
Coming to your second loop,
for(j = 1; j <= n; j++) {
printf(" ");
}
This has a similar problem only difference being the incrementation of the number of spaces printed.
Try something like this
void printTentNMMod(int n)
{
int j;
int i;
for(i = 0; i < n; i++) {
for(j = i; j < n; j++) {
printf(" ");
}
printf("*");
if(i!=0)
{
for(j=0; j<2*(i-1)+1; ++j)
{
printf(" ");
}
printf("*");
}
printf("\n");
}
}
Also, you could shorten this to
void printTent(int n)
{
int j;
int i;
for(i = 0; i < n; i++) {
printf("%*c", n-i, '*');
if(i!=0)
{
printf("%*c", 2*i, '*');
}
printf("\n");
}
}
The * in %*c will set the number of places occupied by the character printed by the %c.
I've finished it and I have written annotation.
void printTent(int n)
{
int j = 1;
int i = 1;
if (n == 1) {
printf("*");
}
else {
for (i = 0; i < n; i++) {
for (j = 0; j < n -i; j++) {// you should use n-i instead of n because the number of spaces is decreasing
printf(" ");
}
if (j == n-i) { //
printf("*");
for (j = 1; j <= i * 2 - 1; j++)//this loop outputs spaces between two "*"
{
printf(" ");
}
if (i != 0)//the first line only needs one "*"
printf("*");
printf("\n"); //Line breaks
}
}
}
}
Another way.
#include <stdio.h>
int main() {
int i, j;
int height = 5;
for(i = height; i > 0; i--) {
for(j = 1; j < height * 2; j++) {
if(j == i || j == height * 2 - i)
printf("*");
else
printf(" ");
}
puts("");
}
return 0;
}
Output
*
* *
* *
* *
* *

Creating a matrix and free() problems - c

it seems i have some problems in my code. the first one is that i cant use the free function correctly:"heap corruption detected".
in the second part of my work i wanted to create a matrix:it puts a red mark under the j and then the compiler says that subscript requires array and pointer type.
i only wanted to create a two dimension matrix.
thanks for your help!!!
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include <math.h>
void main()
{
char *word[1000] = { 0 }, letter[1000], *temparr, *originalarr;
int i = 0, j = 0, counter = 0, k = 0, w = 0, anagram = 0, size = 0, *mat;
for (i = 0; letter[i] != '\n'; i++)
{
letter[i] = getchar();
counter++;
if (letter[i] == ' ' || letter[i] == '\n')
{
if (letter[i] == 10)
{
letter[i] = 0;
word[j] = malloc(sizeof(char*)*(counter - 1));
strcpy_s(word[j], (counter - 1) * sizeof(char*), &letter[i - (--counter)]);
break;
}
if (letter[i - 1] == ' ')
continue;
letter[i] = '\0';
word[j] = malloc(sizeof(char*)*counter);
strcpy_s(word[j], (counter - 1) * sizeof(char*), &letter[i - (--counter)]);
letter[i] = ' ';
counter = 0;
j++;
}
}
while (j > 0)
{
printf_s("%s ", word[j--]);
if (j == 0)
printf_s("%s", word[j]);
}
for (j = 0; word[j] != 0; j++)
{
originalarr = (char*)malloc((sizeof(char) * strlen(word[j])));
strcpy_s(originalarr, strlen(word[j]) + 1, word[j]);
for (i = 0; word[i] != 0; i++)
{
temparr = (char*)malloc((sizeof(char) * strlen(word[i])));
strcpy_s(temparr, strlen(word[i]) + 1, word[i]);
counter = 0;
if (strlen(originalarr) != strlen(temparr))
continue;
for (k = 0; originalarr[k] != 0; k++)
{
for (w = 0; w < strlen(temparr); w++)
{
printf_s("temparr - %c ", temparr[w]);
printf_s("original - %c\n", originalarr[k]);
if (originalarr[k] == temparr[w])
{
temparr[w] = '0';//problem, but cant be equal to 0
counter++;
printf_s("counter- %d\n", counter);
}
}
}
if (counter == strlen(originalarr))
anagram++;
free(temparr);//problem
}
}
k = 0;
size = ceil(sqrt(strlen(letter)));
mat = (int*)malloc((sizeof(int) * size));
for (i = 0; i < size; i++)
{
mat[i] = (int)malloc((sizeof(int) * size));
for (j = 0; j < size; j++)
mat[i][j] = '\0';
}
for (i = 0; i < size; i++)
for (j = 0; j < size; j++)
{
mat[i][j] = letter[k];
k++;
}
}
For the second part of your question you need to declare a pointer to a pointermat instead of a simple pointer as you have done. Then allocate as shown.
int ** mat;
mat = malloc((sizeof(int*) * size));
for (i=0; i<size; i++)
mat[i] = malloc( sizeof(int) * size));
You can use this array mat as a 2D array mat[i][j]

Resources