I have been asked for an assignment to use FisherYates shuffle on an array to be taken in from a file (that, I managed to do) using functions.
int FisherYates(int *player, int n) { //implementation of Fisher
int i, j, tmp; // create local variables to hold values for shuffle
for (i = n - 1; i > 0; i--) { // for loop to shuffle
j = rand(); //randomise j for shuffle with Fisher Yates
tmp = player[j];
player[j] = player[i];
player[i] = tmp;
}
return player;
}
It basically just needs to shuffle the list of players and return me the output so I can print it out in main().
I would very much appreciate it if anyone could show me how to modify the code to make it work, since with this version, I get a error at compile time:
invalid conversion from 'int*' to 'int' [-fpermissive]
You already have the result in player, so returning void should work.
Reference for Fisher-Yates
void FisherYates(int *player, int n) { //implementation of Fisher
int i, j, tmp; // create local variables to hold values for shuffle
for (i = n - 1; i > 0; i--) { // for loop to shuffle
j = rand() % (i + 1); //randomise j for shuffle with Fisher Yates
tmp = player[j];
player[j] = player[i];
player[i] = tmp;
}
}
Two quick things about your function:
rand() requires that srand(...) be called to seed the number generator.
...
srand(clock());
for (i=n-1; i>0; i--){ // for loop to shuffle
j = rand()%n; //randomise j for shuffle with Fisher Yates
...
int FisherYates(int *player, int n) is prototyped to return an int, but you are returning pointer to int Options are to do as Tectrendz suggested and just change the prototype to return void (since player is returned in the arguments), or change the function to return an int *. But this would be redundant because (int *player,... allows the value to be returned via the argument.
Related
I am trying to implement a Left shift/ Right Shift on arrays.
I was able to accomplish this using double loops.
Can I get some help to improve the efficiency?
This is the working code for LeftShift/RightShift which is using 2 loops.
#include <iostream>
#include <stdlib.h>
#include <stdio.h>
struct Array
{
int A[10];
int size;
int length;
};
void Display(struct Array arr)
{
printf("\nElements are : \n");
for(int i = 0;i<arr.length;i++)
printf("%d ", arr.A[i]);
}
// Left Shift-------------------------------------------------------------------------------------------------------
void LeftShift1(struct Array *arr, int n) //n is the number of shifts
{
int temp = arr->A[0];
for(int i=0; i<n; i++)
{
for(int j=0; j<arr->length-1; j++)
{
arr->A[j] = arr->A[j+1];
}
arr->A[arr->length-1] = 0;
}
}
//Right Shift-------------------------------------------------------------------------------------------------------
void RightShift(struct Array *arr, int n) //n is the number of shifts
{
for(int i = 0; i<n; i++)
{
for(int j=arr->length-1; j>0; j--)
{
arr->A[j] = arr->A[j-1];
}
arr->A[0] = 0;
}
}
int main()
{
struct Array arr={{1,2,3,4,5},10,5};
LeftShift1(&arr, 2);
//RightShift(&arr, 1);
Display(arr);
return 0;
}
I'm trying something like this which uses 2 iterators to solve this problem!
This is also working!
void LeftShift2(struct Array *arr, int n)
{
for(int k=0; k<n; k++)
{
int i,j;
for(i=0, j=0; j<arr->length-1; i++, j++)
{
arr->A[j] = arr->A[j+1];
}
arr->A[arr->length-1] = 0;
}
}
But can this be solved without loops? OR with a single loop?
Can this be made more efficient?
some help to improve the efficiency?
Shift: Shift once. Go from O(n*length) to O(length).
Rotate: Shift once into a temporary. Go from O(n*length) to O(length).
Qualify n first.
void LeftShift_alt(struct Array *arr, int n) {
if (n > arr->length) {
n = arr->length;
}
memmove(&arr->A[0], &arr->A[n], (arr->length - n)*sizeof arr->A[0]);
memset(&arr->A[arr->length - n], 0, n * sizeof arr->A[0]);
}
void LeftRotate_alt(struct Array *arr, int n) {
if (arr->length > 0) {
n %= arr->length;
if (n > 0) {
int temp[n];
memcpy(temp, arr->A, sizeof temp);
memmove(arr->A, arr->A + n, sizeof arr->A[0] * (arr->length - n));
memcpy(arr->A + n, temp, sizeof temp);
}
}
}
Replace mem...() with pointer code if desired.
Rather than actually moving the contents of the array around, you could provide all the common accessor operators (<<, >>, [], etc.) in the struct. (Assuming you're using a compiler that supports this. Otherwise, you'll need to create these functions C-style.) If someone did this:
my_array <<= 5;
my_array >>= 2;
...you'd simply keep track of how much the array has been shifted. In this case, they've shifted a total of 3 positions to the left. When someone indexes into the array, you add the accumulated offset to their index (modulo the size of the array) to get the actual location of the entry they're looking for. This makes shifts O(1) instead of O(n). If you're looking for an efficient solution, this is about as good as it gets.
After CODE REVIEW:
In C, efficiency can be improved by using a single loop. Instead of shifting elements one position at a time we can move them n positions!
Something like this:
void LeftShift1(struct Array* arr, unsigned int n) {
if (n > arr->length) {
n = arr->length;
}
for (unsigned int i = 0; i < arr->length; i++) {
if (i + n < arr->length)
arr->A[i] = arr->A[i + n];
else
arr->A[i] = 0;
}
}
In practical usage, we would want to consider doing this array shifting with element types other than a plain int. In fact, it may be a complex type like a string and we should not do raw memcpy on string.
In my code, I was setting the shifted-out elements to 0 which was OK for an integer and related types, but it won't work similarly in string.
As of C++20, there is a standard std::shift_left and std::shift_right ready to use.
There also exists std::rotate which can be used to rotate the elements.
int arr[] = {1,2,3,4,5};
using std::ranges::begin;
using std::ranges::end;
std::shift_left (begin(arr),end(arr),2);
Display(arr);
Also in C++, we should use flexible container like vector in place of struct!
Also If we are doing a lot of adding and removing elements from both ends then there is a container specifically designed for that called deque ("doubly ended queue").
I'm having an issue with my code. Disclaimer btw, I'm new to C. Trying to learn it on my own. Anyways, I'm trying to get the minimum and maximum of an array. I broke the array into 4 parts to make 4 separate arrays and then used those 4 to pass in one of the parameters of each thread. With that being said, I'm only able to get the maximum for each part of the array and not the minimum and I don't understand why.
I think we can simplify your code, avoid all these unnecessary malloc calls, and simplify your algorithm for finding a min/max pair in an array.
Start by having a thread function that takes as input the following: an array (represented by a pointer), an index into the array from where to start searching on, and an index in the array on where to stop. Further, this function will need two output parameters - smallest and largest integer found in the array subset found.
Start with the parameter declaration. Similar to your MaxMin, but has both input and output parameters:
struct ThreadParameters
{
// input
int* array;
int start;
int end;
// output
int smallest;
int largest;
};
And then a thread function that scans from array[start] all the way up to (but not including) array[end]. And it puts the results of its scan into the smallest and largest member of the above struct:
void* find_min_max(void* args)
{
struct ThreadParameters* params = (struct ThreadParameters*)args;
int *array = params->array;
int start = params->start;
int end = params->end;
int smallest = array[start];
int largest = array[start];
for (int i = start; i < end; i++)
{
if (array[i] < smallest)
{
smallest = array[i];
}
if (array[i] > largest)
{
largest = array[i];
}
}
// write the result back to the parameter structure
params->smallest = smallest;
params->largest = largest;
return NULL;
}
And while we are at it, use capitol letters for your macros:
#define THREAD_COUNT 4
Now you can keep with your "4 separate arrays" design. But there's no reason to since the thread function can scan any range of any array. So let's declare a single global array as follows:
#define ARRAY_SIZE 400
int arr[ARRAY_SIZE];
The capitol letter syntax is preferred for macros.
fillArray becomes simpler:
void fillArray()
{
for (int i = 0; i < ARRAY_SIZE; i++)
{
arr[i] = rand() % 1000 + 1;
}
}
Now main, becomes a whole lot simpler by doing these techniques.:
We'll leverage the stack to allocate our thread parameter structure (no malloc and free)
We'll simply start 4 threads - passing each thread a pointer to a ThreadParameter struct. Since the thread won't outlive main, this is safe.
After starting each thread, we just wait for each thread to finish)
Then we scan the list of thread parameters to get the final smallest and largest.
main becomes much easier to manage:
int main()
{
int smallest;
int largest;
// declare an array of threads and associated parameter instances
pthread_t threads[THREAD_COUNT] = {0};
struct ThreadParameters thread_parameters[THREAD_COUNT] = {0};
// intialize the array
fillArray();
// smallest and largest needs to be set to something
smallest = arr[0];
largest = arr[0];
// start all the threads
for (int i = 0; i < THREAD_COUNT; i++)
{
thread_parameters[i].array = arr;
thread_parameters[i].start = i * (ARRAY_SIZE / THREAD_COUNT);
thread_parameters[i].end = (i+1) * (ARRAY_SIZE / THREAD_COUNT);
thread_parameters[i].largest = 0;
pthread_create(&threads[i], NULL, find_min_max, &thread_parameters[i]);
}
// wait for all the threads to complete
for (int i = 0; i < THREAD_COUNT; i++)
{
pthread_join(threads[i], NULL);
}
// Now aggregate the "smallest" and "largest" results from all thread runs
for (int i = 0; i < THREAD_COUNT; i++)
{
if (thread_parameters[i].smallest < smallest)
{
smallest = thread_parameters[i].smallest;
}
if (thread_parameters[i].largest > largest)
{
largest = thread_parameters[i].largest;
}
}
printf("Smallest is %d\n", smallest);
printf("Largest is %d\n", largest);
}
Say I have a pre-specified set S of m items. I would like to generate a random combination of n (unique) items taken from S.
Is there an easy way to implement this in C? I looked into rand() but it didn't seem to do what I want.
(EDIT to add more details)
The specific problem is to randomly choose n distinct elements from an array of size m. My first instinct is to do this:
idx_array = []
int idx = rand() % m
[if idx not in idx_array, add to idx_array. Otherwise repeat above line. Repeat until idx_array has size n]
But it doesn't look like this process is truly random. I'm still new to C and really just want to know if there's a built-in function for this purpose.
Any help appreciated.
Instead of generating a number from 1 to n with the possibility of duplicate, shuffle your array and then pick out of the first n elements:
#include <stdio.h>
#include <stdlib.h>
// Randomly shuffle a array
void shuffle (int * array, int n) {
int i, j, tmp;
for (i = n - 1; i > 0; i--) {
j = arc4random_uniform(i + 1);
tmp = array[j];
array[j] = array[i];
array[i] = tmp;
}
}
int main (int argc, char const *argv[])
{
const int m = 5;
const int n = 3;
int s[m] = {10, 20, 30, 40, 50};
// Make a copy of s before shuffling it
int t[m];
for(size_t i = 0; i < m; i++)
{
t[i] = s[i];
}
shuffle(t, m);
// Now, the first n elements of t is what you want
for(size_t i = 0; i < n; i++)
{
printf("%d ", t[i]);
}
return 0;
}
Credit to Roland Illig for the Fisher-Yate shuffling function.
This is a sampling problem. There are a host of sampling algorithms but a straightforward algorithm which does the job pretty well is known as Reservoir Sampling. Refer geekforgeeks for more details on reservoir sampling.
I want to make a C function for FIR filter, It has a two input arrays and one output array.
both input arrays are constant numbers, I want to use them for computation of output of filter,and after computation delete them and just store the output array of function this is my code but it does not work
#include <stdlib.h>
float * filter(float *PATIENTSIGNAL,float *FILTERCOEF, int lengthofpatient , int lengthoffilter ){
static float FIROUT[8000];
int i,j;
float temp=0;
float* SIGNAL;
float* COEF;
SIGNAL = malloc(lengthofpatient *sizeof(float));
COEF = malloc(lengthoffilter*sizeof(float));
}
for (j = 0; j <= lengthofpatient; j++){
temp = SIGNAL[j] * COEF[0];
for (i = 1; i <= lengthoffilter; i++){
if ((j - i) >= 0){
temp += SIGNAL[j - i] * COEF[i];
}
FIROUT[j] = temp;
}
}
free(SIGNAL);
free(COEF);
free(PATIENTSIGNAL);
return FIROUT;
}
There are several problems in your code,
Unnecessary } after line COEF = malloc(lengthoffilter*sizeof(float));.
for (j = 0; j <= lengthofpatient; j++). This will loop once more than required. The same for the i loop. pmg mentioned it in the comment.
temp += SIGNAL[j - i] * COEF[i]; will not give you the desired outcome, as you do not initialized both SIGNAL or COEF.
Whats the purpose of float *PATIENTSIGNAL,float *FILTERCOEF in the function parameter?
From a wild guess, I think you need this two line to initialize SIGNAL and/or COEF.
memccpy(SIGNAL, PATIENTSIGNAL, lengthofpatient);
memccpy(COEF, FILTERCOEF, lengthoffilter);
Don't free PATIENTSIGNAL in your local function. Let this be done by the function caller.
For my assignment, my code must have 3 source files:
main.c (Handles input and output, as well as top-level program logic.)
node.h (Declares the data structure and function quicksort, which sorts a given doubly linked list with the ascending order), and printlist, which prints a linked list to the screen.
node.c (Defines the function quicksort and printlist, as declared in node.h.)
The main function must use scanf function call to read the input data from keybord (note that the input redirection can be used to directly read the data from a data file). The number of data (in the data file) is not pre-determined.
this is the code that my instructor gave me. I'm really confused, do I need to break the code into 3 parts, if so how?
#include<stdio.h>
void qsort(int a[10], int first, int last);
int main() {
int i, n, a[10], j, pivot, last, t;
printf("enter the no of elements\n");
scanf("%d", &n);
printf("enter the elements\n");
for (i = 0; i < n; i++)
scanf("%d", &a[i]);
qsort(a, 0, n - 1);
printf("sorted elements is\n");
for (i = 0; i < n; i++)
printf("\n%d", a[i]);
}
void qsort(int a[10], int first, int last) {
int i, j, t, pivot, n;
if (first < last) {
i = first;
j = last;
pivot = first;
while (i < j) {
while (a[i] <= a[pivot] && i < last)
i++;
while (a[j] > a[pivot])
j--;
if (i < j) {
t = a[i];
a[i] = a[j];
a[j] = t;
}
}
t = a[pivot];
a[pivot] = a[j];
a[j] = t;
qsort(a, first, j - 1);
qsort(a, j + 1, last);
}
}
Although your instructor gave you a qsort that sorts an array, she expects you to implement it on linked lists. Maybe that's just an example of how quicksort works?
Anyway, you will probably need to copy that main into a main.c file. That file will need to include node.h. Inside of it you will declare the list structures, a way to create them, quicksort and a function that prints the list on screen. Inside o node.c you will implement everything you declared on node.h.
You should use the defined qsort only as a reference and you probably need to make changes to main so it creates a list you coded instead of an array.
That's what I make of your assignment, but you should probably clear things up with your instructor.