fork download
  1. /*
  2. ------------------------------------------------------------
  3. TRAVEL EXPERIENCE BROWSER
  4. Data Structures Mini Project (C Language)
  5.  
  6. DATA STRUCTURES USED:
  7. 1) Singly Linked List - Stores travel destinations dynamically
  8. 2) Stack - Stores recently viewed destination IDs (LIFO)
  9. 3) Queue - Stores recommendation requests (FIFO)
  10.  
  11. FEATURES:
  12. - View all destinations
  13. - View destination by ID (pushes to stack)
  14. - Search destinations by City / Type
  15. - Sort destinations by Rating (descending)
  16. - Recently viewed (stack display)
  17. - Add recommendation request (queue enqueue)
  18. - Process recommendation request (queue dequeue + match)
  19. ------------------------------------------------------------
  20. */
  21.  
  22. #include <stdio.h>
  23. #include <stdlib.h>
  24. #include <string.h>
  25. #include <ctype.h>
  26.  
  27. /* ---------- CONSTANTS ---------- */
  28. #define MAX_NAME 50
  29. #define MAX_CITY 30
  30. #define MAX_TYPE 20
  31. #define MAX_EXP 200
  32.  
  33. /* =========================================================
  34.   1) LINKED LIST: Destination Node
  35.   ========================================================= */
  36. typedef struct Destination {
  37. int id; /* Unique destination ID */
  38. char name[MAX_NAME]; /* Destination name */
  39. char city[MAX_CITY]; /* City */
  40. char type[MAX_TYPE]; /* Beach/Hill/Heritage etc. */
  41. int rating; /* 1 to 5 rating */
  42. char experience[MAX_EXP]; /* Short experience text */
  43. struct Destination *next; /* Pointer to next node */
  44. } Destination;
  45.  
  46. /* =========================================================
  47.   2) STACK: Recently Viewed (stores destination IDs)
  48.   ========================================================= */
  49. typedef struct StackNode {
  50. int destId; /* Viewed destination ID */
  51. struct StackNode *next; /* Next stack node */
  52. } StackNode;
  53.  
  54. /* =========================================================
  55.   3) QUEUE: Recommendation Requests
  56.   ========================================================= */
  57. typedef struct ReqNode {
  58. char user[MAX_NAME]; /* User name */
  59. char prefType[MAX_TYPE]; /* Preferred type */
  60. int minRating; /* Minimum rating */
  61. struct ReqNode *next; /* Next request node */
  62. } ReqNode;
  63.  
  64. typedef struct Queue {
  65. ReqNode *front; /* Front pointer */
  66. ReqNode *rear; /* Rear pointer */
  67. } Queue;
  68.  
  69. /* ---------- FUNCTION DECLARATIONS ---------- */
  70.  
  71. /* Utilities */
  72. static void trim_newline(char *s);
  73. static int containsIgnoreCase(const char *text, const char *pat);
  74.  
  75. /* Linked list operations */
  76. Destination* createDestination(int id, const char *name, const char *city,
  77. const char *type, int rating, const char *exp);
  78. void addDestination(Destination **head, Destination *node);
  79. void displayAll(Destination *head);
  80. Destination* searchById(Destination *head, int id);
  81. void searchDestinations(Destination *head);
  82. void sortByRating(Destination *head);
  83.  
  84. /* Stack operations */
  85. void push(StackNode **top, int id);
  86. void displayStack(StackNode *top);
  87.  
  88. /* Queue operations */
  89. void initQueue(Queue *q);
  90. void enqueue(Queue *q, const char *user, const char *type, int minRating);
  91. ReqNode* dequeue(Queue *q);
  92. void processRecommendation(Queue *q, Destination *head);
  93.  
  94. /* Seed/sample data */
  95. void seedData(Destination **head);
  96.  
  97. /* =========================================================
  98.   UTILITY FUNCTIONS
  99.   ========================================================= */
  100.  
  101. /* Remove trailing newline from fgets() input */
  102. static void trim_newline(char *s) {
  103. if (s == NULL) return;
  104. s[strcspn(s, "\n")] = '\0';
  105. }
  106.  
  107. /* Case-insensitive substring check:
  108.   returns 1 if 'pat' exists inside 'text', else 0 */
  109. static int containsIgnoreCase(const char *text, const char *pat) {
  110. if (pat == NULL || pat[0] == '\0') return 1;
  111. if (text == NULL) return 0;
  112.  
  113. char tbuf[300], pbuf[80];
  114. int i;
  115.  
  116. for (i = 0; text[i] && i < (int)sizeof(tbuf) - 1; i++)
  117. tbuf[i] = (char)tolower((unsigned char)text[i]);
  118. tbuf[i] = '\0';
  119.  
  120. for (i = 0; pat[i] && i < (int)sizeof(pbuf) - 1; i++)
  121. pbuf[i] = (char)tolower((unsigned char)pat[i]);
  122. pbuf[i] = '\0';
  123.  
  124. return (strstr(tbuf, pbuf) != NULL);
  125. }
  126.  
  127. /* =========================================================
  128.   LINKED LIST FUNCTIONS
  129.   ========================================================= */
  130.  
  131. /* Create a new destination node */
  132. Destination* createDestination(int id, const char *name, const char *city,
  133. const char *type, int rating, const char *exp) {
  134. Destination *n = (Destination*)malloc(sizeof(Destination));
  135. if (n == NULL) {
  136. printf("Memory allocation failed while creating destination.\n");
  137. return NULL;
  138. }
  139.  
  140. n->id = id;
  141. strncpy(n->name, name, MAX_NAME - 1); n->name[MAX_NAME - 1] = '\0';
  142. strncpy(n->city, city, MAX_CITY - 1); n->city[MAX_CITY - 1] = '\0';
  143. strncpy(n->type, type, MAX_TYPE - 1); n->type[MAX_TYPE - 1] = '\0';
  144. n->rating = rating;
  145. strncpy(n->experience, exp, MAX_EXP - 1); n->experience[MAX_EXP - 1] = '\0';
  146.  
  147. n->next = NULL;
  148. return n;
  149. }
  150.  
  151. /* Insert destination at the end of the linked list */
  152. void addDestination(Destination **head, Destination *node) {
  153. if (node == NULL) return;
  154.  
  155. if (*head == NULL) {
  156. *head = node;
  157. return;
  158. }
  159.  
  160. Destination *t = *head;
  161. while (t->next != NULL) t = t->next;
  162. t->next = node;
  163. }
  164.  
  165. /* Display all destinations in table format */
  166. void displayAll(Destination *head) {
  167. if (head == NULL) {
  168. printf("No destinations available.\n");
  169. return;
  170. }
  171.  
  172. printf("\nID NAME CITY TYPE RATING\n");
  173. printf("------------------------------------------------------\n");
  174. while (head != NULL) {
  175. printf("%-4d %-17s %-14s %-9s %d\n",
  176. head->id, head->name, head->city, head->type, head->rating);
  177. head = head->next;
  178. }
  179. }
  180.  
  181. /* Search destination by ID */
  182. Destination* searchById(Destination *head, int id) {
  183. while (head != NULL) {
  184. if (head->id == id) return head;
  185. head = head->next;
  186. }
  187. return NULL;
  188. }
  189.  
  190. /* Search destinations by City or Type */
  191. void searchDestinations(Destination *head) {
  192. int option;
  193. char key[80];
  194.  
  195. if (head == NULL) {
  196. printf("No destinations to search.\n");
  197. return;
  198. }
  199.  
  200. printf("\nSearch by:\n1) City\n2) Type\nEnter choice: ");
  201. if (scanf("%d", &option) != 1) {
  202. printf("Invalid input.\n");
  203. return;
  204. }
  205.  
  206. printf("Enter keyword: ");
  207. scanf(" %79[^\n]", key);
  208.  
  209. int found = 0;
  210. while (head != NULL) {
  211. if ((option == 1 && containsIgnoreCase(head->city, key)) ||
  212. (option == 2 && containsIgnoreCase(head->type, key))) {
  213. printf("Match: %s (%s) [%s] Rating=%d\n",
  214. head->name, head->city, head->type, head->rating);
  215. found = 1;
  216. }
  217. head = head->next;
  218. }
  219.  
  220. if (!found) printf("No matching destinations found.\n");
  221. }
  222.  
  223. /* Sort destinations by rating in descending order (bubble sort by swapping data) */
  224. void sortByRating(Destination *head) {
  225. if (head == NULL) return;
  226.  
  227. int swapped;
  228. Destination *ptr1;
  229. Destination *lptr = NULL;
  230.  
  231. do {
  232. swapped = 0;
  233. ptr1 = head;
  234.  
  235. while (ptr1->next != lptr) {
  236. if (ptr1->rating < ptr1->next->rating) {
  237. /* Swap contents (data) of the two nodes */
  238. Destination tmp = *ptr1;
  239. *ptr1 = *(ptr1->next);
  240. *(ptr1->next) = tmp;
  241.  
  242. /* Fix next pointers after struct copy swap */
  243. Destination *n1 = ptr1->next;
  244. Destination *n2 = n1->next;
  245. ptr1->next = n1;
  246. n1->next = n2;
  247.  
  248. swapped = 1;
  249. }
  250. ptr1 = ptr1->next;
  251. }
  252. lptr = ptr1;
  253. } while (swapped);
  254.  
  255. printf("Destinations sorted by rating (descending).\n");
  256. }
  257.  
  258. /* =========================================================
  259.   STACK FUNCTIONS (RECENTLY VIEWED)
  260.   ========================================================= */
  261.  
  262. /* Push destination ID to stack (top insert) */
  263. void push(StackNode **top, int id) {
  264. StackNode *n = (StackNode*)malloc(sizeof(StackNode));
  265. if (n == NULL) {
  266. printf("Memory allocation failed while pushing to stack.\n");
  267. return;
  268. }
  269. n->destId = id;
  270. n->next = *top;
  271. *top = n;
  272. }
  273.  
  274. /* Display stack IDs from top to bottom */
  275. void displayStack(StackNode *top) {
  276. if (top == NULL) {
  277. printf("Recently viewed list is empty.\n");
  278. return;
  279. }
  280.  
  281. printf("Recently Viewed (Top -> Bottom): ");
  282. while (top != NULL) {
  283. printf("%d ", top->destId);
  284. top = top->next;
  285. }
  286. printf("\n");
  287. }
  288.  
  289. /* =========================================================
  290.   QUEUE FUNCTIONS (RECOMMENDATION REQUESTS)
  291.   ========================================================= */
  292.  
  293. /* Initialize queue pointers */
  294. void initQueue(Queue *q) {
  295. q->front = NULL;
  296. q->rear = NULL;
  297. }
  298.  
  299. /* Add request at rear (enqueue) */
  300. void enqueue(Queue *q, const char *user, const char *type, int minRating) {
  301. ReqNode *n = (ReqNode*)malloc(sizeof(ReqNode));
  302. if (n == NULL) {
  303. printf("Memory allocation failed while enqueuing.\n");
  304. return;
  305. }
  306.  
  307. strncpy(n->user, user, MAX_NAME - 1); n->user[MAX_NAME - 1] = '\0';
  308. strncpy(n->prefType, type, MAX_TYPE - 1); n->prefType[MAX_TYPE - 1] = '\0';
  309. n->minRating = minRating;
  310. n->next = NULL;
  311.  
  312. if (q->rear == NULL) {
  313. /* Queue is empty */
  314. q->front = q->rear = n;
  315. } else {
  316. q->rear->next = n;
  317. q->rear = n;
  318. }
  319. }
  320.  
  321. /* Remove request from front (dequeue) and return it */
  322. ReqNode* dequeue(Queue *q) {
  323. if (q->front == NULL) return NULL;
  324.  
  325. ReqNode *t = q->front;
  326. q->front = t->next;
  327.  
  328. if (q->front == NULL) {
  329. /* Queue became empty */
  330. q->rear = NULL;
  331. }
  332. return t;
  333. }
  334.  
  335. /* Process one recommendation request and suggest first matching destination */
  336. void processRecommendation(Queue *q, Destination *head) {
  337. ReqNode *req = dequeue(q);
  338. if (req == NULL) {
  339. printf("No recommendation requests available.\n");
  340. return;
  341. }
  342.  
  343. printf("\nProcessing Recommendation for %s\n", req->user);
  344.  
  345. while (head != NULL) {
  346. if (containsIgnoreCase(head->type, req->prefType) &&
  347. head->rating >= req->minRating) {
  348.  
  349. printf("Recommended Destination:\n");
  350. printf("Name: %s\nCity: %s\nType: %s\nRating: %d\n",
  351. head->name, head->city, head->type, head->rating);
  352.  
  353. free(req);
  354. return;
  355. }
  356. head = head->next;
  357. }
  358.  
  359. printf("No suitable destination found.\n");
  360. free(req);
  361. }
  362.  
  363. /* =========================================================
  364.   SAMPLE DATA
  365.   ========================================================= */
  366. void seedData(Destination **head) {
  367. addDestination(head, createDestination(101, "Baga Beach", "Goa", "Beach", 5,
  368. "Beautiful beach and nightlife."));
  369. addDestination(head, createDestination(102, "Ooty", "TamilNadu", "Hill", 4,
  370. "Pleasant hill station and cool climate."));
  371. addDestination(head, createDestination(103, "Munnar", "Kerala", "Hill", 5,
  372. "Tea gardens and scenic views."));
  373. }
  374.  
  375. /* =========================================================
  376.   MAIN FUNCTION (MENU-DRIVEN)
  377.   ========================================================= */
  378. int main() {
  379. Destination *head = NULL; /* Linked list head */
  380. StackNode *top = NULL; /* Stack top */
  381. Queue q; /* Queue object */
  382. initQueue(&q);
  383.  
  384. seedData(&head); /* Insert sample destinations */
  385.  
  386. while (1) {
  387. int choice;
  388.  
  389. printf("\n==== TRAVEL EXPERIENCE BROWSER ====\n");
  390. printf("1. View All Destinations\n");
  391. printf("2. View Destination by ID\n");
  392. printf("3. Search Destination\n");
  393. printf("4. Sort by Rating\n");
  394. printf("5. Recently Viewed\n");
  395. printf("6. Add Recommendation Request\n");
  396. printf("7. Process Recommendation\n");
  397. printf("8. Exit\n");
  398. printf("Enter choice: ");
  399.  
  400. if (scanf("%d", &choice) != 1) {
  401. printf("Invalid input. Exiting.\n");
  402. break;
  403. }
  404.  
  405. if (choice == 1) {
  406. displayAll(head);
  407. }
  408. else if (choice == 2) {
  409. int id;
  410. printf("Enter destination ID: ");
  411. scanf("%d", &id);
  412.  
  413. Destination *d = searchById(head, id);
  414. if (d != NULL) {
  415. printf("\nName: %s\nCity: %s\nType: %s\nRating: %d\nExperience: %s\n",
  416. d->name, d->city, d->type, d->rating, d->experience);
  417.  
  418. /* Push viewed destination ID to stack */
  419. push(&top, id);
  420. } else {
  421. printf("Destination not found.\n");
  422. }
  423. }
  424. else if (choice == 3) {
  425. searchDestinations(head);
  426. }
  427. else if (choice == 4) {
  428. sortByRating(head);
  429. }
  430. else if (choice == 5) {
  431. displayStack(top);
  432. }
  433. else if (choice == 6) {
  434. char user[MAX_NAME];
  435. char type[MAX_TYPE];
  436. int minRating;
  437.  
  438. /* Consume leftover newline from previous scanf */
  439.  
  440. printf("Enter user name: ");
  441. fgets(user, sizeof(user), stdin);
  442. trim_newline(user);
  443.  
  444. printf("Enter preferred type: ");
  445. fgets(type, sizeof(type), stdin);
  446. trim_newline(type);
  447.  
  448. printf("Enter minimum rating (1 to 5): ");
  449. scanf("%d", &minRating);
  450.  
  451. enqueue(&q, user, type, minRating);
  452. printf("Request added.\n");
  453. }
  454. else if (choice == 7) {
  455. processRecommendation(&q, head);
  456. }
  457. else if (choice == 8) {
  458. printf("Exiting program.\n");
  459. break;
  460. }
  461. else {
  462. printf("Invalid choice.\n");
  463. }
  464. }
  465.  
  466. return 0;
  467. }
Success #stdin #stdout 0.01s 5316KB
stdin
Standard input is empty
stdout
==== TRAVEL EXPERIENCE BROWSER ====
1. View All Destinations
2. View Destination by ID
3. Search Destination
4. Sort by Rating
5. Recently Viewed
6. Add Recommendation Request
7. Process Recommendation
8. Exit
Enter choice: Invalid input. Exiting.