Reverse(s) function [closed] - c

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 7 years ago.
Improve this question
(I can't speak English very well, so I'm sorry for my mistakes)
I'm learning C language, (I'm reading The C Programming Language, second edition). I can't complete exercise 4-13:
Write a recursive version of the function reverse (s), which
reverses the string s in place.
I have to create this function without using pointers or things that I haven't studied yet.
This is my code:
void reverse(char s[])
{
int c;
static int i, k;
i = 0;
k = 0;
if ((c = s[i]) != '\0')
{
i++;
reverse(s);
}
if (c != '\0')
s[k++] = c;
}
but it doesn't work. Could you help me, please?

You are resetting values of "i" and "j" to zero in the function.
static variables are initialized only once in the declaration statement.
Initialize the variables like this :
static int i=0, k=0;
You can also do away with initializing static variables to 0 as it would be done automatically. But it is a good programming practice to initialize variables during declaration.

See #vikas answer, however, that will work only one time as to reverse a second string, i and k must be reset again. The following does that:
static int i, k;
void reverse(char s[]);
int main(void)
{
char s[]="hello world";
i= k= 0;
reverse(s);
return 0;
}
void reverse(char s[])
{
int c;
if ((c = s[i]) != '\0')
{
i++;
reverse(s);
}
if (c != '\0')
s[k++] = c;
}

Using recursive algorithms in C is a bad idea(with few exceptions,of course) because of the space cost and the poor performance when the compared to the equivalent iterative versions. That said,here's my recursive implementation of reverse(s):
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
static void reverse(char s[],const size_t start,const size_t end);
int main(void)
{
char s[] = "C is a great programming language";
reverse(s,0,strlen(s) - 1);
printf("Reversed string: %s\n",s);
return EXIT_SUCCESS;
}
static void reverse(char s[],const size_t start,const size_t end)
{
if(start < end && NULL != s)
{
char tmp = s[end];
s[end] = s[start];
s[start] = tmp;
reverse(s,start + 1,end - 1);
}
}
PS: sorry for my bad english,i'm not a native speaker.

Related

printing strings with pointer arithmetics [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 1 year ago.
Improve this question
I'm trying to print random words with the use of rand().
I think that I've made a mistake on the pointer arithmetic since I get a weird output.
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
int main ()
{
srand(time(0));
const int randomBit = rand() % 2;
char * sz[] ={"good", "bad"};
switch (randomBit)
{
case 0:
for (char *i=*sz; *i<(sz+3); i++)
{
printf("%c", *i);
}
break;
case 1:
for (char *i=*(sz+3); *i!=0x0; i++)
{
printf("%c", *i);
}
break;
default:
break;
}
return 0;
}
What's my mistake?
Thank you.
Given this declaration ...
char * sz[] ={"good", "bad"};
... this code has undefined behavior:
for (char *i=*(sz+3); *i!=0x0; i++)
The expression *(sz+3) is equivalent to sz[3], but array sz has only two elements, so the maximum index is 1.
Likewise, the expression *sz is equivalent to sz[0]. That one is semantically ok but stylistically poor. Likewise stylistically poor is splitting out two separate cases when you could instead cover both with the same code by using sz[randomBit] to select which string to print.
Furthermore, it is unclear why you are printing character by character. Perhaps that's part of the assignment, but in the real world a programmer would probably write ...
printf("%s", sz[randomBit]);
... instead of that entire switch statement.
Your code is incredibly complicated (and wrong).
What's wrong with this:
int main()
{
srand(time(0));
const int randomBit = rand() % 2;
char* sz[] = { "good", "bad" };
printf("%s\n", sz[randomBit]);
return 0;
}
or if you are not allowed to use the %s format specifier as part of your assignement:
for (char* i = sz[randomBit]; *i != 0; i++)
{
printf("%c", *i); // or putchar(*i);
}

Adding int value to string in C [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 4 years ago.
Improve this question
So I've got a problem with int and string in C.
My task is to write a function that will output the error rate in string.
For example if the string is "aaabbbcccdxm" then the output should be "1/12".
By "error" I mean any letter from n to z, and any letter from a to m is "good".
I thought that I could do it by using a for loop to check every letter in the string, and then if to add value to int error which would be numbers of bad letters, but I don't know how to convert that "int error" value to string with output error value/string dimension. Any ideas?
You can use printf to format your output. I recommend reading the man 3 printf on a linux machine or from google.
Here is what such a program could look like:
#include <stdio.h>
#include <string.h>
int main()
{
const char * input_str = "aaabbbcccdxm";
int size = strlen(input_str);
int error = 0;
for (int i = 0; i < size; ++i)
{
if (input_str[i] >= 'n')
error++;
}
printf("%d/%d\n", error, size);
return 0;
}
size_t errors(const char *str, const char *legal)
{
size_t errcnt = 0;
while(str && *str)
{
errcnt += !strchr(legal, *str++);
}
return errcnt;
}
int main()
{
char *str = "aaabbbcccdxm";
printf("%zu/%zu\n", errors(str,"abcdefghijklm"), strlen(str));
return 0;
}

K&R exercise 2-5,error control may reach end of non-void function c [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
"Write the function any(s1,s2), which returns the first location in the string s1 where any character from the string s2 occurs, or -1 if s1 contains no characters from s2.
When I compile my code, I get "control may reach end of non void function.which part causing the error,here’s my code:
int any(string a,string b){
int i,j;
int c = 0;
for(i=0;i<strlen(a);i++){
for(j=0;j<strlen(b);j++){
if(b[j]==a[i]&&c==0){
c = 1;
return i;
break;
}
}
}
if(c==0)
return -1;
}
You should start to learn to use brackets, this means that if you change this:
if(c==0)
return -1;
To this:
if(c==0){
return -1;
}
You will easy discover that there is no return if C != 0.
Another problem is here:
if(b[j]==a[i]&&c==0){
c = 1;
return i;
break;
}
First you say return i; and then break, really?
Another thing is about strlen which is defined like this:
size_t strlen(const char * str){
const char *s;
for (s = str; *s; ++s) {}
return(s - str);
}
size_t is long unsigned int which means that here:
for(i=0;i<strlen(a);i++)
and here:
for(j=0;j<strlen(b);j++)
You are comparing an int with an long unsigned int.
This means that this line:
int i,j;
should be:
size_t i,j;
or:
long unsigned i,j;
So even if you fix that there are still some casts needed:
int any(string a,string b){
size_t i,j;
int c = 0;
for(i=0;i<strlen(a);i++){
for(j=0;j<strlen(b);j++){
if(b[j]==a[i]&&c==0){
c = 1;
break;
}
}
}
if(c==1){
return (int)i;
}else{
return (int)-1;
}
}
Which means that you should reconsider writing in another way the whole program.
Maybe this will be ok for you:
size_t any(string a,string b){
size_t i,j;
int c = 0;
for(i=0;i<strlen(a);i++){
for(j=0;j<strlen(b);j++){
if(b[j]==a[i]&&c==0){
c = 1;
break;
}
}
}
if(c==1){
return i;
}else{
return 1;
}
}
You're getting the error because the compiler is not smart enough to realize that c == 0 must be true if you get to the test. For the same reason, the test is completely unnecessary, so removing it and just returning -1 at that point will fix the error.
You can simplify greatly by changing to:
int any(char * a, char * b){
int i, j;
for( i = 0; a[i]; ++i ) {
for( j = 0; b[j]; ++j ) {
if( b[j] == a[i] ) {
return i;
}
}
}
return -1;
}
This avoids the redundant test(s), avoids the need for your c variable altogether, and avoids the gratuitous and repeated calls to strlen().
typedefing char * as string is also in rather poor taste.
Probably over the top for this exercise, but by trading some memory efficiency for speed efficiency, you could set up an array as a lookup table and read the characters from b into it, and then step through a until you reach the end or get a match. This would require traversing the characters of b exactly once, and at most one full traversal through a, so you'd get a linear time algorithm rather than the quadratic time one you have now.
For instance:
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
int any(char * a, char * b);
int main(void)
{
printf("'rifle', 'flog': %d\n", any("rifle", "flog"));
printf("'pterodactyl', 'dint': %d\n", any("pterodactyl", "dint"));
printf("'xyzzy', 'fish': %d\n", any("xyzzy", "fish"));
return 0;
}
int any(char * a, char * b)
{
int lookup[CHAR_MAX + 1] = {0};
for ( int i = 0; b[i]; ++i ) {
lookup[b[i]] += 1;
}
for ( int i = 0; a[i]; ++i ) {
if ( lookup[a[i]] ) {
return i;
}
}
return -1;
}
with output:
paul#horus:~/Documents/src/sandbox$ ./any
'rifle', 'flog': 2
'pterodactyl', 'dint': 1
'xyzzy', 'fish': -1
paul#horus:~/Documents/src/sandbox$

Quicksort using single loop [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions concerning problems with code you've written must describe the specific problem — and include valid code to reproduce it — in the question itself. See SSCCE.org for guidance.
Closed 9 years ago.
Improve this question
The quicksort code below is giving incorrect results.Could anybody tell what is wrong?
#include <stdio.h>
#include <stdlib.h>
#define MAX 30
int b[MAX];
void print(int a[],int n)
{
int i;
for(i=0;i<n;i++)
{
printf("%d\t",a[i]);
}
printf("\n");
}
int party(int a[],int p,int q)
{
int pivot=a[p];
int t=a[p];
a[p]=a[q];
a[q]=t;
int i,j,k,store=p;
for(i=p;i<=q-1;i++)
{
if(a[i]<=pivot)
{
t = a[i];
a[i] = a[store];
a[store] = t;store++;}
}
t = a[store];
a[store] = a[q];
a[q] = a[store];
return store;
}
void quicksort(int a[],int p,int q)
{
if(p>=q)
{
return;
}
int r=party(a,p,q);
quicksort(a,p,r-1);
quicksort(a,r+1,q);
}
int main()
{
printf("Enter No. oF elements for sorting.\n");
int i,j,k,n;
scanf("%d",&n);
for(i=0;i<n;i++)
{
printf("Element %d\t",i+1); scanf("%d",&b[i]);
}
print(b,n);
quicksort(b,0,n-1);
print(b,n);
return 0;
}
EDIT: Just spent few minutes and did some basic indentation instead of asking author to do it. I could have put proper variable names but since answerd felt fine.
Buried in that dreadful code formatting you seem to like is this:
t=a[store];a[store]=a[q];a[q]=a[store];
Which to sane people looks like this:
t=a[store];
a[store]=a[q];
a[q]=a[store];
You're setting a[q] to the same value it just was, and not swapping anything. It should read:
t=a[store];
a[store]=a[q];
a[q]=t;
Btw, you don't need both low and high indices, you only need a base array address and a length for this algorithm (and a little pointer math, of course):
static void swap_int(int *a, int *b)
{
int t = *a;
*a = *b;
*b = t;
}
void quicksort(int a[], int len)
{
int i=0, pvt=0;
if (len <=1)
return;
for (;i<len;++i)
{
if (a[i] < a[len-1])
swap_int(a+i,a+pvt++);
}
swap_int(a+pvt,a+len-1);
quicksort(a, pvt++);
quicksort(a+pvt, len-pvt);
}
There ya go, It even has the partitioning built in. The pivot should be random-selected, but thats for another day, I suppose.
This was a very silly mistake.
In swapping a[store] and a[q] in the party function :
t=a[store]; a[store]=a[q]; a[q]=a[store]; -----> This is Wrong.
a[q]= t should be the last statement.
Now it works fine. Thanks for the super quick response anyways.

Swapping string using bitwise operation [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
Write a definition of the function bitwise_swap that uses only bit
wise assignment operators to swap the values of two strings.
I tried to iterate over each char, changing into an int and swapping
using
a ^= b;
b ^= a;
a ^= b;
Once I had the char int value but it didn't seem to work.
Thanks in advance for the help
It sounds like you attempted something like this, which should work fine.
void bitwise_swap(char * restrict lhs, char * restrict rhs, size_t length) {
size_t i;
for (i=0; i<length; ++i) {
lhs[i] ^= rhs[i];
rhs[i] ^= lhs[i];
lhs[i] ^= rhs[i];
}
}
#include <stdio.h>
#include <string.h>
//#include <stdbool.h>
int main()
{ int m,n,t,i;
char a[]="National University";
char b[]="India";
char c[100];
char d[100];
m=strlen(a);
n= strlen(b);
if(m>n)
{ t=m;
// strcpy(&c,&a);
for(i=0;i<n;i++)
d[i]=b[i];
for(i=0;i<m-n;i++)
d[n+i]=32;
for(i=0;i<t;i++)
{
a[i]=a[i]^d[i];
d[i]=d[i]^a[i];
a[i]=a[i]^d[i];
}
printf("a= %s \t b=%s" ,a,d);
}
else
{ t=n;
// strcpy(&d,&b);
for(i=0;i<m;i++)
c[i]=a[i];
for(i=0;i<n-m;i++)
c[m+i]=32;
for(i=0;i<t;i++)
{
c[i]=c[i]^b[i];
b[i]=b[i]^c[i];
c[i]=c[i]^b[i];
}
printf("c= %s \t d=%s" ,c,b);
}
return 0;
}
This way you can do it.You just need a loop for swapping each character.
EDIT: Now its dynamic. You need not to specify length manually and I am appending NULL character at the end of shorter string. Look result at :http://ideone.com/B7lsz4

Resources