Exercise on adding elements to a list

In summary: However, it is important to keep in mind that using a static variable can also be a valid and efficient solution in some cases. It ultimately depends on your personal preference and the requirements of the task.
  • #1
RaamGeneral
50
1
(mentor note: moved here from another forum hence no template)

This is the code with also the explanation of the exercise. There is bit of italian, but everything is clear enough.
I actually solved the exercise.

Code:
/*

Add an element of value n before each element of the list that satisfies the property P. count the elements added (return value). this function is recursive.

example:
l: 1 --> 1 --> -1 --> 2 --> -5 --> -4 --> -6 --> 3 --> 0 --> 5 --> //
n=21
P(n) is n>0
result: 21 --> 1 --> 21 --> 1 --> -1 --> 21 --> 2 --> -5 --> -4 --> -6 --> 21 --> 3 --> 0 --> 21 --> 5 --> //
number of items added: 5

my approach:
if (the second element of the list is P) then: add n between the first and the second, repeat with the sublist starting now by "second" (e->next, that now is actually the third...).
else repeat with the sublist starting now by the second

problem: I can't test the first element of the list. so I use a static variable to consider the "first call" of the funcion

*/
int esercizio_2(Lista *l,int n)
{
    static int i=0;
  
    ElementoLista *e;
  
    //list is empty
    if((*l)==NULL) {return 0;}
  
    //last call: reset i.
    if((*l)->next==NULL) {i=0;return 0;}
  
    //first call
    if(i==0){
      
        i=1;
      
        //first element satisfies P
        if(P(&((*l)->info))){
          
            //I add n before the first element
            e=malloc(sizeof(ElementoLista)); e->info=n; e->next=(*l);
            *l=e;
          
            //I count this element added, do the same thing to the sublist, the same as the initial list
            return 1+esercizio_2(&(e->next),n);
          
        }
    }
  
    //element satisfies P
    if(P(&((*l)->next->info))){
      
        //add n between the current element end the next
        e=malloc(sizeof(ElementoLista)); e->info=n; e->next=(*l)->next;
        (*l)->next=e;
      
        //I count this element added, do the same thing to the list starting by the next element
        return 1+esercizio_2(&(e->next),n);
      
    }
  
    //element does not satisfy P; do the same thing to the list starting by the next element
    return esercizio_2(&((*l)->next),n);
  
}
This is the entire code if you want to try (something is missing but it works; note the P takes a pointer as a parameter):

Code:
#include <stdio.h>
#include <stdlib.h>

struct El{
    int info;
    struct El *next;
};

typedef struct El ElementoLista;
typedef ElementoLista *Lista;void lista_init(Lista *l);
void lista_insert(Lista *l,int n);
void lista_insert_array(Lista *l,int *v,int size);
void lista_print(Lista l);
int P(int *n);
int esercizio_2(Lista *l,int n);
int main(int argc,char **argv)
{
  
    Lista l;
    int arr[]={1,1,-1,2,-5,-4,-6,3,-0,5};
    int r;
  
    lista_init(&l);
    lista_insert_array(&l,arr,10);
    lista_print(l);
  
    r=esercizio_2(&l,21);
  
    printf("%d\n",r);
    lista_print(l);
  
    return 0;
}

int P(int *n)
{
    return *n>0;
}

/*

Add an element of value n before each element of the list l that satisfies the property P. count the elements added (return value). this function is recursive.

example:
l: 1 --> 1 --> -1 --> 2 --> -5 --> -4 --> -6 --> 3 --> 0 --> 5 --> //
n=21
P(n) is n>0
result: 21 --> 1 --> 21 --> 1 --> -1 --> 21 --> 2 --> -5 --> -4 --> -6 --> 21 --> 3 --> 0 --> 21 --> 5 --> //
number of items added: 5

my approach:
if (the second element of the list is P) then: add n between the first and the second, repeat with the sublist starting now by "second" (e->next, that now is actually the third...).
else repeat with the sublist starting now by the second

problem: I can't test the first element of the list. so I use a static variable to consider the "first call" of the funcion

*/
int esercizio_2(Lista *l,int n)
{
    static int i=0;
  
    ElementoLista *e;
  
    //list is empty
    if((*l)==NULL) {return 0;}
  
    //last call: reset i.
    if((*l)->next==NULL) {i=0;return 0;}
  
    //first call
    if(i==0){
      
        i=1;
      
        //first element satisfies P
        if(P(&((*l)->info))){
          
            //I add n before the first element
            e=malloc(sizeof(ElementoLista)); e->info=n; e->next=(*l);
            *l=e;
          
            //I count this element added, do the same thing to the sublist, the same as the initial list
            return 1+esercizio_2(&(e->next),n);
          
        }
    }
  
    //element satisfies P
    if(P(&((*l)->next->info))){
      
        //add n between the current element end the next
        e=malloc(sizeof(ElementoLista)); e->info=n; e->next=(*l)->next;
        (*l)->next=e;
      
        //I count this element added, do the same thing to the list starting by the next element
        return 1+esercizio_2(&(e->next),n);
      
    }
  
    //element does not satisfy P; do the same thing to the list starting by the next element
    return esercizio_2(&((*l)->next),n);
  
}

void lista_init(Lista *l)
{
    *l=NULL;
}

void lista_insert(Lista *l,int n)
{
    if(*l==NULL){  
        *l=malloc(sizeof(ElementoLista));
        (*l)->info=n;
        (*l)->next=NULL;
        return;
    }
  
    lista_insert(&((*l)->next),n);
  
  
  
}

void lista_insert_array(Lista *l,int *v,int size)
{
    int i;
  
    for(i=0;i<size;i++) lista_insert(l,v[i]);
  
}

void lista_print(Lista l)
{
    while(l!=NULL){
        printf(" %d -->",l->info);
        l=l->next;
    }
    printf(" //\n");
  
}
I have a couple of questions: is there a better (recursive) algorithm to solve this exercise?
I don't like things like &((*l)->next. What can I do about this?
I once tried assigning *l to a variable, but I remember something didn't work.

Thank you.
 
Last edited by a moderator:
Physics news on Phys.org
  • #2
There is no one-size-fits-all solution to this problem. Every algorithm has its own pros and cons and it depends on the situation which algorithm is best suited for the task. As for your code, you could use a pointer to a pointer instead of &((*l)->next) to make it more readable and easier to maintain. You could also assign *l to a variable and then pass the variable to the recursive call. This would eliminate the need for the static variable.
 

Related to Exercise on adding elements to a list

1. How do I add a single element to a list in Python?

To add a single element to a list in Python, you can use the append() method. This method adds the element to the end of the list. For example, if you have a list called numbers and you want to add the number 10 to the end, you can use numbers.append(10).

2. Can I add multiple elements to a list at once?

Yes, you can add multiple elements to a list at once using the extend() method. This method takes in another list as its argument and adds all the elements from that list to the end of the original list. For example, if you have a list called fruits and you want to add the fruits "apple" and "banana" to the end, you can use fruits.extend(["apple", "banana"]).

3. How can I add an element at a specific position in a list?

You can use the insert() method to add an element at a specific position in a list. This method takes in two arguments: the index where you want to insert the element, and the element itself. For example, if you have a list called colors and you want to insert the color "yellow" at index 2, you can use colors.insert(2, "yellow").

4. Is it possible to add elements to a list in a specific order?

Yes, you can use the insert() method to add elements to a list in a specific order. By inserting elements at different indexes, you can control the order in which they appear in the list. You can also use the sort() method to sort the elements in a list alphabetically or numerically.

5. Can I add elements to a list without changing the original list?

Yes, you can use the copy() method to create a copy of a list and then add elements to the copy without changing the original list. For example, if you have a list called numbers and you want to add the number 5 to a copy of that list, you can use new_numbers = numbers.copy() to create a copy and then use new_numbers.append(5) to add the number 5 to the copy without affecting the original list.

Similar threads

  • Engineering and Comp Sci Homework Help
Replies
1
Views
8K
  • Engineering and Comp Sci Homework Help
Replies
18
Views
1K
  • Engineering and Comp Sci Homework Help
Replies
4
Views
957
  • Engineering and Comp Sci Homework Help
Replies
3
Views
685
  • Programming and Computer Science
Replies
3
Views
1K
  • Engineering and Comp Sci Homework Help
Replies
5
Views
2K
  • Engineering and Comp Sci Homework Help
Replies
10
Views
1K
  • Engineering and Comp Sci Homework Help
Replies
1
Views
1K
  • Engineering and Comp Sci Homework Help
Replies
2
Views
3K
  • Engineering and Comp Sci Homework Help
Replies
17
Views
1K
Back
Top