Disadvantage when exercising with recursion - c

I'm doing the following exercise:
Example:
"abcde"
Output:
a
b
c
d
e
Here the template code:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
char* diag(char* str, char* r)
{
/* Write code */
r[0] = '\0';
return r;
}
int main (void)
{
char str [] = "abcde";
int n = strlen(str);
char* r = malloc(n * n + 1);
r = diag(str, r);
puts(r);
free(r);
return 0;
}
Someone could guide me a little the function must be recursive, not know how to start

The trick with recursion is to consider what condition you need to make the necessary changes. You've already gotten everything set up, now think about how you would increment the array so that you can assign the letters to the diagonal positions (there's a pattern). There also needs to be a terminating case.

You can use this:
printDiagonally(char* s, int low, int high){
if(low < high){
int i;
for(i=0 ; i<low; i++)
printf(" ");
printf("%c\n", *s);
printDiagonally(++s, low+1, high);
}
}

Related

My string assigning correctly into my char array (C)

#include <stdio.h>
#include <string.h>
void mirror(char c[])
{
int l = strlen(c);
char s;
for (int i = 0; i < l/2;i++)
{
s = c[i];
c[i] = c[l-i-1];
c[l-i-1] = s;
}
}
void decimal_to_binary(unsigned int n,char binary_res[]){
char r = n%2;
unsigned int q = (n - r)/2;
int i = 0;
while (q != 0)
{
i++;
r = n%2;
q = (n - r)/2;
n = q;
printf("%d\n",q);
binary_res[i] = r+'0';
}
mirror(binary_res);
}
int main(){
int n = 34; char res[10];
printf("%d\n",n);
decimal_to_binary(n,res);
printf("%s\n",res);
return 0;
}
I wrote this code which is really simple and I wanted it to convert a decimal to a binary through some repeated divisions. But there is a problem I don't understand because if I remove the +'0' when I assign the rest to the ith value in the result array, it displays nothing when I call it printf but when I add the +'0' it adds some weird characters. But I think i cmes from the fact that it is not ascii encording but UTF-8 so 0 hasn't a value of 0 but of 48. But the 0 value is for a null string so '' but when I add it to the r with +'' it shows nothing !
I don't understand what I am doing wrong here but I think there is multiple things I do wrong.
Thanks in advance !
I see three bugs:
You use i++ too soon. You place the first bit at binary_res[1] when it should be placed at binary_res[0].
You don't add a terminating NUL to binary_res.
You don't modify the binary_res at all when the n parameter is zero.
I check this statement '(n%2)' with loop statement and I fill the array, then I use procedure mirror to reverse the string like this:
#include <stdio.h>
#include <string.h>
void mirror(char c[],int l);
void decimal_to_binary(unsigned int n,char binary_res[]);
int main()
{
int n = 40; char res[10];
printf("%d\n",n);
decimal_to_binary(n,res);
printf("The binary form of number %d is %s\n",n,res);
return 0;
}
void mirror(char c[],int l)
{
char s;
for (int i = 0; i < l/2;i++)
{
s = c[i];
c[i] = c[l-i-1];
c[l-i-1] = s;
}
}
void decimal_to_binary(unsigned int n,char binary_res[])
{
int i = 0;
while (n != 0)
{
switch(n%2)
{
case 1:
{
binary_res[i]='1';
i++;
}break;
case 0:
{
binary_res[i]='0';
i++;
}break;
}
n = n/2;
}
binary_res[i]='\0';
mirror(binary_res,i);
}

printing a string in a specific format

So I created have a program that basically prints any given string like that:
Example:
Input:
Hello
Output:
Hello
ello
llo
lo
o
The problem is that for some reason if I use icdiff and compare my output with that output in a text file it says that I am missing elements and that I have more spaces than it should.
Icdiff output:
Hello
ello
llo
As you can see this is clearly different than what I have, but if I test it on the terminal I get the expected output.
Program:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void print_array(char *p, int tamanho) {
int i;
for (i = 0; i < tamanho; i++) {
printf("%c", p[i]);
}
printf("\n");
}
void nova_str(char *p, char *s, int inicio, int tamanho) {
int i;
for (i = inicio; i < tamanho; i++) {
s[i] = p[i];
}
}
int main() {
char p[1001];
int len;
int j;
scanf("%s", p);
len = strlen(p);
print_array(p, len);
for (j = 1; j < len; j++) {
char *np = (char *)calloc(len + 1, sizeof(char));
nova_str(p, np, j, len);
print_array(np, len);
free(np);
}
return 0;
}
Really any help would be appreciated.
The problem is in the nova_str function: you use the same index into the source and the destination, so the destination array still starts with initcio null bytes which are printed by the print_array and appear as spaces on your system. The array is initialized to all bits zero by calloc().
Here is a much simpler version:
#include <stdio.h>
int main() {
char p[1001];
if (scanf("%1000s", p) == 1) {
for (int i = 0; p[i] != '\0'; i++) {
/* print the word starting at offset i */
printf("%s\n", p + i);
}
}
return 0;
}
calloc() is setting the memory to zero, so you are printing null characters in print_array() when it should be spaces. Replace those null characters with spaces there and this is solved, although I think there is an easier way to achieve what you are trying to do.
If you don't want the letters to be prepended by spaces, add an if (p[i] == '\0') continue; before printf() in print_array() instead.

Qsort not sorting char * array

I've got a problem, which is, qsort sometimes sorts stuff, sometimes it doesn't. Here's my code
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
static int compare (const void * a, const void * b)
{
return strcmp (*(const char **) a, *(const char **) b);
}
int main (){
int ile = 0;
scanf("%d", &ile);
const char * slowa[ile];
for(int j = 0; j <= ile; j++){
char string[30];
gets(string);
char * toAdd = strdup(string);
slowa[j] = toAdd;
}
qsort (slowa, ile, sizeof (const char *), compare);
for (int i = 0; i <= ile; i++) {
printf ("%s\n",slowa[i]);
}
return 0;
}
It works well with example { ccc,bbb,aaa } but does not work for the example { afdg ,sspade , trekk, bbre, lol}
The scanf has left a newline in the input buffer, which is read by the first gets.
The two loops iterate once too many, indexing the array beyond its bounds. I guess you did that to get the correct number of apparent inputs.
So clear the input before the first loop, perhaps with a dummy string read, and correct the loop control.
Also please note that gets() is now obsolete.

Reverse string with external function

I recently started a course in Programming in C. I got an assignment where I'm going to make an external function with this declaration:
void reverse(char *array, int numberOfChars)
My code looks like this at the moment. The problem is that the code will just reverse the first half of the word, and keep the second half as normal.
#include <stdio.h>
#include <string.h>
void reverse(char *array, int numberOfChars) {
int i = 0;
int j = 0;
for (i = numberOfChars - 1; i >= 0; i--) {
array[j] = array[i];
j = j + 1;
}
}
#define NAMESIZE 100
int main() {
char word[NAMESIZE];
int length;
printf("Enter a word: ");
scanf("%s", word);
getchar();
length = strlen(word);
reverse(word, length);
printf("%s\n", word);
}
Even when you use an intermediate variable, your code will reverse the string twice, leaving it as it was. A small change to the code compares i with j as well as using a temporary variable to do the swap.
int i, j = 0;
char temp;
for(i = numberOfChars-1; i > j; i--){
temp = array[j];
array[j] = array[i];
array[i] = temp;
j = j + 1;
}
Your function has a classic problem: you are reversing the string in place. You overwrite the characters at the start of the string with the characters from the end. The initial characters are lost by the time you reach the mid point. You should instead swap the characters from both ends and stop at the mid point.
You are going to need a secondary char array to reverse the string.Try like this:
#include <stdio.h>
#include <string.h>
#define NAMESIZE 100
void reverse(char *arr,int numberOfChars);
int main()
{
char word[NAMESIZE];
printf("Enter a word: ");
scanf("%s",word);
getchar();
size_t length=strlen(word);
reverse(word,length);
printf("%s\n",word);
}
void reverse(char *arr,int numberOfChars)
{
char buffer[NAMESIZE];
int j = 0,i = numberOfChars;
while( i-- )
buffer[j++] = arr[i];
buffer[j] = '\0';
strcpy(arr,buffer);
}
A simple way to prevent overwriting your array is to copy your array into a temporary one and write the reversed readed temporary array into the other.
If you want to have an unknown array size at compilation to reverse, I recommend you to use a heap array (see man malloc) instead of stack one to prevent segmentation fault if numberOfChars is too hight.

Palindrome Program

I've created a program that takes an inputted string and outputs the string backwards. I've created a function that counts the number of characters in a string. With that information, I've created another function that puts the first character of the original array at the end of the new array. Thus, when the loop in the function has finished, the new array contains the letters of the original array but backwards. I'm running into some difficulty however. I'm still wary of character arrays and I'm not sure if I'm using them correctly. Could someone help me out?
#include <stdio.h>
#define MAXLINE 1000
char backward(char str[], int count)
int count(char str[])
int main() {
char orig[MAXLINE];
int c;
scanf("%s", orig);
c = count(orig);
printf("%s", backward(orig, c));
return 0;
}
char backward(char str[], int count) {
char back[MAXLINE];
int i;
for(i = 0; i <= count; ++i) {
back[count] = str[i];
--count;
return back;
}
int count(char str[]) {
int i;
for (i = 0; str[i] != '\0'; ++i)
;
return i;
}
Edit: Input: Let's say "minivan". Expected output would be "navinim". There's no actual output yet. I'm getting this error:
palindrome.c:8: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘int’
The error you're getting is because your prototypes are wrong:
#include <stdio.h>
#define MAXLINE 1000
char backward(char str[], int count) /* missing ; */
int count(char str[]) /* missing ; */
int main() {
You should also consider replacing count() with strlen(3) from the <string.h> header file. The standard library is full of utilities that have been debugged and known to work well -- it is worth using them. (Yes, there's educational value in re-implementing them. But in that case, be prepared to test with a variety of corner cases.)
Your code probably won't compile because you missed a closing brace in backward().
char backward(char str[], int count) {
char back[MAXLINE];
int i;
for(i = 0; i <= count; ++i) {
back[count] = str[i];
--count;
/** You should add a } character here! **/
return back;
}
MAJOR EDIT 1:
I tried to compile your code and there were lots of things wrong with it. Here is working code:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define MAXLINE 1000
char * backward(char * str);
int main() {
char orig[MAXLINE];
int c;
scanf("%s", orig);
printf("%s\n", backward(orig));
return 0;
}
char * backward(char * str) {
int count = strlen(str);
char * back = malloc(MAXLINE);
int i;
for(i = 0; i < count; i++)
{
back[count-i-1] = str[i];
}
back[count] = 0; // Add the null termination character.
return back;
}
When I run this code and enter "abcde", it outputs "edcba". Let me know if you have any specific questions about how this works. I got rid of your count() function because it is a duplicate of strlen(), and I moved the call to strlen() inside the backward() to make the interface to the backward() function simpler.
Another thing that made your code fail is that you were decrementing count inside the for loop, which would cause your for loop to terminate earlier than you wanted it to.
This line has an off by one mistake:
back[count] = str[i];
count is not the last character of the string, it's the '\0' character.
Also you are returning a stack variable - this is not going to work.
You should reverse the string in place:
for(i = 0; i <= count; ++i) {
--count;
char tmp = str[i];
str[i] = str[count];
str[count] = tmp;
}
You can then return str.
You program have lot of errors. Firstly you have missed out semicolons(;) while declaring the prototypes for backward and count. Then you haven't closed the for loop in backward function with ending braces(}).
But the biggest three problems are
1. You have defined backward function as a char data type but you are returning a pointer to the array of char data type
2. You are accessing back[count] instead of back[count-1]. Suppose the string is minivan. The count will hold 7. the last character is at 6th position not 7th because in array subscripts starts with 0 not 1. And back[count] will point to null character i.e '\0'
3. You are incrementing i and decrementing count and checking i<=count. This will process your string only till mid of it.
Although the right program has been posted by David Greyson, but since he have removed the count function and introduced the strlen and malloc function, I am posting your program again by just correcting your algorithm
#include <stdio.h>
#define MAXLINE 1000
char *backward(char str[], int count);
int count(char str[]);
int main() {
char orig[MAXLINE];
int c;
scanf("%s", orig);
c = count(orig);
printf("%s", backward(orig, c));
return 0;
}
char *backward(char str[], int count) {
char back[MAXLINE];
int i;
for(i = 0; i < count; ++i) {
back[count-i-1] = str[i];
}
back[i] = '\0';
return back;
}
int count(char str[]) {
int i;
for (i = 0; str[i] != '\0'; ++i)
;
return i;
}
You can create a character pointer then add length of string to this pointer, it should likely char *reverse = (char *)name, then add reverse = reverse + strlen(name) -1.
Then you can use while loop through through the start of string. The whole code looks,
void main(void)
{
char *name = "Kernel";
char *reverse = (char *)name;
reverse = reverse + strlen(name) - 1;
while(*reverse)
printf("%c", *reverse);
}
#include<Stdio.h>
#include<string.h>
int main()
{
size_t i,j;
char arr[10]={'\0'};//orignal array
char arr2[10]={'\0'};//it's reverse to be
gets(arr);//prompt
strncpy(arr2,arr,10);//copy
strrev(arr2);
if(strncmp(arr,arr2)==0)
printf("plaindrom");
return 0;
}

Resources