Hi guys I just cant seem to reverse my array, my syntax looks ok and my logic seems fine but the FOR function is just not iterating through. This function is meant to reverse arrays, mainly strings. and n = length of the string.
#include <stdio.h>
#include <string.h>
void reverse(char, int);
int main()
{
char a[100];
gets(a);
reverse(a, strlen(a)-1);
printf("%s\n",a);
getchar();
getchar();
getchar();
return 0;
}
void reverse(char ar[], int n)
{
char c;
int i = 0;
printf("n = %d" , n);
for ( i = 0; i >= n ; i++){
c = ar[i];
ar[i] = ar[n];
ar[n] = c;
printf("Processed");
n--;}
}
/*
if (begin >= n)
return;
c = *(x+begin);
*(x+begin) = *(x+n);
*(x+n) = c;
offs = x++;
printf("Begin = %d , n = %d, offs = %p \n", begin, n, offs);
reverse(x, ++begin, --n); */
The condition with the loop variable is wrong, it should test for less-than, not for greater-than (since you seem to want to go from 0 to n).
i >= n should be i < n / 2.
As well as the logic bug already pointed out by #H2CO3, your function prototype is wrong - change:
void reverse(char, int);
to:
void reverse(char *, int);
^^^^^^
Note that if you compile with warnings enabled (e.g. gcc -Wall ...) the compiler will point out such mistakes and thereby save you a lot of time and effort.
This is O(N) performance. Actually you only perform N/2 iterations
void reverseArray(char[] arr) {
int start = 0, end = strlen(arr) - 1, tempVal;
for (; start < end; start++, end--) {
//swap start & end location
tempVal = arr[end];
arr[end] = arr[start];
arr[start] = tempVal;
}
}
Related
I try to solve the problem of N queens solution and manage to create an algorithm that gives me all possibilities and prints it (I try to understand everything but as backtracking is a little new to me, it is hard).
My program looks at every possibility and prints the position of the queens one by colones, it looks like it works well, even if I don't understand my stopping condition.
My problem is that I need to print the position in a certain a order (start from first queen position 0 - N), but it prints in a random way.
I could store it in an array and sort it, but it will take too much time, so i would like to know if people can look at my code and point out possible problems and give some tips or feedback.
#include <unistd.h>
#include <stdio.h>
#define N 10
void print(int tab[N][N])
{
int i;
int a;
char c;
i = -1;
while (++i < N)
{
a = -1;
while (++a < N)
if (tab[a][i])
{
c = '0' + a;
write(1, &c, 1);
}
}
write(1, "\n", 1);
}
int check(int tab[N][N] , int x, int y)
{
int i;
int j;
i = 0;
while (i < x)
if (tab[i++][y])
return (0);
i = x;
j = y;
while (j >= 0 && i >= 0)
if (tab[i--][j--])
return (0);
i = x;
j = y;
while (i >= 0 && j < N)
if (tab[i--][j++])
return (0);
return (1);
}
int backtrack(int tab[N][N],int x ,int y, int *nbr)
{
if (x >= N)
{
print(tab);
*nbr += 1;
}
while (++y < N)
if (check(tab, x, y))
{
tab[x][y] = 1;
if (backtrack(tab, x + 1, -1, nbr))
return (1);
tab[x][y] = 0;
}
return (0);
}
int ft_ten_queens_puzzle(void)
{
int tab[N][N];
int nbr;
int b;
nbr = -1;
while(++nbr < N)
{
b = -1;
while (++b < N)
tab[nbr][b] = 0;
}
nbr = 0;
backtrack(tab,0,-1, &nbr);
return (nbr);
}
int main()
{
printf("%d\n",ft_ten_queens_puzzle());
}
Your output is coming out random due to a couple of bugs in your print function :
a) If you are printing out a grid, then EVERY cell must be output, but you are not printing cells where tab[a][i] is 0
b) You need a newline at the end of EVERY line, but your write statement is in the wrong place
So the function should be like :
void print(int tab[N][N])
{
char c;
for (int i=0; i < N; i++)
{
for (int a=0; a < N; a++)
{
if (tab[a][i])
{
c = '0' + a;
}
else
{
c = ' ';
}
write(1, &c, 1);
}
write(1, "\n", 1);
}
}
A couple of tips/feedback :
Use full easy-to-understand variable names.
Don't use that awkward "int x = -1; while (++x < N) {" format - the standard for (int x=0; x < N; x++) { format is better
Indent your code correctly. for example, in print, you had the write for the newline out side of it's intended loop, which was easily missed due to indentation issues
Yes, the language allows you to skip the "{","}" for single-statement loops and if statements. I would STRONGLY recommend to never skip them, but always put them on all loops and ifs; It is so much easier to both prevent, and also to track down bugs (especially when indentation is not consistent)
Just my thoughts, I hope they help :)
I am trying to practice with C by making a bubble sort program. The problem until now seems to be that the for loop that is giving values to the cells of the array is stuck after the condition is no longer fulfilled but it doesn't seem to be executing the commands in the loop. I don't know what is happening exactly and I have added some extra lines to see what is happening an these were my conclusions. Here is the code:
#include <stdio.h>
#include <stdlib.h>
void swap(int *x, int *y)
{
int temp = *x;
*x = *y;
*y = temp;
}
int *sort(int *array)
{
int finish = 1;
while (finish = 1)
{
finish = 0;
for (int i = 0; i <= sizeof(array); i++)
{
if ((array + i) > (array + i + 1))
{
swap(array + i, array + i + 1);
finish = 1;
}
}
}
return array;
}
int main()
{
int s, res;
printf("Give me the size of the array being sorted(larger than 1) : ");
do
{
res = scanf("%d", &s);
if (res != 1)
{
printf("Wrong Input!\n");
exit(1);
}
if (s < 2)
printf("Only numbers equal or larger than 2\n");
} while (s < 2);
int array[s];
for (int i = 0; i < s; i += 1)
{
scanf("%d", array + i);
printf("%d %d %d\n\n", *(array + i), i, i < s); // I used this to check if my values were ok
}
printf("end of reading the array"); //I added this line to see if I would exit the for loop. I am not seeing this message
sort(array);
printf("\n");
for (int i = 0; i < sizeof(array); i++)
printf("%d\n\n", array + i);
printf("Array has been sorted! Have a nice day!\n\n************************************************************");
return 0;
}
See the annotations in the code:
#include <stddef.h> // size_t 1)
#include <stdio.h>
#include <stdlib.h>
void swap(int *x, int *y)
{
int temp = *x;
*x = *y;
*y = temp;
}
int *sort(int *array, size_t size) // needs an extra parameter to know the size of the array
{
int finish = 1;
while (finish /* = 1 * you don't want assignment, you want comparison: */ == 1)
{
finish = 0;
for (int i = 0; i /* <= sizeof(array) */ < size - 1; i++) // i should be of type size_t
{
// if ((array + i) > (array + i + 1)) you are not dereferencing:
if(array[i] > array[i + 1])
{
// swap(array + i, array + i + 1); // easier to read imho:
swap(&array[i], &array[i + 1]);
finish = 1;
}
}
}
return array; // why does this function return anything? it is never used.
}
int main()
{
int s; /* , res; no need for an extra variable res */
printf("Give me the size of the array being sorted(larger than 1) : ");
do
{
// res = scanf("%d", &s);
// if (res != 1)
if (scanf("%d", &s) != 1)
{
printf("Wrong Input!\n");
// exit(1); // should be EXIT_FAILURE. Use return instead of exit() when in main().
return EXIT_FAILURE;
}
if (s < 2)
printf("Only numbers equal or larger than 2\n");
} while (s < 2);
int array[s];
for (int i = 0; i < s; /* i += 1* idiomatic: */ ++i) // size_t would be the correct type for s and i.
{
scanf("%d", /* array + i use indexes: */ &array[i]);
printf("%d %d %d\n\n", array[i], i, i < s); // again: indexes. i < s is allready ensured by the condition of the for-loop
}
printf("end of reading the array");
// sort(array); // sort will have no idea about the size of array use
sort(array, s); // instead.
printf("\n");
for (int i = 0; i < /* sizeof(array) 2) */ s; i++)
printf("%d\n\n", /* array + i * again you don't dereference */ array[i]);
printf("Array has been sorted! Have a nice day!\n\n************************************************************");
return 0;
}
1) size_t is the type that is guaranteed to be big enough to hold all sizes of objects in memory and indexes into them. The conversion specifier for scanf() is "%zu".
2) sizeof(array) in main() will yield the number of bytes in array, but you want the number of elements so you'd have to use sizeof(array) / sizeof(*array). But thats not needed since you already know its size. It is s.
This line
printf("end of reading the array");
has no line feed at the end of the string. This is a problem because printf is part of the family of functions called "buffered IO". The C library maintains a buffer of the things you want to print and only sends them to the terminal if the buffer gets full or it encounters \n in the stream of characters. You will not see, end of reading the array on your screen until after you have printed a line feed. You only do this after calling sort(). So all you know is your program is getting into an infinite loop at some point before the end of sort.
So there are actually three loops that could be infinite: the for loop you identified, the while loop in sort and the for loop inside the while loop. As the other answers point out, you have made the classic mistake of using assignment in the while conditional
while (finish = 1)
// ^ not enough equals signs
Unless your C compiler is really old, it is probably outputting a warning on that line. You should heed warnings.
Also, you should learn to use a debugger sooner rather than later. Believe me, it will save you a lot of time finding bugs.
In the sort function sizeof(array) returns the size of the pointer. (you can check it by yourself using printf("%d", sizeof(array).
The solution is to change your function to:
int sort(int* array, size_t size) { ... }
and call it with the correct array size:
sort(array, s);
I tried to write a program in C that reverses all the numbers in an array, but it actually doesn't reverse anything, so I get unchanged numbers back. I guess I got something wrong with the pointers.
Here is my code:
#include <stdio.h>
void reverse(int *n) {
int number = *n, number2 = 0;
while (number!=0) {
number2 *= 10;
number2 += number % 10;
number /= 10;
}
*n = number2;
}
void ReverseDigits(int *p, int n) {
int i = 0;
while (i < n) {
reverse(&p);
p++;
i++;
}
}
int main() {
int array[3] = {123, 456, 789}, i = 0;
while (i < 3) {
ReverseDigits(array, 3);
i++;
}
return 0;
}
In ReverseDigits the variable p is an int pointer. When you do &p you'll get a pointer to int pointer. But your reverse function just expects an int pointer so your call of reverseis wrong. Simply do
reverse(p); // insteand of reverse(&p)
In main you shall not call ReverseDigits in a loop as the function already loops the array (i.e. the number of elements passed). So skip the while and simply do:
int main() {
int array[3] = {123, 456, 789};
ReverseDigits(array, 3);
return 0;
}
It seems to me that your reverse() function is "both baffling, and necessarily wrong." (Hey, don't take that personally...)
How could such a function possibly work, without being told, not only where the (array) is, but how long it is? You seem to be missing a parameter here.
Once you've settled that problem in your design, the task of "reversing" an array is simply a process of "swapping" the first-and-last elements in an algorithm that goes something like this: (pseudocode!)
function reverse( array[], array_size) {
int i = 0;
int j = array_size - 1; // since zero-based
while (i < j) { // no need to use "<=" here"
temp = array[i];
array[i] = array[j];
array[j] = temp;
i++;
j--;
}
}
I'm having trouble with the things I am and am not allowed to do with arrays and pointers in the following code:
#include <stdio.h>
#define MAX 1000
void swap (char *v[], int i, int j);
main() {
int i = 1, j = 2;
int count;
char *a = "Bill ", *b = "went ", *c = "to the ", *d = "grocery store.";
char *v[MAX];
v[0] = a;
v[1] = b;
v[2] = c;
v[3] = d;
printf("String before swapping elements at index %d and %d: \n",i,j);
for(count = 0; count < 4; ++count)
printf("%s",v[count]);
printf("\n");
swap(v,i,j);
printf("String after swapping elements at index %d and %d: \n",i,j);
for(count = 0; count < 4; ++count)
printf("%s",v[count]);
printf("\n");
system("Pause");
return 0;
}
void swap (char *v[], int i, int j)
{
char *temp;
temp = v[i];
v[i] = v[j];
v[j] = temp;
}
Two things come to mind:
Why can't I write v[] = {a,b,c,d} after declaring *v[MAX]? In fact, I did a quick test and even this isn't allowed:
char v[MAX];
v[] = {'w','o','r','d','s'};
whereas char v[] = {'w','o','r','d','s'}; is accepted. Why is that?
Second thing, how can I re-write the for loop without having to use a magic number (in this case 4)? I tried using strlen in various ways but I got an error each time. The best I could come up with is a somewhat clumsy solution of declaring char *k; and changing the loop condition to
for(count = 0, k = v; *(k-1); ++count, ++k)
printf("%s",v[count]);
Surely there must be a more elegant way to loop through the v array?
how can I re-write the for loop without having to use a magic number
(in this case 4)?
One way of doing this, is to add a special terminator value ( usually NULL) in the array that you are iterating, e.g.
char *v[] = { a, b, c, d, NULL };
for(count = 0; v[count] != NULL; ++count)
printf("%s",v[count]);
char *v[] = { a, b, c, d};
int size = sizeof(v)/sizeof(*v);//4
Im a new programmer
I am have an char array M = "something",
and I want to print in this way
t
eth
methi
omethin
something
can any one help me in the logic to print in this way using loops.
I have used this code so far, but shows Segmentation error, can any body help me out where I have gone wrong.
main() {
int i, j, k, m, n;
char a[] = "Something";
n = sizeof(a) - 1;
for (i = 0; i < (n/2) + 1; i++) {
for (j = 0; j <= n - i; j++)
printf(" ");
for (m = (n/2) - i; !(m >= (n/2)); m--)
printf("%c",a[m]);
for (k = (n/2);k <= (n/2) + i; k++)
printf("%c", a[k]);
printf("\n");
}
}
Linear solution (note the string must be modifiable)
#include<stdio.h>
#include<string.h>
int main()
{
char array[] = "something";
char * str = array;
int size = strlen(str);
int i=size/2;
if(size%2==0)i--;
for(;i>=0;i--){
char c = str[size-i];
str[size-i]='\0';
printf("%s\n",str+i);
str[size-i]=c;
}
}
I remember i had a homework like this when I was learning c :)
Update:
As Jonathan Leffler pointed out, without modifying the string itself, we can print by passing the string length to printf function. (I didn't know the %.*s specifier :)) Well it shows we can learn even from a basic simple problems :) Thanks Jonathan. This makes the code more elegant and compact.
#include<stdio.h>
#include<string.h>
void print_string(const char *string)
{
int size = strlen(string),i;
for (i = (size - 1) / 2; i >= 0; i--)
printf("%d:%d: %.*s\n", i, size-2*i, size-2*i, string+i);
}
int main()
{
char * a = "something";
print_string(a);
}
C program i created , hope this helps.
#include<stdio.h>
int main()
{
char *str,*p1,*p2;
int count=0;
str="something";
p1=str; //points to the first element of the string.
while(*(str+1)!='\0')
str++;
p2=str; //points to the last element of the string.
while(*p1!='\0')
{
if(p1==p2)
printf("%c\n",*p1);
if(p1>p2)
{
while(p2<=p1)
{
printf("%c",*p2);
p2++;
count++;
}
p2=p2-(count);
count=0;
printf("\n");
}
p1++; // move to right.
p2--; // move to left.
}
}
Output :
Time complexity of this algorithm would be O(n^2)