i declare a global variable and use and modify its value in the function. Then i want to get the modified value of this global variable, it has some problem. Can anyone help me?
#include<stdio.h>
#include<string.h>
#include<conio.h>
#include<stdlib.h>
#define MAX 10
struct link
{
int freq;
char value[MAX];
struct link* right;
struct link* left;
};
typedef struct link node;
void sort(node *[], int);
node* create(char[], int);
void sright(node *[], int);
void Assign_Code(node*, int [], int);
void Delete_Tree(node *);
int test[720][720];
main()
{
node* ptr, * head;
int i, n, total = 0, u, c[256];
char str[MAX];
node* a[256];
int freq;
printf( "Huffman Algorithm\n");
printf("\nEnter the no. of letter to be coded:");
/*input the no. of letters*/
scanf("%d", &n);
for (i = 0; i < n; i++)
{
printf("Enter the letter & frequency:");
/*input the letter & frequency*/
scanf("%s %d", str, &freq);
a[i] = create(str, freq);
}
while (n > 1)
{
sort(a, n);
u = a[0]->freq + a[1]->freq;
strcpy(str,a[0]->value);
strcat(str,a[1]->value);
ptr = create(str, u);
ptr->right = a[1];
ptr->left = a[0];
a[0] = ptr;
sright(a, n);
n--;
}
Assign_Code(a[0], c, 0);
//getch();
printf("Code: ");
for (i = 1; i <= n; i++)
{
printf("%d", test[0][i]);
}
printf("\n");
Delete_Tree(a[0]);
}
node* create(char a[], int x)
{
node* ptr;
ptr = (node *) malloc(256*sizeof(node));
ptr->freq = x;
strcpy( ptr->value , a);
ptr->right = ptr->left = NULL;
return(ptr);
}
void sort(node* a[], int n)
{
int i, j;
node* temp;
for (i = 0; i < n - 1; i++)
for (j = i; j < n; j++)
if (a[i]->freq > a[j]->freq)
{
temp = a[i];
a[i] = a[j];
a[j] = temp;
}
}
void sright(node* a[], int n)
{
int i;
for (i = 1; i < n - 1; i++)
a[i] = a[i + 1];
}
void Assign_Code(node* tree, int c[], int n)
{
int i;
if ((tree->left == NULL) && (tree->right == NULL))
{
printf("%s code: ", tree->value);
test[0][0]=tree->value;
for (i = 0; i < n; i++)
{
test[0][i+1]=c[i];
printf("%d", c[i]);
}
printf("\n");
}
else
{
c[n] = 1;
n++;
Assign_Code(tree->left, c, n);
c[n - 1] = 0;
Assign_Code(tree->right, c, n);
}
}
void Delete_Tree(node * root)
{
if(root!=NULL)
{
Delete_Tree(root->left);
Delete_Tree(root->right);
free(root);
}
}
Let me highlight the problem:
while (n > 1)
{
...
n--;
}
...
for (i = 1; i <= n; i++)
{
printf("%d", test[0][i]);
}
By the time the second loop starts n is one, and the printf is executed only once, so that you print the value of test[0][1] and only that.
The value of test[0][1] is overwritten many times (as many as the number of leaf nodes in the tree) in Assign_Code:
void Assign_Code(node* tree, int c[], int n)
{
if ((tree->left == NULL) && (tree->right == NULL))
{
...
for (i = 0; i < n; i++)
{
test[0][i+1]=c[i];
}
}
...
}
Now, because of the way you are traversing the tree the last time test[0][1] is overwritten is for a Huffman code that has a '0' as first character.
As a side note:
node* create(char a[], int x)
{
node* ptr;
ptr = (node *) malloc(256*sizeof(node)); // <--- This is wrong
ptr->freq = x;
strcpy( ptr->value , a);
ptr->right = ptr->left = NULL;
return(ptr);
}
There is no reason to allocate 256 times the size of node to store one node. You are creating a node and storing it in an array of pointers to nodes. Allocate one node there, like this:
malloc (sizeof (node)); or malloc ((sizeof (*ptr));
you can store the n value to some temporary variables, after you get the
values.
Then use the temporary variable in your for loop condition.
scanf("%d", &n);
int temp = n ;
for (i = 1; i <= temp ; i++)
{
printf("%d", test[0][i]);
}
Related
Based on the BFS algorithm, I am required to write a function SD() to find the shortest distance from vertex $v$ to $w$, in an undirected graph. Vertices ranged from 1 to $|V|$. The distance is measured by the number of edges. If there is no path from $v$ to $w$, then -1 is returned. You may assume that the input graph is always valid (no duplicate or any invalid link, etc.). The function prototype is given as follows:
int SD (Graph G, int v, int w);
For the sample input and output below, my code outputs 1 instead of 2 and I don't know what I'm doing wrong, more like I don't know what I am doing at this point, help would be appreciated thank you! (Please refer to the int SD(Graph g, int v, int z) section of the code below).
#include <stdio.h>
#include <stdlib.h>
typedef struct _listnode
{
int vertex;
struct _listnode *next;
} ListNode;
typedef struct _graph{
int V;
int E;
int *visited;
int **matrix;
}Graph;
typedef ListNode QueueNode;
typedef struct _queue{
int size;
QueueNode *head;
QueueNode *tail;
} Queue;
int SD (Graph G, int v, int w);
void printGraphMatrix(Graph );
// You should not change the prototypes of these functions
void enqueue(Queue *qPtr, int item);
int dequeue(Queue *qPtr);
int getFront(Queue q);
int isEmptyQueue(Queue q);
void removeAllItemsFromQueue(Queue *qPtr);
int main()
{
Graph g;
int i,j;
printf("Enter the number of vertices:\n");
scanf("%d",&g.V);
g.E = 0;
g.matrix = (int **)malloc(g.V*sizeof(int *));
for(i=0;i<g.V;i++)
g.matrix[i] = (int *)malloc(g.V*sizeof(int));
for(i=0;i<g.V;i++)
for(j=0;j<g.V;j++)
g.matrix[i][j] = 0;
g.visited = (int *) malloc(sizeof(int)*g.V);
for(i=0;i<g.V;i++) g.visited[i] = 0;
int V1, V2;
printf("Enter two vertices which are adjacent to each other:\n");
while(scanf("%d %d",&V1,&V2)==2)
{
if(V1>0 && V1<=g.V && V2>0 && V2<=g.V)
{
g.matrix[V1-1][V2-1] = 1;
g.matrix[V2-1][V1-1] = 1;
g.E++;
}
else
break;
printf("Enter two vertices which are adjacent to each other: (press a to stop)\n");
}
scanf("%*c");
// printGraphMatrix(g);
printf("Enter two vertices for finding their shortest distance: (press a to stop)\n");
scanf("%d %d", &i, &j);
int d = SD(g,i,j);
if(d==-1)
printf("%d and %d are unconnected.\n",i,j);
else
printf("The shortest distance is %d\n",d);
return 0;
}
int SD(Graph g, int v, int z){
int * distance;
distance = (int *) malloc(sizeof(int)*g.V);
// Initialize distances
for(int i = 0; i < g.V; i++)
{
distance[i] = -1;
}
// queue to do BFS.
Queue q;
q.size = 0;
q.head = NULL;
q.tail = NULL;
int w;
int i;
enqueue(&q,v);
distance[v-1] = distance[v-1] + 1;
g.visited[v-1] = 1;
while(isEmptyQueue(q)==0){
w = dequeue(&q);
for(i=0;i<g.V;i++)
{
if(g.matrix[w-1][i] == 1 && g.visited[i]==0)
{
g.visited[i]=1;
distance[i] = distance[i] + 3;
enqueue(&q,i+1);
}
}
}
if(z <= g.V) return distance[z-1];
return -1;
}
void printGraphMatrix(Graph g)
{
int i,j;
for(i=0;i<g.V;i++){
for(j=0;j<g.V;j++)
printf("%d\t",g.matrix[i][j]);
printf("\n");
}
}
void enqueue(Queue *qPtr, int item) {
QueueNode *newNode;
newNode = malloc(sizeof(QueueNode));
if(newNode==NULL) exit(0);
newNode->vertex = item;
newNode->next = NULL;
if(isEmptyQueue(*qPtr))
qPtr->head=newNode;
else
qPtr->tail->next = newNode;
qPtr->tail = newNode;
qPtr->size++;
}
int dequeue(Queue *qPtr) {
if(qPtr==NULL || qPtr->head==NULL){ //Queue is empty or NULL pointer
return 0;
}
else{
int headValue = qPtr->head->vertex;
QueueNode *temp = qPtr->head;
qPtr->head = qPtr->head->next;
if(qPtr->head == NULL) //Queue is emptied
qPtr->tail = NULL;
free(temp);
qPtr->size--;
return headValue;
}
}
int getFront(Queue q){
return q.head->vertex;
}
int isEmptyQueue(Queue q) {
if(q.size==0) return 1;
else return 0;
}
void removeAllItemsFromQueue(Queue *qPtr)
{
while(dequeue(qPtr));
}
I'm trying to make a program that finds if node B belongs to the subtree starting from node A. I wrote the code in C and self-implemented a mechanism for queue because I'm using BFS to traverse the tree. The problem is that my code runs into an infinite loop saying that my queue is full even is not.
Code:
#include <stdlib.h>
#include <stdio.h>
#define MAXSIZE 6
typedef struct Queue
{
int capacity;
int size;
int front;
int rear;
int * elements;
}Queue;
Queue * createQueue(int maxElements)
{
Queue *q;
if (NULL != (q = (Queue *)malloc(sizeof(Queue))))
{
q->elements = (int*)malloc(maxElements * sizeof(int));
q->size = 0;
q->capacity = maxElements;
q->front = 0;
q->rear = -1;
return q;
}
}
void dequeue(Queue *q)
{
if (0 == q->size)
{
printf("Queue is empty\n");
return;
}
else
{
q->size--;
q->front++;
if (q->front == q->capacity)
{
q->front = 0;
}
}
}
int front(Queue *q)
{
if (q->size == 0)
{
printf("queue is empty\n");
exit(0);
}
return q->elements[q->front];
}
void enqueue(Queue *q, int element)
{
if (q->size == q->capacity)
{
printf("queue is full \n");
}
else
{
q->size++;
q->rear++;
if (q->rear == q->capacity)
{
q->rear = 0;
}
q->elements[q->rear] = element;
}
return;
}
void readInput(int A[],int B[],int M[][MAXSIZE],int N)
{
FILE * fp;
int row, col;
for (int i = 0; i < 5; i++)
for (int j = 0; j < 5; j++)
M[i][j] = 0;
if (0 == fopen_s(&fp,"input.txt", "r"))
{
fscanf_s(fp, "%d", &N);
for (int i = 0; i < N; i++)
fscanf_s(fp,"%d ", &A[i]);
for (int i = 0; i < N; i++)
fscanf_s(fp,"%d ", &B[i]);
for (int i = 0; i < N; i++)
{
fscanf_s(fp, "%d %d", &row,&col);
M[row][col] = 1;
}
}
}
bool vBelongsToUSubtree(int M[][MAXSIZE], int *u, int* v)
{
bool belongs = false, visited[MAXSIZE];
for (short i = 0; i < MAXSIZE; i++)visited[i] = false;
visited[*u] = true;
Queue *q = createQueue(MAXSIZE);
enqueue(q, *u);
printf("%d\n", front(q));
int node;
while (0 != q->size)
{
node = front(q);
dequeue(q);
for (int i = 1; i < MAXSIZE; i++)
{
if (1 == M[node][i] and false == visited[i])
{
enqueue(q, node);
visited[node] = true;
if (node == *v)return true;
}
//printf("!\n");
}
//printf("%d\n", node);
}
/*for (int i = 0; i < q->size; i++)
{
printf("%d \n", front(q));
}
*/
return belongs;
}
int main()
{
int A[100], B[100], M[MAXSIZE][MAXSIZE], N=0;
readInput(A, B, M, N);
for(int i=1;i<=MAXSIZE;i++)
for(int j=i;j<=MAXSIZE;j++)
if(vBelongsToUSubtree(M, &i, &j))printf("yes");
else printf("not");
system("pause");
return 0;
}
As pointed out in the comments, there are several problems with your existing code. Before it is expected to work at all, you should address them.
This answer addresses only the infinite loop you asked about...
Also pointed out in the comments:
If i or j in the statement: if(vBelongsToUSubtree(M, &i, &j))printf("yes"); are not controlled properly they may never satisfy the exit condition in for(int i=1;i<=MAXSIZE;i++) or for(int j=i;j<=MAXSIZE;j++)
Following i through to the end of its execution flow, it appears it (and perhaps j) are never changed.
The chain of calls passing i :
if(vBelongsToUSubtree(M, &i, &j))printf("yes");
Which in turn calls:
enqueue(q, *u);
Which has the prototype:
void enqueue(Queue *q, int element)
where int element is the value for i, and is not changed. (nor could it be using this prototype.)
I am trying to store elements for Fibonacci series in the array which is inside the function and after returning from function by "return arr " my stack frame is getting destroyed and I am unable to receive values in main function. I wanted to use recursion only and printing from main function these are my conditions.
#include <stdio.h>
int *fib(int *num, int *first, int *second, int i, int *arr);
int main()
{
int num;
printf("Enter any number : \n");
scanf("%d", &num);
int first = 0, second = 1, i = 0;
int arr[num];
int *result = fib(&num, &first, &second, i, arr);
for (int i = 0; i < num; i++)
printf("%d ", result[i]);
}
int *fib(int *num, int *first, int *second, int i, int *arr)
{
int temp;
if (*first == 0)
printf("%d ", *first);
if (*num < 0)
{
if (*second == 1)
printf("%d ", *second);
temp = *first - *second;
*first = *second;
*second = temp;
if (*second > *num && *second < -*num)
{
*(arr + i) = *second;
return fib(num, first, second, i++, arr);
}
else
return arr;
}
else
{
temp = *first + *second;
*first = *second;
*second = temp;
if (*second >= *num + 3)
return arr;
else
{
*(arr + i) = *second;
return fib(num, first, second, i++, arr);
}
}
printf("\n");
}
You can't.
You are trying to fight against the very definition of what a stack frame is, and you are losing.
And you will always lose!
Instead, properly structure your program to pass data around in the way you need, in accordance with the rules and specifications of the language.
You can definitely achieve what you're wanting do without protecting the information on the function stackframes, as I don't believe your error has anything to do with that. With that said, recursion with Fibonacci numbers is kind of pointless compared to the iterative approach, it just ends up spamming extra stackframes when none are needed.
I took inspiration from Jabberwocky's answer and made an example with "recursion", though it ends up just being a fancy for loop.
#include <stdio.h>
void fib(int num, int *arr, int pos);
int main()
{
int num;
printf("Enter any number : \n");
scanf("%d", &num);
int arr[num];
if (num > 1) {
arr[0] = 0 ;
arr[1] = 1 ;
}
int pos = 2;
fib(num, arr, pos);
for (int i = 0; i < num; i++)
printf("%d ", arr[i]);
}
void fib(int num, int *arr, int pos)
{
if (pos < num && pos > 1)
{
arr[pos] = arr[pos - 2] + arr[pos - 1];
fib(num, arr, pos + 1);
}
else {
return;
}
}
This stores all values into arr which is allocated in main, so deletion of stackframes has no effect. The fib function even when recursive does not need to return anything because it has the array pointer and can directly change the values of the array. Of course more error checking is needed but I think this is sufficient to get the idea across.
Somewhat off topic, but you probably simply want this:
#include <stdio.h>
void fib(int num, int *arr);
int main()
{
int num;
printf("Enter any number : \n");
scanf("%d", &num);
int arr[num] = { 0, 1 } ;
fib(num, arr);
for (int i = 0; i < num; i++)
printf("%d ", arr[i]);
}
void fib(int num, int *arr)
{
for (int i = 0; i < num; i++)
{
arr[i + 2] = arr[i] + arr[i + 1];
}
}
Using recursion is pretty pointless here.
This is untested code, there may be bugs.
#include <stdio.h>
int fib ( int *num , int *first , int *second , int count , int *arr ) ;
int main()
{
char ch;
do
{
int num = 0;
printf("Enter any number : \n");
scanf("%d", &num);
int first = 0, second = 1, count = 0,size = num;
if(num < 0)
{
size = -(num);
}
int arr[size];
count = fib(&num, &first, &second, count, arr);
for (int j = 0; j < count; j++)
{
printf("%d ", *(arr + j));
}
printf("\n");
printf("Do you want to repeat ? Y / N\n");
scanf("\n\n%c", &ch);
} while (ch == 'y' || ch == 'Y');
}
int fib(int *num, int *first, int *second, int count, int *arr)
{
int temp;
if (*first == 0)
{
printf("%d ", *first);
}
if (*num < 0)
{
if (*second == 1)
{
printf("%d ", *second);
}
temp = *first - *second;
*first = *second;
*second = temp;
if (*second >= *num && *second <= -*num)
{
*(arr + count) = *second;
return fib(num, first, second, count+1, arr);
}
}
else if(*num > 0)
{
temp = *first + *second;
*first = *second;
*second = temp;
if (*second == 1)
{
printf("%d ", *second);
}
if (*second <= *num)
{
*(arr + count) = *second;
return fib(num, first, second, count+1, arr);
}
}
return count;
}
int *fib(int *num, int *first, int *second, int i, int *arr)
{
int temp;
if (*first == 0)
printf("%d ", *first);
if (*num < 0)
{
if (*second == 1)
printf("%d ", *second);
temp = *first - *second;
*first = *second;
*second = temp;
if (*second > *num && *second < -*num)
{
*(arr + i) = *second;
return fib(num, first, second, i++, arr);
}
else
return arr;
}
else
{
temp = *first + *second;
*first = *second;
*second = temp;
I can scan the matrix and determine the size but the output is blank.
Here is my code:
int createTripplesArrayAndList(int** mat, int row, int colum, Tripple **arr, Node** ls) {
int i, j, count=0, k = 0;
Node* head = *ls;
Node* tmp=NULL;
//count how many elements would be in the required array\list
for (i = 0; i < row; i++) {
for (j = 0; j < colum; j++) {
if (mat[i][j] == i + j) {
count++;
}
}
}
//going over the matrix and add the relevant elements to the array and to the list
(*arr) = (Tripple*)calloc(count, sizeof(Tripple));
for (i = 0; i < row; i++) {
for (j = 0; j < colum; j++) {
if (mat[i][j] == i + j) {
//add element to array
(*arr)[k].argument = mat[i][j];
(*arr)[k].i = i;
(*arr)[k].j = j;
//add element to the list
if (!head) {
tmp = (Node*)malloc(sizeof(Node));
tmp->value = (*arr)[k];
tmp->next = NULL;
head = tmp;
} else {
Node *new_node = (Node*)malloc(sizeof(Node));
new_node->value = (*arr)[k];
new_node->next = NULL;
head->next = new_node;
head = new_node;
}
k++;
}
}
}
*ls = tmp;
return count;
}
void printTrripleArrAndList(Tripple* arr, int n, Node** ls) {
int i, j;
Node* curr = *ls;
printf("The tripple list is: ");
while (curr != NULL) {
printf("%d+%d=%d ->", curr->value.i, curr->value.j, curr->value.argument);
curr = curr->next;
}
printf("\nThe tripple array is: ");
for (i = 0; i < n; i++) {
printf("%d+%d = %d\n", arr[i].i,arr[i].j,arr[i].argument);
}
}
int ** createMat(int*n,int*m) {
int** mat = NULL;
int i, j, row, column;
//allocate and the matrix
printf("please enter size of row and colum: ");
scanf("%d%d", &row, &column);
mat = (int**)calloc(row, sizeof(int*));
for (i = 0; i < row; i++) {
mat[i] = (int*)calloc(column, sizeof(int));
}
//fill the matrix
printf("enter numbers for the matrix: ");
for (i = 0; i < row; i++) {
for (j = 0; j < column; j++) {
scanf("%d", &mat[i][j]);
}
}
*n = row;
*m = column;
return mat;
}
I used to get an error saying a value of type Node* cannot be assigned to an entity of type list* so I had to change them both to Node* The problematic area was:
head->next = new_node;
and:
curr = curr->next;
Please help.
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define M 2
#define N 3
#define R 4
typedef struct Tripple {
int i;
int j;
int argument;
} Tripple;
typedef struct Node {
Tripple value;
struct Node* next;
} Node;
int* powerArray(int n);
void printPowArr(int* p, int n);
int** MatrixMultiplication(int firstMat[M][N], int secondMat[N][R]);
void printMatrix(int** p);
int createTripplesArrayAndList(int** mat, int row, int colum, Tripple **arr, Node** ls);
void printTrripleArrAndList(Tripple* arr, int n, Node** ls);
int** createMat(int* n, int*m);
This is my main :
void main() {
int *p;
int** newMat;
int p1[M][N] = { { 1, 4, 2 }, { 0, 3, 1 } };
int p2[N][R] = { { 1, 3, 1, 4 }, { 0, 2, 6, 4 }, { 4, 1, 0, 7 } };
int **mat=NULL;
int count;
int n = 0, m = 0, i = 0, j = 0;
p = powerArray(10);
printPowArr(p, 10);
newMat = MatrixMultiplication(p1, p2);
printMatrix(newMat);
Tripple* arr=NULL;
Node* ls=NULL;
mat=createMat(&n,&m);
count = createTripplesArrayAndList(mat, n, m, &arr, &ls);
printTrripleArrAndList(arr, count, &ls);
system("pause");
}
You are pointing both the head and head->next to new_node! This is absurd. Remove head->next = new_node.
I tried to reverse an array using only pointers. The program runs without any errors but it doesn't reverse the array. What's wrong with my code?
#include <stdio.h>
#define SIZE 10
void arrayReverseOutput(int * arr);
void arrayInput(int * arr);
void printArray(int * arr);
int main(void)
{
int arr[SIZE] = { 0 };
arrayInput(arr);
arrayReverseOutput(arr);
printArray(arr);
system("PAUSE");
return 0;
}
void arrayInput(int * arr){
int i = 0;
for (i = 0; i < SIZE; i++){
scanf("%d",(arr+i));
}
}
void arrayReverseOutput(int * arr){
int i = 0;
int k = SIZE-1;
int temp = 0;
for (i = 0; i < SIZE; i++){
temp = *(arr+i);
*(arr+i) = *(arr + k);
*(arr + k) = temp;
k--;
}
}
void printArray(int * arr){
int i = 0;
for (i = 0; i < SIZE; i++){
printf("%d ", *(arr+i));
}
}
The problem is, you are actually reversing the array twice, negating any changes achieved by swapping places.
Loop over only half of the array while swapping the elements, like
for (i = 0; i < SIZE/2; i++)
You can use 2 pointers to do so
void arrayReverseOutput(int *head, int *tail)
{
int temp = 0;
do
{
temp = *tail;
*tail = *head;
*head = temp;
}
while (head++ < tail--);
}
Complete code
#include <stdio.h>
#define SIZE 10
void arrayReverseOutput(int *head, int *tail);
void arrayInput(int * arr);
void printArray(int * arr);
int main(void)
{
int arr[SIZE] = { 0 };
arrayInput(arr);
arrayReverseOutput(arr, &arr[SIZE - 1]);
printArray(arr);
return 0;
}
void arrayInput(int * arr)
{
int i = 0;
for (i = 0; i < SIZE; i++)
{
scanf("%d", (arr + i));
}
}
void arrayReverseOutput(int *head, int *tail)
{
int temp = 0;
do
{
temp = *tail;
*tail = *head;
*head = temp;
}
while (head++ < tail--);
}
void printArray(int * arr)
{
int i = 0;
for (i = 0; i < SIZE; i++)
{
printf("%d ", *(arr + i));
}
}