Algorithm Graph depth - first search - c

This is graph code, I want to understand Depth-first search algorithm, but I had some problem with this code,
If I input params:
5 5
1 2
1 3
1 5
2 4
3 5
Why cur become return 4 to 2 to 1 in function dfs?
thank your response
#include <stdio.h>
int book[101], sum,e[101][101];
int n,m,a,b;
void dfs(int cur){
int i;
printf("%d ",cur);
sum++;
if(sum==n){
return;
}
//
for(i=1;i<=n;i++){
if( e[cur][i]==1 && book[i]==0 ){
book[i]=1;
dfs(i);
}
}
return;
}
int main(){
int i,j;
scanf("%d %d ", &n,&m);
for(i=1;i<=n;i++){
for(j=1;j<=n;j++){
if(i==j){
e[i][j] = 0;
}else{
e[i][j] = 99999999;
}
};
};
for(i=1;i<=m;i++){
scanf("%d %d" ,&a, &b);
e[a][b] = 1;
e[b][a] = 1;
}
book[1] = 1;
dfs(1);
getchar();
getchar();
return 0;
}

I assume you're asking why your DFS is first exploring 1, then 2, then 4? Well, that's how a DFS works: It greedily goes to the next unvisited vertex. What output would you expect?
Some remarks regarding your code:
To improve the answers that you get, I'd suggest posting code that is a lot cleaner than the code in your question:
Please use variable names that tell your readers what they mean. For example: Use something like bool visited[] instead of int book[].
Use the correct data type! If you want to store whether an edge is there or not, or whether a vertex was visited or not, use bool, not some magic int values.
Global variables are usually not the right thing. There is no reason why all your variables should be global.
Neither is there a reason why the arrays should have the constant size 101.

Related

Codeblocks compiler not displaying output

I am trying to solve this problem below. As far as I know, everything is correct logically and syntax wise. However, when I click run, the black cmd window pops up, it displays the answers to problems 1-4 (those have been omitted because they are irrelevant, and problem 5 has been cropped out), but nothing happens at the problem 6 function, and I never get the "process returned 0 (0x0) execution time: xxxx s". Is there something I am doing wrong, or is it the compiler?
Note: I'm not asking for the answer. I just want to know why it isn't displaying.
/* problem 6 Find the difference between the sum of the squares of the first 100 numbers and the square of the sum*/
void problem6()
{
int sum_of_squares;
int square_of_sums;
int counter;
int answer;
int x;
for(x=1; x=100; x++)
{
sum_of_squares += (x*x);
counter += x;
}
square_of_sums = (counter*counter);
answer = square_of_sums - sum_of_squares;
printf("Problem 6 answer: %d", answer);
}
/* problem5(); */
problem6();
(=) is an assignment operator. Your condition should be (x<=100) or (x!=101). And you have not initialized sum_of_squares,square_of_sums and counter with any value so they contain garbage values.
void problem6()
{
int sum_of_squares=0;
int square_of_sums=0;
int counter=0;
int answer;
int x;
for(x=1; x<=100; x++)
{
sum_of_squares += (x*x);
counter += x;
}
square_of_sums = (counter*counter);
answer = square_of_sums - sum_of_squares;
printf("Problem 6 answer: %d", answer);
}

Base case of recursion function for Fibonacci sequence

I'm trying to write the function void fib(int arr[], int n), which would fill the array with Fibonacci numbers until index n.
I've tried to find base cases, and chose these:
void fib(int arr[], int num){
int arrLength = num + 1;
if(num<0){
return;
}else if(num == 0){
arr[num] = 1;
}else if(num == 1){
arr[num-1] = 1;
arr[num] = 1;
}
}
But, as you can see, I did not find recursive method itself.
Here's sample output, for example, for call fib(arr, 5):
0 1 2 3 4 5
1 1 2 3 5 8
My main function for testing case:
int main(){
int n = 10, i;
int arr[n+1];
fib(arr, n);
for(i=0;i<=10;i++){
printf("%i ", arr[i]);
}
return 0;
}
Is there any other way to make base cases more "elegant"? Also, I would truly appreciate hints using which I could fill the array with numbers starting from 2 with recursive option.
You question is asking for recursion but the program you write is just using function, because of this reason I am writing very basic code for your better understanding, you can improve this after understanding the flow and functionality or ask new question with some work.
Below one is a working code tested on TurboC, I am sharing complete test code.
#include <stdio.h>
#include<conio.h>
#define MAX 100
void fib(int *arr, int num, int a, int b, int term){
if(term == 0 && term <= num){
arr[term] = 1;
term++;
fib(arr,num,a,b,term);
}else if(term ==1 && term <= num){
arr[term] = 1;
term++;
fib(arr,num,a,b,term);
}else if(term <= num){
arr[term] = a+b;
term++;
fib(arr,num,b,a+b,term);
}
}
void main()
{
int firstTerm = 1;//First term of fibbo series
int secondTerm = 1;//Second term of fibbo series
int tracker = 0; // Tracker to track how much term we printed
int i;//To run loop here to check array after recursive function
int ar[MAX],n=5;// n is number of term we want to print
clrscr();
fib(ar,n,firstTerm,secondTerm,tracker);//recursive function call
// below is printing array to check
for(i=0;i<=n;i++){
printf("%d\t",ar[i]);
}
getch();
}
One thing I have to suggest is, if n is 5 then you just get 1 1 2 3 5, In code I did according to your requirement, so here it will print 1 1 2 3 5 8
I'd state that the "elegant" solution should be a simple loop, without any recursion, but let's see how it could be done in the less efficient and more error prone way.
// I'll assume that the function signature can't be changed
void fib(int arr[], int num)
{
// In the general case, use the well known recurrence relation.
if ( num > 1 )
{
// Use recursion here to calculate the previous elements of the array.
fib(arr, /* ... */);
// ^^^^^^^^^ Can you figure out what index should be passed here?
// Then, calculate the element at index num using the recurrence relation.
arr[num] = arr[num - 1] + arr[num - 2];
// ^^^^^^^ ^^^^^^^ Note the indices.
// Are those values alredy known?
}
// When num is 0 or 1, we can't use the general formula. Can you tell why?
else if ( num >= 0 )
{
fib(arr, /* ... */);
// ^^^^^^^^^ Same as before.
arr[num] = 1;
}
// If num is less than 0, it just do nothing.
}

Trying to write a function to shuffle a deck in C

So all I'm trying to do is take an input from the user of how many cards to use and then randomly assign each card to a different index in an array. I'm having extensive issues getting the rand function to work properly. I've done enough reading to find multiple different ways of shuffling elements in an array to find this one to be the easiest in regards to avoiding duplicates. I'm using GCC and after I input the amount of cards I never get the values from the array back and if I do they're all obscenely large numbers. Any help would be appreciated.
#include <time.h>
#include <stdlib.h>
#include <stdio.h>
void main(){
srand(time(NULL));
int d, c, i, z, l, r;
printf("Enter the deck length: ");
scanf("%d\n ", &c);
int deck[c];
int swap[c];
z = c;
for(l=0; l<c; l++){
swap[l] = l;
}
for(i=z; i=0; i--){
r = rand() / i
deck[i] = swap[r];
for(r; r=(c-1); r++){
swap[r] = swap[(r+1)];
}
}
for(d = 0; d < c; d++){
printf("%d ", deck[d]);
}
return;
}
I can spot one major problem here:
for(i=z; i=0; i--)
^^^
This loop will never execute since you are using assignment(=) and setting i to 0 therefore the condition will always be false, although using equality(==) will still be false in this case, you probably want:
for(i=z; i!=0; i--)
This means you will be using deck unitialized which is undefined behavior. Once you fix that you have a similar problems here:
for(r; r=(c-1); r++){
main has to return int and your return at the end needs to provide a value.
Turning on warning should have allowed you to find most of these issues, for example using -Wall with gcc gives me the following warning for both for loops:
warning: suggest parentheses around assignment used as truth value [-Wparentheses]
Note, see How can I get random integers in a certain range? for guidelines on how to use rand properly.
You basically need to be able to generate 52 numbers pseudo-randomly, without repeating. Here is a way to do that...
First, loop a random number generator 52 times, with a method to ensure none of the random numbers repeat. Two functions in addition to the main() will help to do this:
#include <ansi_c.h>
int NotUsedRecently (int number);
int randomGenerator(int min, int max);
int main(void)
{
int i;
for(i=0;i<52;i++)
{
printf("Card %d :%d\n",i+1, randomGenerator(1, 52));
}
getchar();
return 0;
}
int randomGenerator(int min, int max)
{
int random=0, trying=0;
trying = 1;
while(trying)
{
srand(clock());
random = (rand()/32767.0)*(max+1);
((random >= min)&&(NotUsedRecently(random))) ? (trying = 0) : (trying = 1);
}
return random;
}
int NotUsedRecently (int number)
{
static int recent[1000];//make sure this index is at least > the number of values in array you are trying to fill
int i,j;
int notUsed = 1;
for(i=0;i<(sizeof(recent)/sizeof(recent[0]));i++) (number != recent[i]) ? (notUsed==notUsed) : (notUsed=0, i=(sizeof(recent)/sizeof(recent[0])));
if(notUsed)
{
for(j=(sizeof(recent)/sizeof(recent[0]));j>1;j--)
{
recent[j-1] = recent[j-2];
}
recent[j-1] = number;
}
return notUsed;
}

Array doesn't print in reverse in C using pointers

I am trying to make a program that takes 10 numbers as input and outputs them in reverse order using pointers in C.
#include<stdio.h>
#define N 10
int array[N]; //Global variable
int main(void) {
int j;
int i;
printf("Enter 10 numbers: ");
for (i=0;i<N;i++) {
scanf("%d",(array+(4*i))); //Works
}
for (j=N-1;j<0;j--) {
printf("%d",array[j]); //Doesn't print, using *(array+j*4) doesn't
//print also
}
printf("\n");
printf("%d\n",*(array)); //Works so scanf works
printf("%d\n",*(array+4)); //Works so scanf works
return 0;
}
I have tried a making a seperate function for the two for loops but still it doesn't work. I want to know WHY this for-loop doesn't print but the two printfs below it print.
EDIT:
My new code is
#include<stdio.h>
#define N 10
int array[N]; //Global variable
int main(void) {
int j;
int i;
printf("Enter 10 numbers: ");
for (i=0;i<N;i++) {
scanf("%d",(array+i)); //Works
}
for (j=N-1;j<0;j--) { //it is supposed to be j>=0 or j>0 WHY
printf("%d",array[j]); //Doesn't print, using *(array+j) doesn't
//print also
}
printf("\n");
printf("%d\n",*(array)); //Works so scanf works
printf("%d\n",*(array+1)); //Works so scanf works
return 0;
}
Thanks to all the posts, I have a better understanding of how indexing works in C now but the printf doesn't work still unless I change the for-loop conditions(see above). WHY doesn't it work with the initial conditions but with the latter conditions.
Whoa!
This:
scanf("%d",(array+(4*i))); //Works
is very wrong and is overwriting memory! Why are you multiplying the index? You don't need to do that, C can index by itself. It should just be:
scanf("%d", &array[i]);
You want the address of the i:th array member, so say that, don't beat around the bush with strange multiplications.
If you really want to be "using pointers", as mentioned in a comment, you can do so:
scanf("%d", array + i);
This works since array is a pointer to the first element of the array, and adding i to is a fully valid use of pointer arithmetic; C will compute the proper pointer, knowing the size of each int in the array.
Your array consists of 10 elements with type int (obviously). In expression array + i variable i is not an offset in bytes. It is an index of element. So when you read it like you do (scanf("%d",(array+(4*i)))) you basicly read array[0], array[4], array[8], array[12] (we're out of array bounds here already, it causes memory corruption and might cause crashes), etc. Elements array[1],[2],[3],[5], etc. are uninitialized. That's why your code doesn't work :)
UPDATE:
And #shilong-liu's note about array indices is important, too. I didn't notice it.
for (j=N-1;j<0;j--) {
printf("%d",array[j]); //Doesn't print, using *(array+j*4)
}
the for loop is not right. The correct one is that
for (j = N - 1; j > 0; j--)
I guess since the pointer used is of type int, you assume that you have to multiply i by 4 because depending on the compiler int is 4 bytes. I guess if you really care only about the output, then you could do it the way you did with reverse iteration.
What you have to do has been already mentioned by the others so I will give you my solution for actually swapping the pointers memory wise and you could choose from the given solutions:
#include<stdio.h>
#define N 10
int array[N]; //Global variable
int main(void) {
int j;
int i;
printf("Enter 10 numbers: ");
for (i=0; i<N; i++) {
scanf("%d", (array + i));
}
for (left = 0; left < N / 2; left++)
{
int right = N - left - 1;
int temporary = array[left];
array[left] = array[right];
array[right] = temporary;
}
for (i=0; i<N; i++) {
printf("%d", (array + i));
}
return 0;
}
I have been programming for algorithmic contests so you could trust me.

function to perform bubble sort in C providing unstable results

I am participating in Harvard's opencourse ware and attempting the homework questions. I wrote (or tried to) write a program in C to sort an array using bubble sort implementation. After I finished it, I tested it with an array of size 5, then 6 then 3 etc. All worked. then, I tried to test it with an array of size 11, and then that's when it started bugging out. The program was written to stop getting numbers for the array after it hits the array size entered by the user. But, when I tested it with array size 11 it would continuously try to get more values from the user, past the size declared. It did that to me consistently for a couple days, then the third day I tried to initialize the array size variable to 0, then all of a sudden it would continue to have the same issues with an array size of 4 or more. I un-did the initialization and it continues to do the same thing for an array size of over 4. I cant figure out why the program would work for some array sizes and not others. I used main to get the array size and values from the keyboard, then I passed it to a function I wrote called sort. Note that this is not homework or anything I need to get credit, It is solely for learning. Any comments will be very much appreciated. Thanks.
/****************************************************************************
* helpers.c
*
* Computer Science 50
* Problem Set 3
*
* Helper functions for Problem Set 3.
***************************************************************************/
#include <cs50.h>
#include <stdio.h>
#include "helpers.h"
void
sort(int values[], int n);
int main(){
printf("Please enter the size of the array \n");
int num = GetInt();
int mystack[num];
for (int z=0; z < num; z++){
mystack[z] = GetInt();
}
sort(mystack, num);
}
/*
* Sorts array of n values.
*/
void
sort(int values[], int n)
{
// this is a bubble sort implementation
bool swapped = false; // initialize variable to check if swap was made
for (int i=0; i < (n-1);){ // loops through all array values
if (values[i + 1] > values [i]){ // checks the neighbor to see if it's bigger
i++; // if bigger do nothing except to move to the next value in the array
}
else{ // if neighbor is not bigger then out of order and needs sorting
int temp = values[i]; // store current array value in temp variable for swapping purposes
values[i] = values[i+1]; //swap with neighbor
values[i+1] = temp; // swap neighbor to current array value
swapped = true; // keep track that swap was made
i++;
}
// if we are at the end of array and swap was made then go back to beginning
// and start process again.
if((i == (n-1) && (swapped == true))){
i = 0;
swapped = false;
}
// if we are at the end and swap was not made then array must be in order so print it
if((i == (n-1) && (swapped == false))){
for (int y =0; y < n; y++){
printf("%d", values[y]);
}
// exit program
break;
}
} // end for
// return;
}
You can easily use 2 nested for loops :
int i, j, temp ;
for ( i = 0 ; i < n - 1 ; i++ )
{
for ( j = 0 ; j <= n - 2 - i ; j++ )
{
if ( arr[j] > arr[j + 1] )
{
temp = arr[j] ;
arr[j] = arr[j + 1] ;
arr[j + 1] = temp ;
}
}
}
also you should now it's a c++ code not a c, because c doesn't have something like :
int mystack[num];
and you should enter a number when you're creating an array and you can't use a variable (like "int num" in your code). This is in C, but in C++ you're doing right.
The first thing to do when debugging a problem like this is ensure that the computer is seeing the data you think it should be seeing. You do that by printing out the data as it is entered. You're having trouble with the inputs; print out what the computer is seeing:
static void dump_array(FILE *fp, const char *tag, const int *array, int size)
{
fprintf(fp, "Array %s (%d items)\n", tag, size);
for (int i = 0; i < size; i++)
fprintf(fp, " %d: %d\n", i, array[i]);
}
int main(void)
{
printf("Please enter the size of the array \n");
int num = GetInt();
printf("num = %d\n", num);
int mystack[num];
for (int z = 0; z < num; z++)
{
mystack[z] = GetInt();
printf("%d: %d\n", z, mystack[z]);
}
dump_array(stdout, "Before", mystack, num);
sort(mystack, num);
dump_array(stdout, "After", mystack, num);
}
This will give you direct indications of what is being entered as it is entered, which will probably help you recognize what is going wrong. Printing out inputs is a very basic debugging technique.
Also, stylistically, having a function that should be called sort_array_and_print() suggests that you do not have the correct division of labour; the sort code should sort, and a separate function (like the dump_array() function I showed) should be used for printing an array.
As it turns out the reason why it was doing this is because when comparing an array's neighbor to itself as in:
if (values[i + 1] > values [i])
The fact that I was just checking that it is greater than, without checking if it is '=' then it was causing it to behave undesirably. So if the array is for example [1, 1, 5, 2, 6, 8] then by 1 being next to a 1, my program did not account for this behavior and acted the way it did.

Resources