You will first create an interface for handling string items.
Basically, you will need to do the following:
Create an interface named item.h Define a type Item represents a char
* (i.e., a c-string) Implement a less function that compares between two strings and return which
one should precede. Then, you will add to the linked list interface
the following functions: linkedlistScanInit: The header of the
function will be linkedlistScaninit(pLinkedList list). The function
takes a linkedlist as input, reads from the command line a set of
strings, and store them inside the linkedlist. You can call the
function linkedlistAddNode to add a node to the end of the linked
list. linkedlistShow: The header of the function will be
linkedlistShow(pLinkedList list). The function takes a linkedlist as
input, loops through the linkedlist and show what inside it
Finally, you will create a main, your main will be as follow:
}
You will use the code in linkedListSt.h and linkedListSt.c
sorry its messy its from a pdf and I didn't seem to be able to adjust it without messing it up even more.
So am being asked to basically sort strings in selection sort method on a linked list. my question here isn't anything code specific but what does "less function to compare two strings" mean. does it mean it only needs the declaration?. would that return a string pointer or a string pointer pointer?. Also, I am having trouble understanding the meaning of linkedlistScanInit?
am not entirely sure what the question is here. its not asking me to sort the actual list or at least thats my poor understanding of it.
I'm guessing they mean a function which compares which of two strings is 'lesser' than the other, alphabetically.
The function declaration could look something like this:
int lessThan(char *a, char *b);
which returns 1 if a is lesser than b, and otherwise 0. I'll leave the implementation up to you.
Good luck
Related
I know that one can act a function on every member of a list using the map function, e.g.,
f(x):=block([x:x], x^2)$
foo:[1,2,3];
map('f,foo);
However, I haven't been able to work out how one would do the equivalent with an array of lists, and a function that acts on lists (vs. list members).
E.g., given bar:[[1,2,3],[a,b,c]]$ I'd like to find a general way to obtain a list of each member of bar concatenated into a string, i.e., the output would be the same as:
[apply('sconcat, bar[1]), apply('sconcat,bar[2])];
I'd actually like to then concatenate the resulting list; however, that seems pretty straightforward, once at this point.
This question already has answers here:
How do function pointers in C work?
(12 answers)
Closed 1 year ago.
I am doing a C exercise where we are given prototypes, and we have to turn them into functions.
I stumbled onto the following prototype:
void ft_lstdelone(t_list *lst, void (*del)(void*))
This function is supposed to delete a node from a linked list, but I don't understand what is happening in the second argument "void (*del)(void*)".
The description of the exercise has:
Parameters -
#1 The element to free.
#2 The address of the function used to delete the content.
Description - Takes as a parameter an element and frees the
memory of the element’s content using the function
’del’ given as a parameter and free the element.
The memory of ’next’ must not be freed.
I take from this that I have to use a function as an argument, but it doesn't make any sense.
Can someone help me unwrap what this means?
It actually makes a lot of sense. It is a function pointer, that is, ft_lstdelone will find the location of the element. If it was the first element, then the new first element will be its next. If it was the last element, then its previous will point to null. Otherwise its previous will point to its next.
However, how will you remove the actual item? Will you call free? It seems to be a logical approach first, but if you think it through, you will realize that it's a naive approach. If your list contains elements of composite types, then calling free on it will free the address of your data, but the inner members of your data will still hold some allocated data. This raises the possible issue of memory leak, so, depending on the data type you have at your item, you will have to free it in different manners. This is only known at the time when you call ft_lsdelone, because at that point you know the data type of your data.
So, in order to be able to cope with the different scenarios, the function separates the concerns. This function is only concerned in the manner of how an item is to be removed from a list, but will not worry about its deallocation. Instead, it trusts its caller with the deallocation and expects to get a function that is assumed to handle the deallocation properly.
I am reading Mastering Algorithms with C by Kyle Loudon, and currently I am struggling with Loudon's implementation of Singly-Linked List in Chapter 5.
Here are the links to the source code. I apologize for not posting them here as they are a bit long.
list.h
list.c
My question is related to the destroy in list.c as it is mentioned in line 11 under
void list_init(List* list, void (*destroy)(void* data))
as list->destroy = destroy
and then again in line 24 as
list->destroy(data).
All I know is that this destroy is different from the function list_destroy but I have no idea what it is. Is it a function or is it just a pointer? What purpose does it serve in the list_init() function for initializing a linked list?
I really appreciate your time and help! The source code is linked above.
It is a function pointer. When you create an instance of this list, you also have to hand the init_list function a function which it will use to destroy the info.
The purpose of a linked list is to store information, and the linked list structure is there to give some structure to
this data. Hence, each element of the list contains a pointer to some data, and a pointer to the next element in the list. However, you want the list to able to handle multiple kinds of data.
Suppose you want to remove an element of the list, then there are basically two things that have to happen:
The data needs to be destroyed
The linked list structure must be restored. Meaning that the predecessor of the element you removed must point to
the next element in the list.
Since you do not know beforehand what kind of data the data pointer in the list will contain, for step 1 a function pointer is provided to handle the destroying of that data.
A linked list is a data structure made up of nodes, each of which contains or links to one piece of data.
The destroy function destroys just one node out of the list.
The list_destroy function destroys an entire list.
In the given implementation, the node actually contains a pointer to its destroy function, and accesses it by dereferencing that pointer. As it happens (so far), all nodes point to the same destroy function. But with more complex data structures this pattern allows multiple types of nodes to be in the data structure. And the equivalent of the list_destroy function will correctly destroy each node type correctly since the node knows how it should be destroyed.
In implementing a single linked list in C, I think there are three ways :
HEADER IS A POINTER ITSELF.IT POINTS TO THE FIRST NODE OF THE LINKED LIST.
1.Declare the header globally and use function void insert(int) to insert.This should work as header is global.
2.Declare header inside main and use function node*insert(node*) to insert.This should work because of the return involved.
3.Declare header inside main and use function void insert(node**) to insert.
Sometimes the second way works even without the return involved. Why?
Which is the better way?
If the functions involved are recursive as in tree which method is appropriate?
You should encapsulate your data structure in a single object (the head node or a struct that contains it), and then you can have your functions work on that object. This means that you can have more than one linked list in your program (that won't work with a global head node) and you can also pass it around to different functions that want to use it (there's no point having a data structure without being able to use it).
If you have your single object (head node) stored in your program then the insert and delete functions don't need to return anything, as you already have a pointer to the object that represents the linked list.
If the functions involved are recursive as in tree which method is appropriate?
The functions should not be recursive "as in tree". The depth of a tree is O(logn), which means recursion is reasonable in many situations; The size of a linked list is O(n), which means recursion can easily overflow the stack.
I've been developing a MathLink application with a function that accepts two lists, e.g.
:Pattern: g[zi_List, fi_List]
which I intended to pull in to the function manually. Both lists can be real or complex with the result being complex if either parameter is complex. Additionally, fi could be a list of square matrices, but zi is to remain a one dimensional list.
Within the MathLink C API, the most straightforward seeming function to use is MLGetReal64Array which can handle both real and complex data types as Complex shows up as the innermost Head of the array. And, once complexity is determined, the array can be cast to std::complex<double> or the C99 complex type, if appropriate. Now, MLGetReal64Array doesn't handle non-rectangular Lists, so each List element must have the dimensionality of the others and be of the same type: real of complex. Oddly, though, with a function that accepts a single List parameter, MLGetReal64Array returns a data structure that has a one element List as its outermost element, i.e. inputing h[ {1, 3, 5} ] returns List[List[1,3,5]] on the c-side of things.
It turns out that for a two list function, like g, a single call to MLGetReal64Array will return both parameters at once, i.e. g receives List[ zi, fi ]. Since I plan on preprocessing each list for uniformity of structure and element type, ensuring that both had the same element type wouldn't be a problem. But, I'd like for fi to be a list of matrices, and MLGetReal64Array causes a MLEGSQ: MLGet() called out of sequence error.
So, my questions are: can I use MLGetReal64Array to get both lists? how would I go about it? And, if I can't use MLGetReal64Array, what are my alternatives?
I'm thinking that if MLGetReal64Array is correct about the structure, I can pop the outer List off the link by using MLGetFunction which would then allow me to use MLGetReal64Array for each parameter. As of yet, I haven't tried it. But, in the meantime, I would appreciate any suggestions.
I'd create separate functions for the different cases you have. It's much easier to handle this logic on the Mathematica side than figure out what you have coming over the link in C.