Array of structures lose data while passing it in C - arrays

I don't understand why printq() function prints 0, but when I access it back in main() it prints. I don't understand what I am doing wrong, I tried using pointers, but I get some different error in the priority queue. I want to print elements in array pq[10].
EDIT: I realized that the elements are stored but when I use pq[R].data it prints
but when I use pq[i].data in printq() and put it inside for loop, it prints zero.
#include <stdio.h>
int F = -1, R = -1;
int item, max = 10;
struct prioq {
int data;
int prio;
};
struct prioq pq[10] = { 0 };
void printq()
{
int i = 0;
printf("%d,", pq[i].data);
printf("QUEUE :");
for (i = 0; i < max; i++) {
printf("%d,", pq[i].data);
}
printf("\n");
printf("PRIO :");
for (i = 0; i < max; i++) {
printf("%d,", pq[i].prio);
}
}
void enqueue(int item, int p, struct prioq pq[])
{
if (F == -1 && R == -1 || F > R) {
F == 0;
R == 0;
pq[R].data = item;
pq[R].prio = p;
printf("%d", pq[R].data);
printf("%d", pq[R].prio);
printq();
} else if (R == max-1 || R > max) {
printf("overflow\n");
} else if (R < max) {
R++;
pq[R].data = item;
pq[R].prio = p;
printq();
}
}
void dequeue(struct prioq pq[])
{
int large = 0;
if (F == -1) {
printf("underflow\n");
} else {
int i;
for (i = 0; i < max; i++) {
if (pq[i].prio > large) {
large = i;
}
}
}
item = pq[large].data;
pq[large].prio = 0;
pq[large].data = 0;
printf("item deleted: %d\n", item);
printq();
}
void main()
{
int item = 0;
int c = 0, p = 0;
do {
printf("choose your option\n");
printf("1.Insert, 2.Delete, 3.Exit\n" );
scanf("%d", &c);
switch (c) {
case 1:
printf("Enter the priority and element to insert\n");
scanf("%d %d", &item, &p);
enqueue(item,p,pq);
printf("%d", pq[R].data);
printf("%d", pq[R].prio);
break;
case 2:
dequeue(pq);
break;
default:
c = 3;
break;
}
} while (c != 3);
printf("exited\n");
}

In your enqueue function, change the == in the F and R assignments to =.
void enqueue(int item, int p, struct prioq pq[])
{
if (F == -1 && R == -1 || F > R) {
F = 0; // Here
R = 0; // And here
pq[R].data = item;
pq[R].prio = p;
printf("%d", pq[R].data);
printf("%d", pq[R].prio);
printq();
} else if (R == max-1 || R > max) {
printf("overflow\n");
} else if (R < max) {
R++;
pq[R].data = item;
pq[R].prio = p;
printq();
}
}

Related

K-ary tree with array implementation in C

Hi everyone so i got this task to make an adt of non-binary tree which can do traversals. I messed up the structure from the very beginning but I still can do the post-order and pre-order traversal (i don't know if i did it wrong too, but it works). Now i confused how to do the in-order traversal. My code just doesn't work.
This is my data structure
typedef char infotype;
typedef int letak;
typedef struct {
infotype info;
letak parent, firstson, nextsibling;
} node;
typedef node tree;
These are how I initialize each node
void initNode(tree T[], int k, int i)
{
char info;
printf("Input the node name : ");
scanf(" %c", &info);
createNode(T, k, i, info);
}
void createNode(tree T[], int k, int i, char value)
{
int j;
if(i == 0)
{
T[i].info = value;
T[i].firstson = i+1;
}
else
{
T[i].info = value;
T[i].parent = (i-1) / k;
T[i].firstson = (i * k) + 1;
if (i % k != 0)
{
T[i].nextsibling = i+1;
}
else
{
T[i].nextsibling = 0;
}
}
}
and this is how I try to do the in-order traversal
void InOrder(tree T[], int maksimum_array, int maksimum_anak)
{
bool Resmi = true;
int i = 0;
while(i >= 0)
{
if(T[i].firstson < maksimum_array - 1 && Resmi == true)
{
i = T[i].firstson;
}
else
{
if(Resmi == true)
{
printf("%c ", T[i].info);
}
if(i = T[T[i].parent].firstson)
{
printf("%c ", T[T[i].parent].info);
}
if(T[i].nextsibling < maksimum_array - 1 && T[i].nextsibling != 0)
{
i = T[i].nextsibling;
Resmi = true;
}
else
{
i = T[i].parent;
Resmi = false;
}
}
}
}
And this is my main driver :
int main()
{
tree pohon[1000];
int maksimum;
int maksimum_anak;
int level;
int i = 0;
int count = 0;
char cari;
printf("Enter array maximum amount : ");
scanf("%d", &maksimum);
printf("\nEnter maximum child of each node : ");
scanf("%d", &maksimum_anak);
createTree(pohon);
for (i = 0; i < maksimum ; i++)
{
initNode(pohon, maksimum_anak, i);
}
for (i = 0; i < maksimum; i++)
{
printTree(pohon, i, maksimum, maksimum_anak);
}
printf("In Order Traversal : ");
InOrder(pohon, maksimum, maksimum_anak);
}
I've tried another algorithms for the in-order traversal like using recursive. But since i messed up the struct those algorithms just did not work. Thank you before.
if(i = T[T[i].parent].firstson)
Should be
if(i == T[T[i].parent].firstson)
The former assigns to i, the latter compares it.

My BFS code is only showing the direct paths from source to destination, but not all possible paths

I want to print all possible paths from a given source and destination. But in my BFS code, it only shows the two paths, not the multiple path. For a directed graph where n = 4, edge = 6, given,
1-2
1-3
1-5
5-3
5-4
3-4
3-2
It should've printed 3 paths:
1-5-4
1-3-4
1-5-3-4
But it only shows this two paths
1-3-4
1-5-4
This is my sample code for finding the src to destination path
#include <stdio.h>
int queue1[100], state[100], parent[100];
int front = 0, rear = -1, maxSize = 100;
int count = 0;
int initial = 1, waiting = 2, visited = 3;
int n, e;
int adj[100][100];
bool isEmpty()
{
return count == 0;
}
bool isFull()
{
return count == maxSize;
}
void enqueue(int val)
{
if (!isFull())
{
if (rear == maxSize - 1)
{
rear = -1;
}
rear++;
queue1[rear] = val;
count++;
}
}
int dequeue()
{
int val = queue1[front];
front++;
if (front == maxSize)
{
front = 0;
}
count--;
return val;
}
void BFS_Traversal(int src, int des)
{
int done = 0;
enqueue(src);
state[src] = waiting;
parent[src] = -1;
printf("path ");
while (!isEmpty() && done == 0)
{
src = dequeue();
// printf("%d ",src);
state[src] = visited;
for (int i = 1; i <= n; i++)
{
if (adj[src][i] == 1 && state[i] == initial)
{
enqueue(i);
state[i] = waiting;
parent[i] = src;
if (i == des)
{
state[i] = initial;
int k = des;
do
{
printf("%d ", k);
k = parent[k];
} while (k != -1);
printf("\n");
}
}
}
}
}
int main()
{
int src, start, end, des;
scanf("%d%d", &n, &e);
for (int i = 1; i <= e; i++)
{
scanf("%d%d", &start, &end);
adj[start][end] = 1;
}
for (int i = 1; i <= n; i++)
{
state[i] = initial;
}
for (int k = 1; k <= n; k++)
{
parent[k] = -1;
}
scanf("%d%d", &src, &des);
BFS_Traversal(src, des);
}
As, you can see 1-5-3-4 path is not showing because they are already visited. How should I modify this code to print all possible paths?

Possible mode error

I've made this program that computes the mean, the median and the mode from an array. Although I've tested with some examples, I found out there might be a case that I have forgotten as for many of the inputs I've tested it works but the testing program that my teacher is using gave me an error for a certain test, but I was not presented with its input. Maybe someone can have a look and see if I am making a mistake at the mode point of the code:
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
void *safeMalloc(int n) {
void *p = malloc(n);
if (p == NULL) {
printf("Error: malloc(%d) failed. Out of memory?\n", n);
exit(EXIT_FAILURE);
}
return p;
}
int main(int argc, char *argv[]) {
int n, i;
scanf("%d", &n);
int *array = safeMalloc(n * sizeof(int));
for (i = 0; i < n; i++) {
int value;
scanf("%d", &value);
array[i] = value;
}
//mean
double mean;
double sum = 0;
for (i = 0; i < n; i++) {
sum = sum + (double)array[i];
}
mean = sum / n;
printf("mean: %.2f\n", mean);
//median
float temp;
int j;
for (i = 0; i < n; i++)
for (j = i + 1; j < n; j++) {
if (array[i] > array[j]) {
temp = array[j];
array[j] = array[i];
array[i] = temp;
}
}
printf("median: %d\n", array[n / 2]);
//mode
int val = array[0], noOfRepetitions = 1, valMax = array[0], maxRepetitions = 1, possibleMax = 1;
for (i = 1; i < n; i++) {
if (array[i] == val) {
noOfRepetitions++;
}
if (array[i] != val) {
val = array[i];
noOfRepetitions = 1;
}
if (noOfRepetitions == possibleMax) {
maxRepetitions = 1;
continue;
}
if (noOfRepetitions > maxRepetitions) {
valMax = val;
maxRepetitions = noOfRepetitions;
possibleMax = maxRepetitions;
}
}
if (maxRepetitions > 1) {
printf("mode: %d\n", valMax);
} else {
printf("mode: NONE\n");
}
return 0;
}
My idea for mode was because the numbers are sorted when just transverse it. If the next element is the same as the previous one, increase the noOfRepetitions. If the noOfRepetition is bigger than the maxRepetitions until now, replace with that. Also store the last maximum val needed if we have for example more than 2 numbers with the same number of repetitions.
EDIT: The mode of an array should return the number with the maximum number of occurrences in the array.If we have 2 or more number with the same number of maximum occurrences , there isn't a mode on that array.
I've discovered my mistake. I didn't think of the case when I have numbers with same maximum frequency and after that came one with lower frequency but still bigger than others. For example : 1 1 1 2 2 2 3 3 4 5 6.With my code , the result would have been 3 . I just needed to change the comparison of noOfRepetitions with oldMaxRepetition.
There seems to be no purpose for the variable possibleMax. You should just remove these lines:
if(noOfRepetitions==possibleMax){
maxRepetitions=1;
continue;
}
They cause maxRepetitions to be reset erroneously.
You could detect if the distribution is multimodal and print all mode values:
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
void *safeMalloc(int n) {
void *p = malloc(n);
if (p == NULL) {
printf("Error: malloc(%d) failed. Out of memory?\n", n);
exit(EXIT_FAILURE);
}
return p;
}
int main(int argc, char *argv[]) {
int n, i;
if (scanf("%d", &n) != 1 || n <= 0)
return 1;
int *array = safeMalloc(n * sizeof(int));
for (i = 0; i < n; i++) {
if (scanf("%d", &array[i]) != 1)
return 1;
}
//mean
double sum = 0;
for (i = 0; i < n; i++) {
sum = sum + (double)array[i];
}
printf("mean: %.2f\n", sum / n);
//median
int j;
for (i = 0; i < n; i++) {
for (j = i + 1; j < n; j++) {
if (array[i] > array[j]) {
int temp = array[j];
array[j] = array[i];
array[i] = temp;
}
}
}
printf("median: %d\n", array[n / 2]);
//mode
int val = array[0], noOfRepetitions = 1, valMax = array[0], maxRepetitions = 1;
for (i = 1; i < n; i++) {
if (array[i] == val) {
noOfRepetitions++;
if (noOfRepetitions > maxRepetitions) {
valMax = val;
maxRepetitions = noOfRepetitions;
}
} else {
val = array[i];
noOfRepetitions = 1;
}
}
if (maxRepetitions == 1) {
printf("mode: NONE\n");
} else {
printf("mode: %d", valMax);
val = array[0];
noOfRepetitions = 1;
for (i = 1; i < n; i++) {
if (array[i] == val) {
noOfRepetitions++;
} else {
if (noOfRepetition == maxRepetitions && val != valMax) {
printf(", %d", val);
}
val = array[i];
noOfRepetitions = 1;
}
}
if (noOfRepetition == maxRepetitions && val != valMax) {
printf(", %d", val);
}
printf("\n");
}
return 0;
}
Your code to search a mode seems too complicated. Compare this:
//mode
int val = array[0], noOfRepetitions = 1,
valMax = array[0], maxRepetitions = 1;
for (i = 1; i < n; i++) {
if (array[i] == val) {
if (++noOfRepetitions > maxRepetitions) {
valMax = val;
maxRepetitions = noOfRepetitions;
}
}
else
{
val = array[i];
noOfRepetitions = 1;
}
}
It's probably the simplest code to do what you need, but it overwrites maxVal and maxRepetitions much too often.
The following version overwrites the two 'max' variables only once per each new maximum found – at the cost of duplicating some part of code:
//mode
int val = array[0], noOfRepetitions = 1,
valMax = array[0], maxRepetitions = 1;
for (i = 1; i < n; i++) {
if (array[i] == val) {
++noOfRepetitions;
}
else
{
if (noOfRepetitions > maxRepetitions) {
valMax = val;
maxRepetitions = noOfRepetitions;
}
val = array[i];
noOfRepetitions = 1;
}
}
if (noOfRepetitions > maxRepetitions) {
valMax = val;
maxRepetitions = noOfRepetitions;
}

Intermittent Failure with Blackjack code

The purpose of this code is to play a simulated game of Blackjack. The 'Dealer' is automated and will deal two cards to itself and stop when it wins/busts or hits 17. Then the user draws until he/she is satisfied. Then a winner is determined.
I've run into a brick wall because the code compiles fine, but when it runs it will either work (and by work I mean not work as intended but it will run) or it will crash.
I have no idea how this can happen only some of the time and not all of the time and I need some help.
Here is my code:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define SIZE 52
#define LIMIT 21
enum faces{Ace = 0, Jack = 10, Queen, King};
char * facecheck(int d);
void shuffle( int deck[]);
int draw(int deck[SIZE]);
void printcards(int hand[], int numCards);
int dealer(int deck[]);
int player(int deck[]);
int value(int yourhand[]);
int victory(int d, int p);
int i, numCards = 1;
int top = 52;
int preValue = 0;
int count = 2;
int main()
{
int deck[SIZE], i, a;
int d, p;
char suits[4][9] =
{
"Hearts",
"Diamonds",
"Clubs",
"Spades"};
srand( time( NULL ) ) ;
for(i = 0; i<SIZE; i++)
{
deck[i] = i;
};
shuffle(deck);
d = dealer(deck);
p = player(deck);
victory(d, p);
return 0;
}
char * facecheck(int d)
{
static char * face[] =
{
"Ace",
"Jack",
"Queen",
"King" };
if(d == Ace)
return face[0];
else
{
if(d == Jack)
return face[1];
else
{
if(d == Queen)
return face[2];
else
{
if(d == King)
return face[3];
}
}
}
}
void shuffle( int deck[])
{
int i, j, temp;
for(i = 0; i < SIZE; i++)
{
j = rand() % SIZE;
temp = deck[i];
deck[i] = deck[j];
deck[j] = temp;
}
printf("The deck has been shuffled \n");
}
int draw(int deck[SIZE])
{
int numCards = 1;
int i;
int hand[numCards];
int card;
for(i = 0; i < numCards && top > 0; i++)
{
card = deck[top-1];
hand[i] = card;
top--;
}
return card;
}
void printcards(int hand[], int numCard)
{
char suits[4][9] =
{
"Hearts",
"Diamonds",
"Clubs",
"Spades"};
for(i = 0; i < numCard; i++)
{
int card = hand[i];
if(card%13 == 0 || card%13 == 10 || card%13 == 11 || card%13 == 12)
printf("%s ", facecheck(card%13) );
else
printf("%d ", card%13+1);
printf("of %s \n", suits[card/13]);
}
}
int dealer(int deck[])
{
int x;
int a;
int yourhand[10];
int handIndex = 0;
int cardLimit;
int dealerValue;
yourhand[handIndex] = draw(deck);
yourhand[handIndex] = draw(deck);
printf("The Dealers second card is:");
printcards(yourhand, handIndex+1);
cardLimit = value(yourhand);
do
{
if(cardLimit == LIMIT)
{
printcards(yourhand, handIndex+1);
dealerValue = cardLimit;
return dealerValue;
}
if(cardLimit > LIMIT)
{
printcards(yourhand, handIndex+1);
dealerValue = cardLimit;
return dealerValue;
}
if(cardLimit == 17)
{
printcards(yourhand, handIndex+1);
dealerValue = cardLimit;
return dealerValue;
}
if(cardLimit <= 16)
{
yourhand[handIndex] = draw(deck);
cardLimit = value(yourhand);
}
}
while(cardLimit <= LIMIT);
handIndex++;
}
int player(int deck[])
{
int x;
int a;
int yourhand[10];
int cardLimit;
int playerValue;
int handIndex = 2;
yourhand[handIndex] = draw(deck);
yourhand[handIndex] = draw(deck);
cardLimit = value(yourhand);
printf("Your hand is: /n");
printcards(yourhand, handIndex+1);
printf("%d /n" , cardLimit);
do
{
if(cardLimit == LIMIT)
{
printcards(yourhand, handIndex+1);
playerValue = cardLimit;
return playerValue;
}
if(cardLimit > LIMIT)
{
printcards(yourhand, handIndex+1);
playerValue = cardLimit;
return playerValue;
}
else
{
printf("What would you like to do: Press 1 to Hit. 2 to Stay. \n");
scanf("%d" , &x);
if(x == 1)
{
yourhand[handIndex] = draw(deck);
cardLimit == value(yourhand);
}
else
{
printf("Player choses to stay \n");
return playerValue;
}
}
}
while(cardLimit <= LIMIT);
handIndex++;
}
int value(int yourhand[])
{
int faceValue = 10;
int cardValue[count];
int aceValue = 11;
int card[count];
int value;
int curvalue;
for(i = 0; i < count; i++)
{
card[i] = yourhand[i];
}
for(i = 0; i < count; i++)
{
cardValue[i] = card[i]%13;
}
if(cardValue[0] >= 10 && cardValue[1] >= 10)
{
value = 20;
}
if(cardValue[0] < 10 && cardValue[1] < 10)
{
value = cardValue[0] + cardValue[1];
}
if(cardValue[0] >= 10 && cardValue[1] < 10)
{
value = faceValue + cardValue[1];
}
if(cardValue[0] < 10 && cardValue[1] >= 10)
{
value = faceValue + cardValue[0];
}
if(cardValue[0] == 0 && cardValue[1] == 0)
{
value = 12;
}
if(cardValue[0] == 0 && cardValue[1] >= 10)
{
value = 21;
}
if(cardValue[1] == 0 && cardValue[0] >= 10)
{
value = 21;
}
if(cardValue[0] == 0 && cardValue[1] < 10)
{
value = aceValue + cardValue[1];
}
if(cardValue[1] == 0 && cardValue[0] < 10)
{
value = aceValue + cardValue[0];
}
preValue = value;
if(count > 2)
{
if(cardValue[count] != 0)
{
value = curvalue;
value = preValue + curvalue;
}
else
{
if(cardValue[count] + preValue > LIMIT)
{
value = preValue + 1;
}
else
{
value = cardValue[count] + aceValue;
}
}
}
count++;
return value;
}
int victory(int d, int p)
{
if(d > p)
printf("Dealer Wins \n");
else
printf("Player Wins");
}
In your code
int dealer(int deck[])
{
int handIndex = 0;
int yourhand[10];
yourhand[handIndex] = draw(deck);
yourhand[handIndex] = draw(deck);
you never change handIndex, so these two assignments are to the same element (ie, the second draw overwrites the first)
cardLimit = value(yourhand);
now, having written to yourhand[0] twice, and without initialising any other elements, you call value which expects yourhand[0] and yourhand[1] to be initialised.
This should be visible under valgrind (you're reading random values from uninitialized memory).

Having trouble coming up with a 'display function' or added functionality - c

Finishing up a program and been told that I need to have the cards be displayed after the user quits.
Tried having draw return the hand variable and printing that, and storing each result of the draw(), which I had turned to int; although I am showing you the working function, which is void.
So far nothing works and I am lost.
void draw(int deck[SIZE], int a) {
int numCards = 10;
int i;
int hand[numCards];
int card;
for(i = 0; i < numCards && top > 0; i++) {
card = deck[top-1];
hand[i] = card;
top--;
}
if(a != 0) {
printcards(card);
} else {
for(i = 0; i < numCards && top > 0; i++)
printcards(card);
}
}
Program can print off cards as drawn and edited version looks like:
int draw(int deck[SIZE], int a) {
int numCards = 10;
int i;
int hand[numCards];
int card;
for(i = 0; i < numCards && top > 0; i++) {
card = deck[top-1];
hand[i] = card;
top--;
}
if(a != 0) {
printcards(card);
} else {
for(i = 0; i < numCards && top > 0; i++)
printcards(card);
}
return card; /* or return hand */
}
void printcards(int card) {
char suits[4][9] = {
"Hearts",
"Diamonds",
"Clubs",
"Spades"
};
if(card%13 == 0 || card%13 == 10 || card%13 == 11 || card%13 == 12) {
printf("%s ", facecheck(card%13) );
} else {
printf("%d ", card%13+1);
}
printf("of %s \n", suits[card/13]);
}
This function is the actual printing of cards:
void players(int deck[]) {
int x;
int a;
int yourhand[10];
a = 1;
printf("Player 1 \n");
printf("Your Hand is: \n");
draw(deck, a);
draw(deck, a);
while(a == 1) {
printf("What would you like to do: Press 1 to Draw. 2 to Stay. \n");
scanf("%d" , &x);
if(x == 1) {
draw(deck, a);
} else {
a--;
}
}
}
This function calls the draw() with user input, then need to add a display() after the else, before a-- or store result of draw into your hand and print result. So far nothing has worked.

Resources