Thread: Linked list problem

  1. #1
    Registered User
    Join Date
    Oct 2006
    Posts
    60

    Linked list problem

    I have to write a program which will convert the input:

    Hello
    World
    Test
    .

    into

    Test
    World
    Hello

    I have written a program so far that takes the input and stores it in a linked list, though I am not entirely sure how I can change this into the output. I have been told not to use arrays, the only idea I have is to try to read each line into a seperate list and then swap them over.

    Though the problem is with this I don't know how many lines will be entered so I don't know how many lists will need to be created.

    I would really appreciate any advice on how I should go about adapting my program to solve this problem.

    Thanks in advance

  2. #2
    Registered User
    Join Date
    Nov 2006
    Posts
    176
    the only idea I have is to try to read each line into a seperate list

    -- do you mean seperate list node?

    if you make a list and just keep adding to the head of the list, they will end up in the order you want

    ie.

    add Hello
    List: Hello
    add World
    List: World -> Hello
    add test
    List: test -> World -> Hello

    print from head to tail. want the orignal as well? use a doubly linked list and keep points to head and tail so you can traverse in either direction

  3. #3
    Registered User
    Join Date
    Oct 2006
    Posts
    60
    This is the code I have used, it reads each character into a seperate node. How would I change the lines I have (currently seperate nodes) into a single node per line?

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    typedef struct List{
            char x;
            struct List *next;
    }list;
    
    list *insertlist(char hd, list *a1){
         list *a = calloc(1,sizeof(list));
         a->x = hd;
         a->next = a1;
         return a;
         free (a);
    }
    
    list *mainlist(){
         list *b = NULL;
         char i = 0;
         while (i != '.'){
               i = getchar();
               b = insertlist(i,b);
               }
         return b;
         }
         
    int main(){
        list *c = calloc(1,sizeof(list));
        list *temp = NULL, *d = NULL ;
        printf("Please enter the phrase you wish to store in a list: \n");
        d = mainlist();
        
        while(d)
        {
           c = d->next;
           d->next = temp;
           temp = d;
           d = c;
        }
        d = temp;
        
        
        
    
        if(d != 0) { 
        printf("\n");
        while(d->next != 0) {
            printf("%c", d->x);
            d = d->next;
        }
        printf("%c", d->x);
    }
        return 0;    
    }

  4. #4
    Registered User
    Join Date
    Nov 2006
    Posts
    176
    Code:
    typedef struct List{
            char x;
            struct List *next;
    }list;
    needs to hold a string, so char x[STRINGLENGTH] or char *x
    Code:
    list *insertlist(char hd, list *a1){
    needs to take char *hd now
    and inside copy the string with strncpy or similar

    in mainlist you will take the whole list from the user and put it in a buffer
    fgets

    that buffer can then be broken up into words deliminated by " "
    those words are then used to call the new insertlist

  5. #5
    Registered User
    Join Date
    Oct 2006
    Posts
    60
    Trouble is don't I need to create an array to hold the string which I am not allowed to do.

    I have modified my code so it now reads it in reverse order and then tries to switch the first line round, although it doesn't seem to work and I can't understand why.

    I would be very grateful if someone could check it over for me, I think the problem is in one of the highlighted areas.

    Thanks

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    typedef struct List{
            char x;
            struct List *next;
    }list;
    
    list *insertlist(char hd, list *a1){
         list *a = calloc(1,sizeof(list));
         a->x = hd;
         a->next = a1;
         return a;
         free (a);
    }
    
    list *mainlist(){
         list *b = NULL;
         char i = 0;
         while (i != '.'){
               i = getchar();
               b = insertlist(i,b);
               }
         return b;
         }
    
    list *lookup(char c, list *head){
         if (head == NULL)
            return NULL;
         else if (c == head->x)
            return head;
         else
             return (lookup(c, head->next));
    }
         
    list *reversewords(list *a){
         list *b;
         list *temp = NULL;
         list *c = calloc(1,sizeof(list));
         a = a->next;
         a = lookup('\n', a);
         b = b->next;
         b = b->next;
         b = lookup('\n', b);
         
         
         while(a < b)
        {
           c = a->next;
           a->next = temp;
           temp = a;
           a = c;
           a++;
        }
        a = temp;
        
        return a;
    }
    
         
    int main(){
        
        list *d = NULL ;
        printf("Please enter the phrase you wish to store in a list: \n");
        d = mainlist();
        d = reversewords(d);
    
        if(d != 0) { 
        printf("\n");
        while(d->next != 0) {
            printf("%c", d->x);
            d = d->next;
        }
        printf("%c", d->x);
    }
        return 0;    
    }

  6. #6
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    Why not use the bidirectional linked list. It can be traversed in any direction - no manipulations needed
    All problems in computer science can be solved by another level of indirection,
    except for the problem of too many layers of indirection.
    – David J. Wheeler

  7. #7
    Registered User
    Join Date
    Oct 2006
    Posts
    60
    I haven't been taught that yet, so I presume I am supposed to use a normal linked list.

  8. #8
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    your reversewords function has several erros
    1. b = b->next;
    b is not initialized, possible GPF
    2. c = a->next;
    previously c was set to allocated memory, now this memory is lost
    3. a++; you allocate one node at time, ++ operation can be used only on pointers pointing to arrays
    Maybe thre is something else

    lookup can be simply done using loop ( no stack overflow possibility)
    All problems in computer science can be solved by another level of indirection,
    except for the problem of too many layers of indirection.
    – David J. Wheeler

  9. #9
    Registered User
    Join Date
    Nov 2006
    Posts
    176
    I see, no arrays period. Are you allowed to change that struct?...is so, an easier method would be to just have an int length member, so everytime you see a space you record the length of that word...otherwise say its -1 or 0 or somthin. then it would only take a small recusive function to take in that list and length and print it correctly.

  10. #10
    Registered User
    Join Date
    Nov 2006
    Posts
    176
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    typedef struct List{
            char x;
            int len;
            struct List *next;
    }list;
    
    list *insertlist(char hd, list *a1, int len){
         list *a = calloc(1,sizeof(list));
         a->x = hd;
         a->len = len;
         a->next = a1;
         return a;
         free (a);
    }
    
    list *mainlist(){
         list *b = NULL;
         int n = 0;
         char i = 0;
    
         while (i != '.'){
               i = getchar();
               if ((i == ' ') || (i == '.')) {
                    b = insertlist(i,b,n);
                    n = 0;
               }
               else
               {
                   b = insertlist(i,b,0);
                   n++;
               }
         }
         return b;
    }
    
    void print_word(list *l, int i)
    {
       if (i != 0)
           print_word(l->next, i-1);
    
       if (l->x == '.')
           printf(" ");
       else printf("%c", l->x);
    }
    
    int main(){
    
        list *d = NULL ;
        list *temp;
    
        printf("Please enter the phrase you wish to store in a list: \n");
        d = mainlist();
    
        temp = d;
        if(temp != 0) {
        printf("\n");
    
        while(temp->next != 0) {
            if (temp->len != 0)
            {
                print_word(temp, temp->len);
            }
            temp = temp->next;
        }
        printf("\n");
    
        }
        return 0;
    }
    heres POC based on your code

    output:
    Please enter the phrase you wish to store in a list:
    Hello World Test.

    Test World Hello

    edit::
    another output
    Please enter the phrase you wish to store in a list:
    This is a LONGER better testing phrase.

    phrase testing better LONGER a is This
    Last edited by sl4nted; 12-07-2006 at 01:31 PM.

  11. #11
    Registered User
    Join Date
    Oct 2006
    Posts
    60
    Thanks for the help, though it doesnt seem to work.

    The code below is my last update, I have no got it to print the last word first. Although the list is no longer linked together so I cannot figure out how to reverse the other words in the list.

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    typedef struct List{
            char x;
            struct List *next;
    }list;
    
    list *insertlist(char hd, list *a1){
         list *a = calloc(1,sizeof(list));
         a->x = hd;
         a->next = a1;
         return a;
         free (a);
    }
    
    list *mainlist(){
         list *b = NULL;
         char i = 0;
         b = insertlist('\n',b);
         while (i != '.'){
               i = getchar();
               b = insertlist(i,b);
               }
         
         return b;
         }
    
    list *lookup(char c, list *head){
         if (head == NULL)
            return NULL;
         while (head->x != c){
               head = head -> next;
         }
         return head;
    
         
    }
         
    list *reversewords(list *a,list *b){
         list *temp = NULL;
         list *c = calloc(1,sizeof(list));
       
         a = a->next;
         a = lookup('\n', a);
         b = b->next;
         b = b->next;
         b = lookup('\n', b);
         
         
         while(a != b)
        {
           c = a->next;
           a->next = temp;
           temp = a;
           a = c;
           
        }
        a = temp;
        
         
        
            
        return a;
    }
    
         
    int main(){
        
        list *d = NULL ;
        printf("Please enter the phrase you wish to store in a list: \n");
        d = mainlist();
        d = reversewords(d,d);
    
        if(d != 0) { 
        printf("\n");
        while(d->next != 0) {
            printf("%c", d->x);
            d = d->next;
        }
        printf("%c", d->x);
    }
        return 0;    
    }

  12. #12
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    you still have a problem with loosing pointer to allocated memory and using uninitialized pointer (now it is a)
    All problems in computer science can be solved by another level of indirection,
    except for the problem of too many layers of indirection.
    – David J. Wheeler

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Need help sorting a linked list. Beginner
    By scarlet00014 in forum C Programming
    Replies: 1
    Last Post: 09-27-2008, 06:16 PM
  2. singly linked circular list
    By DarkDot in forum C++ Programming
    Replies: 0
    Last Post: 04-24-2007, 08:55 PM
  3. Replies: 6
    Last Post: 03-02-2005, 02:45 AM
  4. Linked list with two class types within template.
    By SilasP in forum C++ Programming
    Replies: 3
    Last Post: 02-09-2002, 06:13 AM
  5. singly linked list
    By clarinetster in forum C Programming
    Replies: 2
    Last Post: 08-26-2001, 10:21 PM