#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <limits.h>
typedef struct List List;
typedef struct ListNode ListNode;
struct ListNode {
List *list;
ListNode *next;
ListNode *prev;
};
void ListNode_init (ListNode *node) {
node->next = 0;
node->prev = 0;
node->list = 0;
}
void ListNode_separate (ListNode *node) {
if (node->list == 0) return;
node->next->prev = node->prev;
node->prev->next = node->next;
ListNode_init(node);
}
struct List {
ListNode head;
};
void List_init (List *l) {
l->head.list = l;
l->head.next = &l->head;;
l->head.prev = &l->head;;
}
int List_member (List *l, ListNode *node) {
return node->list == l;
}
int List_empty (List *l) {
return l->head.next == &l->head;
}
ListNode * List_front (List *l) {
return l->head.next;
}
ListNode * List_end (List *l) {
return &l->head;
}
void List_add (List *l, ListNode *node) {
if (node->list) ListNode_separate(node);
node->next = l->head.prev->next;
l->head.prev->next = node;
node->prev = l->head.prev;
l->head.prev = node;
node->list = l;
}
#define ALPHABET_SIZE UCHAR_MAX
ListNode letters[ALPHABET_SIZE];
List list1;
List list2;
const char *printable (int x) {
static char buf[5] = " ' '";
buf[2] = x;
return buf;
}
void dump_list (List *l) {
if (l
== &list1
) printf("list1: "); ListNode *node = List_front(l);
while (node != List_end(l)) {
printf("%s", printable
(node
- letters
)); node = node->next;
}
}
int main (int argc, char *argv[]) {
const char *input = "the quick brown fox jumped over the lazy dog";
const unsigned char *p;
if (argc > 1) input = argv[1];
List_init(&list1);
List_init(&list2);
for (p = (const void *)input; *p; ++p) {
ListNode *node = &letters[c];
if (List_member(&list1, node)) {
List_add(&list2, node);
} else if (!List_member(&list2, node)) {
List_add(&list1, node);
}
}
if (List_empty(&list1)) {
puts("No non-repeating letters."); } else {
char x = List_front(&list1) - letters;
printf("first non-repeating char: %#04x%s\n", x
, printable
(x
)); }
return 0;
}