I'm supposed to write a function called - "disAssemblyList" that gets a linked list of chars(without a dummy element). The function should move a nodes with big letters to "bigLetter" linked list (without a dummy element) , move nodes with small letters to "smallLetter" linked list, nums to "nums" linked list and other chars keep into original list.
I need to pass by reference the smallLetter, bigLetter and nums linked lists and return the list with other chars.
I need to scan the original list. The original list can be empty.
for example:
An original linked list:
3-> a-> 7-> M-> K-> u-> 5-> #-> &-> P-> %-> A
bigLetter
:
M-> K-> P-> A
smallLetter
:
a-> u
nums
:
3-> 7-> 5
other chars (original list after the function runs):
#-> &-> %
I wrote this code and I cant seem to understand how to make it work. It does not scan the chars to linked list.
typedef struct chNode
{
char data;
struct chNode *next;
}chNode;
chNode * createCharList(char data)
{
chNode *temp = (chNode*)malloc(sizeof(chNode));
temp->data = data;
temp->next = NULL;
return temp;
}
chNode * addCharToLast(chNode *head, char data)
{
chNode *p = head;
chNode *temp = createCharList(data);
if (head == NULL)
return temp;
while (p->next != NULL)
p = p->next;
p->next = temp;
return head;
}
void printf_CharList(chNode *head)
{
chNode *p = head;
while (p != NULL)
{
printf("%d, ", p->data);
p = p->next;
}
printf("\n\n");
}
chNode* insert_Charlist() // A function that imports numbers into a linked list , till -1
{
char ch;
chNode *Head = NULL;
printf("Enter chars For Linked-List Till 'Enter':\n");
//5scanf_s("%c", &ch);
ch = getchar();
while (ch != "\n")
{
Head = addCharToLast(Head, ch); //Makes last number to be First
//scanf_s("%c", &ch);
ch = getchar();
}
return Head;
}
void add_to_other_list(chNode** head, chNode* p)
{
static chNode* tail = NULL;
p->next = NULL;
if (tail == NULL)
{
*head = p;
}
else
{
tail->next = p;
}
tail = p;
}
chNode* disAssemblyList(chNode* p, chNode **bigLetter, chNode **smallLetter, chNode **nums)
{
chNode* t = NULL;
if (p == NULL) return p; // 0 elements
if (p->next == NULL) return p; // 1 element
if (p->next->next == NULL) // 2 elements
{
if ((p->next->data >= 65) && (p->next->data) <= 90)
{
// Move p->next to other list
add_to_other_list(&(*bigLetter), p->next);
p->next = NULL;
return p;
}
}
// Repeat as long as the list has minimum 3 elements
while (p->next)
{
if ((p->next->data >= 65) && (p->next->data) <= 90)
{
// Move p-next
t = p->next;
p->next = p->next->next;
add_to_other_list(&(*bigLetter), t);
}
if ((p->next->data >= 97) && (p->next->data) <= 122)
{
t = p->next;
p->next = p->next->next;
add_to_other_list(&(*smallLetter), t);
}
if ((p->next->data >= 48) && (p->next->data) <= 57)
{
t = p->next;
p->next = p->next->next;
add_to_other_list(&(*nums), t);
}
p = p->next;
}
return p;
}
void main()
{
chNode *Orignial_list = NULL;
chNode *bigLetter = NULL;
chNode *smallLetter = NULL;
chNode *nums = NULL;
Orignial_list = insert_Charlist(); // Function that imports a list
printf("You Entered This linked-list:\n");
printf_CharList(Orignial_list); //Printing the linked list
Orignial_list = disAssemblyList(Orignial_list,&bigLetter,&smallLetter,&nums);
printf("The BigLetter Linked-List is:\n");
printf_CharList(bigLetter);
printf_CharList(smallLetter);
printf_CharList(nums);
printf_CharList(Orignial_list);
getch();
}
I have not looked through all your code because as I have understood the question is about one function implementation that splits an original list to some other lists.
Though I am sure that there are drawbacks in your code as for example the function print_CharList
outputs internal codes of characters instead of characters stored in a list themselves.
void printf_CharList(chNode *head)
{
chNode *p = head;
while (p != NULL)
{
printf("%d, ", p->data);
p = p->next;
}
printf("\n\n");
}
Or the function add_to_other_list
with a static variable does not make a sense.
Or this condition in beginning of the function disAssemblyList
if (p->next == NULL) return p; // 1 elementNevertheless the function
also does not make a sense.
Nevertheless the function that splits a list can look as it is shown in the demonstrative program below.
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
typedef struct chNode
{
char data;
struct chNode *next;
} chNode;
void clear( chNode **head )
{
while ( *head != NULL )
{
chNode *tmp = *head;
*head = ( *head )->next;
free( tmp );
}
}
size_t assign( chNode **head, const char *s )
{
if ( *head ) clear( head );
size_t n = 0;
while ( *s && ( *head = malloc( sizeof( chNode ) ) ) != NULL )
{
( *head )->data = *s++;
( *head )->next = NULL;
head = &( *head )->next;
++n;
}
return n;
}
FILE * display( const chNode *head, FILE *fp )
{
for ( ; head != NULL; head = head->next )
{
fprintf( fp, "%c -> ", head->data );
}
fputs( "null", fp );
return fp;
}
chNode * disAssemblyList( chNode *p,
chNode **bigLetter,
chNode **smallLetter,
chNode **nums )
{
while ( *bigLetter ) bigLetter = &( *bigLetter )->next;
while ( *smallLetter ) smallLetter = &( *smallLetter )->next;
while ( *nums ) nums = &( *nums )->next;
chNode **head = &p;
while ( *head != NULL )
{
if ( isdigit( ( unsigned char )( *head )->data ) )
{
*nums = *head;
*head = ( *head )->next;
( *nums )->next = NULL;
nums = &( *nums )->next;
}
else if ( isupper( ( unsigned char )( *head )->data ) )
{
*bigLetter = *head;
*head = ( *head )->next;
( *bigLetter )->next = NULL;
bigLetter = &( *bigLetter )->next;
}
else if ( islower( ( unsigned char )( *head )->data ) )
{
*smallLetter = *head;
*head = ( *head )->next;
( *smallLetter )->next = NULL;
smallLetter = &( *smallLetter )->next;
}
else
{
head = &( *head )->next;
}
}
return p;
}
int main(void)
{
chNode *head = NULL;
assign( &head, "3a7MKu5#&P%A" );
fputc( '\n', display( head, stdout ) );
putchar( '\n' );
chNode *bigLetter = NULL;
chNode *smallLetter = NULL;
chNode *nums = NULL;
head = disAssemblyList( head, &bigLetter, &smallLetter, &nums );
fputc( '\n', display( head, stdout ) );
fputc( '\n', display( bigLetter, stdout ) );
fputc( '\n', display( smallLetter, stdout ) );
fputc( '\n', display( nums, stdout ) );
clear( &head );
clear( &bigLetter );
clear( &smallLetter );
clear( &nums );
return 0;
}
The program output is
3 -> a -> 7 -> M -> K -> u -> 5 -> # -> & -> P -> % -> A -> null
# -> & -> % -> null
M -> K -> P -> A -> null
a -> u -> null
3 -> 7 -> 5 -> null
If you are not allowed to use standard C functions from the header <ctype.h>
then the while loop in the function disAssemblyList
can look like
while ( *head != NULL )
{
char c = ( *head )->data;
if ( '0' <= c && c <= '9' )
{
*nums = *head;
*head = ( *head )->next;
( *nums )->next = NULL;
nums = &( *nums )->next;
}
else if ( 'A' <= c && c <= 'Z' )
{
*bigLetter = *head;
*head = ( *head )->next;
( *bigLetter )->next = NULL;
bigLetter = &( *bigLetter )->next;
}
else if ( 'a' <= c && c <= 'z' )
{
*smallLetter = *head;
*head = ( *head )->next;
( *smallLetter )->next = NULL;
smallLetter = &( *smallLetter )->next;
}
else
{
head = &( *head )->next;
}
}