fork download
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <ctype.h>
  4. #include <limits.h>
  5.  
  6. typedef struct List List;
  7. typedef struct ListNode ListNode;
  8.  
  9. struct ListNode {
  10. List *list;
  11. ListNode *next;
  12. ListNode *prev;
  13. };
  14.  
  15. void ListNode_init (ListNode *node) {
  16. node->next = 0;
  17. node->prev = 0;
  18. node->list = 0;
  19. }
  20.  
  21. void ListNode_separate (ListNode *node) {
  22. if (node->list == 0) return;
  23. node->next->prev = node->prev;
  24. node->prev->next = node->next;
  25. ListNode_init(node);
  26. }
  27.  
  28. struct List {
  29. ListNode head;
  30. };
  31.  
  32. void List_init (List *l) {
  33. l->head.list = l;
  34. l->head.next = &l->head;;
  35. l->head.prev = &l->head;;
  36. }
  37.  
  38. int List_member (List *l, ListNode *node) {
  39. return node->list == l;
  40. }
  41.  
  42. int List_empty (List *l) {
  43. return l->head.next == &l->head;
  44. }
  45.  
  46. ListNode * List_front (List *l) {
  47. return l->head.next;
  48. }
  49.  
  50. ListNode * List_end (List *l) {
  51. return &l->head;
  52. }
  53.  
  54. void List_add (List *l, ListNode *node) {
  55. if (node->list) ListNode_separate(node);
  56. node->next = l->head.prev->next;
  57. l->head.prev->next = node;
  58. node->prev = l->head.prev;
  59. l->head.prev = node;
  60. node->list = l;
  61. }
  62.  
  63. #define ALPHABET_SIZE UCHAR_MAX
  64. ListNode letters[ALPHABET_SIZE];
  65. List list1;
  66. List list2;
  67.  
  68. const char *printable (int x) {
  69. static char buf[5] = " ' '";
  70. if (!isprint(x)) return " .";
  71. buf[2] = x;
  72. return buf;
  73. }
  74.  
  75. void dump_list (List *l) {
  76. if (l == &list1) printf("list1: ");
  77. else printf("list2: ");
  78. ListNode *node = List_front(l);
  79. while (node != List_end(l)) {
  80. printf("%s", printable(node - letters));
  81. node = node->next;
  82. }
  83. puts("");
  84. }
  85.  
  86. int main (int argc, char *argv[]) {
  87. const char *input = "the quick brown fox jumped over the lazy dog";
  88. const unsigned char *p;
  89. if (argc > 1) input = argv[1];
  90. List_init(&list1);
  91. List_init(&list2);
  92. for (p = (const void *)input; *p; ++p) {
  93. int c = tolower(*p);
  94. if (!isalpha(c)) continue;
  95. ListNode *node = &letters[c];
  96. if (List_member(&list1, node)) {
  97. List_add(&list2, node);
  98. } else if (!List_member(&list2, node)) {
  99. List_add(&list1, node);
  100. }
  101. }
  102. if (List_empty(&list1)) {
  103. puts("No non-repeating letters.");
  104. } else {
  105. char x = List_front(&list1) - letters;
  106. printf("first non-repeating char: %#04x%s\n", x, printable(x));
  107. }
  108. return 0;
  109. }
Success #stdin #stdout 0s 2248KB
stdin
Standard input is empty
stdout
first non-repeating char: 0x71 'q'