Union Find - Quick Find - c

I just started the Princeton Algorithms course and tried to implement a very basic quick find algorithm in C as follows -
#include <stdio.h>
void find(int *, int, int);
void unite(int *, int, int);
int main() {
int arr[10], i, n1, n2, opt;
char ch;
for (i = 0; i < 10; i++)
arr[i] = i;
do {
printf("1. Find\n2. Union\n");
scanf("%d", &opt);
if (opt == 1) {
scanf("%d,%d", &n1, &n2);
find(arr, n1, n2);
}
if (opt == 2) {
scanf("%d,%d", &n1, &n2);
unite(arr, n1, n2);
}
for (i = 0; i < 10; i++)
printf("%d ", arr[i]);
printf("Continue? (Y/N)");
getchar();
scanf("%c", &ch);
} while (ch == 'Y');
}
void find(int *id, int p, int q) {
if ((*(id + p)) == (*(id + q)))
printf("Connected\n");
}
void unite(int *id, int p, int q) {
int i;
for (i = 0; i < 10; i++) {
if ((*(id + i)) == (*(id + p)))
*(id + i) = *(id + q);
}
}
The program isn't running as it is supposed to. When I try to do a union(4,3) and then a union(3,8), only arr[3] changes its value and not arr[4]. Also, I'm not sure why I had to use getchar (the program kept ending without it).

This line:
if((*(id+i))==(*(id+p)))
is equivalent to:
if (id[i] == id[p])
and tests the current id for i with the current id for p.
The problem is that id[p] may have already been changed to id[q]!
So when you try to turn all 3's into 8's, after we change arr[3] to 8, from then on we are only changing 8's into 8's.
Instead try storing the current id for p, and testing against that:
void unite(int *id, int p, int q)
{
int i;
int id_to_change = id[p];
for(i=0;i<10;i++)
{
if(id[i] == id_to_change)
id[i] = id[q];
}
}

Related

Reallocating my Memory doesnt work properly but i dont know what im doing wrong. Any idea?

code: (at //right here is the line that doesnt work)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
void insert(int size, char *arr);
void swap(char *arr, int pos1, int pos2);
void printList(int size, char *arr);
int main()
{
int size = 0;
do
{
printf("Put in size of the list (Range[1;2^16-1]): ");
scanf(" %d", &size);
if (size < 0)
printf("Put in a correct length!\n");
} while (size <= 0);
printf("Put in ur List: ");
char buffer[size];
int errFlag;
do
{
errFlag = 1;
while (fgets(buffer, size + 2, stdin))
{
}
for (int i = 0; i < size; i++)
if (!isdigit(buffer[i]))
errFlag = 0;
if (errFlag == 0)
printf("Input failed try again:");
} while (errFlag == 0);
char *list = malloc(size*sizeof(char));
strcpy(list, buffer);
insert(size, list);
printList(size, list);
int input = 0;
do
{
printf("\nDo u want to add another element(0) or a list(1)? If u want to stop type (2): ");
scanf(" %d", &input);
if (input != 0 && input != 1 && input != 2)
printf("\nInput failed try again: ");
else if (input == 1)
{
int tempElem = 0;
printf("Input ur element: ");
scanf(" %d", &tempElem);
size++;
printf("%d", tempElem);
list = (char *)realloc(list, size + 1); //right here
list[size-1]=tempElem;
printf("New ");
insert(size, list);
printList(size, list);
}
} while (input != 0);
return 0;
}
void insert(int size, char *arr)
{
for (int i = 1; i < size; i++)
for (int j = i - 1; j >= 0; j--)
if (arr[j] > arr[j + 1])
swap(arr, j, j + 1);
else
j = 0;
}
void swap(char *arr, int pos1, int pos2)
{
char temp = arr[pos1];
arr[pos1] = arr[pos2];
arr[pos2] = temp;
}
void printList(int size, char *arr)
{
printf("ArrayList: ");
for (int i = 0; i < size; i++)
{
printf("[");
printf("%d", arr[i]-48);
printf("] ");
}
}
My code works properly until the reallocation, but i dont get an error. The programm just stops (VScode). I did some research but didnt find any solution.
Output:
Put in size of the list (Range[1;2^16-1]): 3
Put in ur List: 123
^Z (my input to stop f gets)
ArrayList: [1] [2] [3]
Do u want to add another element(0) or a list(1)? If u want to stop type (2): 1
Input ur element: 3
3
Then it stops. Normally i would expect: New ArrayList: [1] [2] [3] [4]

How can I delete a user inputed element/data from an Array in Structure? [duplicate]

How to delete an element from the array of type structure? Let's say if I register an item and then want to delete it how can I do that? The delete function is at the end of the code. I want to delete the item by giving the varunummer (id number). Any one know how to do it?
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#define WORDLENGTH 30
#define MAX 5
struct varor {
int varunummer;
char namn[WORDLENGTH];
int lagersaldo;
};
int readLine(char s[], int length);
int ifVarunummerExist(int varunummer, const struct varor reg[], int nrOfGoods);
void registerVaror(struct varor reg[], int *nrOfGoods);
void getPrint(const struct varor reg[], int nrOfGoods);
void avregristreraVaror(struct varor reg[], int nrOfGoods);
int main(void) {
struct varor vRegister[WORDLENGTH];
int nrOfGoods = 0;
int run = 1;
while (run) {
char choice;
printf("\n\t\tMeny - Lager Program\n\n\
(1) Register\n\b\b\b\b\
(2) Print\n\
(3) Delete\n\
(4) Quit\n");
scanf(" %c%*c", &choice);
if (choice=='1')
registerVaror(vRegister, &nrOfGoods);
if (choice=='2')
getPrint(vRegister, nrOfGoods);
if (choice=='3')
avregristreraVaror(vRegister, nrOfGoods);
else if (choice=='4')
run = 0;
}
return 0;
}
int ifVarunummerExist(int varunummer, const struct varor reg[], int nrOfGoods) {
int i;
for (i = 0; i < nrOfGoods; i++)
if(reg[i].varunummer == varunummer)
return i;
return -1;
}
int readLine(char s[], int length) {
int ch, i=0;
while (isspace(ch=getchar()));
while (ch != '\n' && ch != EOF) {
if (i < length)
s[i++] = ch;
ch = getchar();
}
s[i] = '\0';
return i;
}
void registerVaror(struct varor reg[], int *nrOfGoods) {
char namn[WORDLENGTH], tmp[WORDLENGTH];
int varunummer, lagersaldo;
if (*nrOfGoods == MAX) {
printf("\nError! Finns inte plats kvar!\n");
return;
}
printf("Ange varunummer: ");
scanf("%d", &varunummer);
if (ifVarunummerExist(varunummer, reg, *nrOfGoods) >= 0) {
printf("\nVarunummer finns redan!\n");
return;
}
reg[*nrOfGoods].varunummer = varunummer;
printf("Ange namn: ");
readLine(reg[*nrOfGoods].namn, WORDLENGTH);
printf("Ange lagersaldo :");
scanf("%d", &reg[*nrOfGoods].lagersaldo);
//reg[*nrOfGoods]=createVara(varunummer,namn,lagersaldo);
(*nrOfGoods)++;
}
void getPrint(const struct varor reg[], int nrOfGoods) {
int i;
printf("\nVarunummer \t Namn \t\t\t Lagersaldo\n");
for (i = 0; i < nrOfGoods; i++) {
printf(" %d \t\t %s \t\t\t %d\n",reg[i].varunummer,reg[i].namn,reg[i].lagersaldo);
}
}
void avregristreraVaror(struct varor reg[], int nrOfGoods) {
int run = 1;
while (run) {
char choice;
printf("\n (1) Delete \n (2) Exit");
scanf(" %c", &choice);
//DELETE IF CHOICE 1---------
if (choice == '1') {
int i, varunummer;
printf("Ange varunummer: ");
scanf("%d", &varunummer);
for (i = varunummer + 1; i < MAX; i++) {
reg[i - 1] = reg[i];
}
reg[i] = 0;
}
}
//QUIT TO MY MENU CHOICE 2--------
if (choice == '2')
run = 0;
}
You can try iterating through the array in a for loop UNTIL your varunummer is matched with the struct's property. Something along these lines (let's say you are searching for the member with varunummer = varunummerToLookFor), this shift all the elements in the array from the point onwards of your deletion by 1, hence, producing an array with the same sequence as before but with your wanted element removed. Hope that helps!
for(int i = 0, i < varorArraySize, i++){
if(varunummerToLookFor == varorArray[i].varunummer){
for (i = pos; i < varorArraySize - 1; i++)
{
varorArray[i] = varorArray[i + 1];
}
}
}

Crashing issue, might be due to a for loop

My program keeps crashing while I run it. I have isolated parts of it (using /**/) to try and figure out what the issue is, and I think it has something to do with the second for loop in my sort function, since isolating that prevents the crashing. However, I've tried fixing it in several different ways (using while/do loops instead, etc), but it manages to keep crashing. Ive also looked at the parameters and how I declared it in main, but I can't see an issue with that. Knowing me, its probably something really dumb ive been missing for hours trying to fix this. Any help would be greatly appreciated
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define SIZE 5
struct student
{
char name[20];
int hw1, hw2, hw3, ex1, ex2, totalhw, totalex;
float classperc;
char grade;
};
void student_info(struct student s[], int n, int *classex1, int *classex2, int *a, int *b, int *c, int *d, int *f)
{
for (int i = 0; i < n; i++)
{
printf("\n\nPlease enter the student's name:\n");
gets_s(s[i].name, 20);
printf("\nPlease enter the student's homework grades:\n");
scanf("%d %d %d", &(s[i].hw1), &(s[i].hw2), &(s[i].hw3));
printf("\nPlease enter the student's exam scores:\n");
scanf("%d %d", &(s[i].ex1), &(s[i].ex2));
getchar();
s[i].totalhw = s[i].hw1 + s[i].hw2 + s[i].hw3;
s[i].totalex = s[i].ex1 + s[i].ex2;
*classex1 += s[i].ex1;
*classex2 += s[i].ex2;
s[i].classperc = ((float)s[i].totalhw / 1.875) + ((float)s[i].totalex / 3.333);
if (s[i].classperc >= 90)
{
*a = *a + 1;
s[i].grade = 'A';
}
else if (s[i].classperc >= 80)
{
*b = *b + 1;
s[i].grade = 'B';
}
else if (s[i].classperc >= 70)
{
*c = *c + 1;
s[i].grade = 'C';
}
else if (s[i].classperc >= 60)
{
*d = *d + 1;
s[i].grade = 'D';
}
else
{
*f = *f + 1;
s[i].grade = 'F';
}
}
}
void sort(struct student s[], int n)
{
struct student temp;
for (int i = 0; i < SIZE - 1; i++)
{
for (int j = i + 1; j< SIZE; j++)
{
if (strcmp(s[i].name, s[j].name) > 0)
{
temp = s[i];
s[i] = s[j];
s[j] = temp;
}
}
}
for (int i = 0; i < n; i++)
{
printf("\nStudent: %s\nThe Three Homework Scores: %d %d %d\nThe Two Exam Scores: %d %d\n", s[i].name, s[i].hw1, s[i].hw2, s[i].hw3, s[i].ex1, s[i].ex2);
printf("Total Homework Score: %d\nTotal Exam Score: %d\nClass Percentage: %f Grade: %s", s[i].totalhw, s[i].totalex, s[i].classperc, s[i].grade);
// It crashes right before executing this second printf statement (I have no idea why :[)
}
}
void avg_exams(int classex1, int classex2, float *avgex1, float *avgex2)
{
*avgex1 = classex1 / (float)5;
*avgex2 = classex2 / (float)5;
}
void print_classinfo(float avgex1, float avgex2, int a, int b, int c, int d, int f)
{
printf("\n\nThe Average Exam Score for Exam 1 is: %0.2f\nThe Average Exam Score for Exam 2 is: %0.2f\n", avgex1, avgex2);
printf("There were %d A's, %d B's, %d C's, %d D's, %d F's in the class overall\n\n", a, b, c, d, f);
}
void main()
{
struct student s[SIZE];
int a, b, c, d, f , classex1, classex2;
a = b = c = d = f = 0;
classex1 = classex2 = 0;
float classperc, avgex1, avgex2;
student_info( s, SIZE, &classex1, &classex2, &a, &b, &c, &d, &f);
sort(s, SIZE);
avg_exams(classex1, classex2, &avgex1, &avgex2);
print_classinfo(avgex1, avgex2, a, b, c, d, f);
system("PAUSE");
}
Check out your printf() format codes. You can break it into smaller chunks for debugging, to see which portion of the printf() is working unexpectedly.
I don't think the crash is due to your for loops.

scanf not passing value to variable

I wanted to ask a little bit about scanf in C using Xcode IDE. If I not initially set value for variable choice, anytime I open my program and enter any choice(either 1/2) it will go to else case every time. So I check the value after select any choice then I got a strange number. Could you please take a look at my code. Thank you in advance.
Here's my actual code:
/* Bubble Sort using MPI */
#include <stdio.h>
#include <stdlib.h>
#include <mpi.h>
#include <time.h>
#define N 1000
double startT,stopT;
double startTime;
void showElapsed(int id, char *m)
{
printf("%d: %s %f secs\n",id,m,(clock()-startTime)/CLOCKS_PER_SEC);
}
void showVector(int *v, int n, int id)
{
int i;
printf("%d: ",id);
for(i=0;i<n;i++)
printf("%d ",v[i]);
putchar('\n');
}
int * merge(int *v1, int n1, int *v2, int n2)
{
int i,j,k;
int * result;
result = (int *)malloc((n1+n2)*sizeof(int));
/*
i : pointer of v1
j : pointer of v2
k : pointer of k
*/
i=0; j=0; k=0;
while(i<n1 && j<n2)
if(v1[i]<v2[j])
{
result[k] = v1[i];
i++; k++;
}
else
{
result[k] = v2[j];
j++; k++;
}
if(i==n1)
while(j<n2)
{
result[k] = v2[j];
j++; k++;
}
else
while(i<n1)
{
result[k] = v1[i];
i++; k++;
}
return result;
}
void swap(int *v, int i, int j)
{
int t;
t = v[i];
v[i] = v[j];
v[j] = t;
}
void sort(int *v, int n)
{
int i,j;
for(i=n-2;i>=0;i--)
for(j=0;j<=i;j++)
if(v[j]>v[j+1])
swap(v,j,j+1);
}
int main(int argc, char **argv)
{
int * data;
int * chunk;
int * other;
int m,n=N;
int id,p;
int s;
int i;
int step;
int choice = 0;
//start asking user to select option between sequential or parallel version of BubbleSort
printf(":: Welcome to BubbleSort Project for CSS333 ::\n");
printf("Please select option that you prefer\n");
printf("Type \"1\" for sequential mode or \"2\" for parallel mode\n");
printf("");
fflush(stdout);
scanf("Enter here: %d", &choice);
printf("Test value of choice(should be either 1 or 2): %d\n", choice);
//end asking
if(choice == 1){
// do seq
printf("You have selected option 1 which is running BubbleSort in Sequential mode\n");
printf("Please wait...");
}
else if(choice == 2){
// do parallel
printf("You have selected option 2 which is running BubbleSort in parallel mode\n");
printf("Please wait...");
MPI_Status status;
MPI_Init(&argc,&argv);
MPI_Comm_rank(MPI_COMM_WORLD,&id);
MPI_Comm_size(MPI_COMM_WORLD,&p);
if(id==0)
{
int r;
srandom(clock());
s = n/p;
r = n%p;
data = (int *)malloc((n+p-r)*sizeof(int));
for(i=0;i<n;i++)
data[i] = random();
if(r!=0)
{
for(i=n;i<n+p-r;i++)
data[i]=0;
s=s+1;
}
startT = clock();
MPI_Bcast(&s,1,MPI_INT,0,MPI_COMM_WORLD);
chunk = (int *)malloc(s*sizeof(int));
MPI_Scatter(data,s,MPI_INT,chunk,s,MPI_INT,0,MPI_COMM_WORLD);
sort(chunk,s);
}
else
{
MPI_Bcast(&s,1,MPI_INT,0,MPI_COMM_WORLD);
chunk = (int *)malloc(s*sizeof(int));
MPI_Scatter(&data,s,MPI_INT,chunk,s,MPI_INT,0,MPI_COMM_WORLD);
sort(chunk,s);
}
step = 1;
while(step<p)
{
if(id%(2*step)==0)
{
if(id+step<p)
{
MPI_Recv(&m,1,MPI_INT,id+step,0,MPI_COMM_WORLD,&status);
other = (int *)malloc(m*sizeof(int));
MPI_Recv(other,m,MPI_INT,id+step,0,MPI_COMM_WORLD,&status);
chunk = merge(chunk,s,other,m);
s = s+m;
}
}
else
{
int near = id-step;
MPI_Send(&s,1,MPI_INT,near,0,MPI_COMM_WORLD);
MPI_Send(chunk,s,MPI_INT,near,0,MPI_COMM_WORLD);
break;
}
step = step*2;
}
if(id==0)
{
FILE * fout;
stopT = clock();
printf("%d; %d processors; %f secs\n",N,p,(stopT-startT)/CLOCKS_PER_SEC);
fout = fopen("result","w");
for(i=0;i<s;i++)
if (chunk[i] != 0)
fprintf(fout,"%d\n",chunk[i]);
fclose(fout);
}
MPI_Finalize();
}
else{
printf("Invalid value\n");
printf("Program exiting...\n");
exit(0);
}
}
This is your problem:
scanf("Enter here: %d", &choice);
You might be expecting this to display "Enter here: " then accept a number as input and store it in the variable choice. But that's not what it does.
What this does is that it goes through the formatting string ("Enter here: %d"), one character by one. For each character that is not '%', it reads a character from stdin and compares them together. If they don't match, it pushes the character back to the buffer of stdin and stops scanning.
So unless the user types in something starting with Enter here: followed immediately by a number, it fails at reading that number.
What you probably wanted to do is to:
printf("Enter here: ");
scanf("%d", &choice);
(and then read the documentation for scanf().

C programm to find middle number

Hi this is my code to find the middle number of three but when i give a=3 b=2 and c=1 i get wrong output.How can i find the right middle number?Is there any way with arrays?
thank you
#include<stdio.h>
int main()
{
int a,b,c;
int min,mid,max,i=1;
printf("Enter number: ");
scanf("%d",&a);
printf("\nEnter number: ");
scanf("%d",&b);
printf("\nEnter number: ");
scanf("%d",&c);
if(((a<b)&&(b<c)) || ((a>b)&&(a<c)))
{
min=a;
mid=b;
max=c;
}
if(((b<a)&&(a>c)) || ((a>b)&&(a<c)))
{
min=c;
mid=a;
max=b;
}
if(((c<a)&&(c>b)) || ((c>a)&&(c<b)))
{
min=b;
mid=c;
max=a;
}
printf("\nMid is %d",mid);
for(i=min;i<=max;i++)
{
if(i==mid)
continue;
printf("\n%d",i);
}
getchar();
getchar();
}
To make your life easier, write a function called min. It takes two integers and returns the one which is smaller. Now use this function like this:
int min = min(min(a,b),c);
Similar with max.
To get the mid value, just make this calculation:
int mid = a + b + c - max - min;
If you have a sorted array:
int nums[N];
Then:
For N even the median is: (nums[N/2] + nums[(N/2)-1])/2
For N odd the median is: nums[(N-1)/2]
If your array is not sorted, then check the Median of Medians
if you are able to find maximum and minimum values, you can find the middle value like this:
int a = 1, b = 2, c = 3;
int minVal = min(a, b);
int maxVal = max(maxVal, c);
int midVal = a + b + c - maxVal - minVal;
midVal should contain the middle value of those 3 numbers.
Sorting with an array is pretty simple:
#include<stdio.h>
#include<errno.h>
#include<string.h>
#include<stdlib.h>
int compar( const void *a, const void *b)
{
return *(int*)a > *(int*)b;
}
void die(const char *msg)
{
if( errno )
fprintf(stderr, "%s: %s\n", strerror(errno), msg);
else
fprintf(stderr, "%s\n", msg);
exit(EXIT_FAILURE);
}
int get_input(void)
{
int ret;
errno = 0;
if( scanf("%d", &ret ) != 1 )
die("invalid input");
return ret;
}
void * xmalloc(size_t s)
{
void *ret;
ret = malloc(s);
if(ret == NULL)
die("malloc");
return ret;
}
int main(int argc, char **argv)
{
int *a;
int *b;
int count;
count = get_input();
a = b = xmalloc( count * sizeof *a);
while(count-- > 0)
*b++ = get_input();
qsort(a, b - a, sizeof *a, compar);
printf("sorted:");
while(a != b)
printf(" %d", *a++);
putchar('\n');
return EXIT_SUCCESS;
}
int a,b,c;
if(b>a && a>c || c>a && a>b)
printf("The middle number is a");
else if(a>b && b>c || c>b && b>a)
printf("The middle number is b");
else
printf("The middle number is c");

Resources