Advertisement
Guest User

Untitled

a guest
Apr 22nd, 2019
90
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 8.59 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <ctype.h>
  5.  
  6. #define maxcities 50  // the maximum number of cities I put it hear so I can change when I need to
  7. #define mincities 5   //the minimum of cities
  8. #define maxdis 20       //the maximum distance
  9. #define impossible 10000 // the * dis value
  10. #define big 100000
  11. //This code by Ahmad Hamdan for the ITP2 Assignment
  12.  
  13. int adj[maxcities][maxcities];      //adjacency matrix
  14. int noc=0, in = 0, d =0; // The Number of cities , initial city , destination city
  15. int dist[maxcities], visited [maxcities], number_of_paths, path[maxcities], cnt; //distance matrix and the matrix of visited nodes and the matrix of all possible paths
  16.  
  17. void cntPaths(int node){        //count the all paths
  18.     visited[node] = 1;          //mark the node a visited
  19.     if(node == d)
  20.         number_of_paths++;
  21.  
  22.     // iterate on the neighbors of node
  23.     for(int i=0;i<noc;i++)
  24.         if(!visited[i] && adj[i][node] != impossible && dist[i] == dist[node] + adj[i][node] && node != d)
  25.             cntPaths(i);
  26.  
  27.     visited[node] = 0; // we are done with node so it is free now
  28. }
  29.  
  30. void printPaths(int node){
  31.     visited[node] = 1;      //mark the node a visited
  32.     path[cnt++] = node;     // add the node to the shortest path
  33.     if(node == d){          // we reached the destination so we print the path
  34.         printf("%d. ", number_of_paths++);
  35.         for(int i=0;i<cnt;i++){
  36.             printf("%d", path[i]);
  37.             if(i != cnt-1)
  38.                 printf(" -> ");
  39.         }
  40.         printf("\n");
  41.     }
  42.  
  43.     // iterate on the neighbors of node
  44.     for(int i=0;i<noc;i++)
  45.         if(!visited[i] && adj[i][node] != impossible && dist[i] == dist[node] + adj[i][node] && node != d)
  46.             printPaths(i);
  47.     visited[node] = 0;
  48.     cnt--;              // delete a node from the current shortest path
  49. }
  50.  
  51. void dijkstra(int adj[maxcities][maxcities],int source,int dest){
  52. int visited [maxcities];
  53. int current,mindis, cnt = noc - 1;
  54.  
  55. // initializing values
  56. for(int i=0;i<noc ;i++)
  57. {
  58.   dist[i]= adj[i][source];
  59.   visited[i]=0;
  60. }
  61. visited[source]=1;
  62. while(cnt){
  63.  
  64.     mindis = impossible;
  65.  
  66.     // selecting the minimum distance for an unvisited node
  67.     for(int i=0;i<noc;i++){
  68.         if(dist[i] < mindis && !visited[i]){
  69.             mindis = dist[i];
  70.             current = i;
  71.         }
  72.     }
  73.  
  74.     // updating distances of node's neighbors
  75.     for(int i=0;i<noc;i++){
  76.         if(!visited[i] && dist[current]+adj[i][current] < dist[i]){
  77.             dist[i] = dist[current]+adj[i][current];
  78.         }
  79.     }
  80.  
  81.     // no path
  82.     if(dist[dest] == impossible){
  83.         printf("Initial and destination cities are not connected\n");
  84.         exit(0);
  85.     }
  86.     cnt--;
  87. }
  88. }
  89. int test(char s[], char e[])    //this function is just to test the number read from the input file as soon as it's read
  90. {
  91.     if (strlen(s)>1) // if it has more than one digit and the first one is zero this zero is insignificant
  92.     {
  93.        if (s[0]=='0')
  94.        {
  95.             printf("Insignificant zero in %s.", e);
  96.             exit(1);
  97.        }
  98.        else for (int j =0; s[j] != '\0' ;j++) //if it has more than one character i should make sure that all of them are digits
  99.        {
  100.            if (!(isdigit(s[j]))) //I am using isdigit function
  101.             {
  102.                printf("Invalid number for %s.", e);
  103.                exit(1);
  104.             }
  105.        }
  106.  
  107.  
  108.     }
  109.  
  110.     if (strlen(s)==1) // if it is one digit only i have to make sure that it is either a digit or a star
  111.     {
  112.         if (!((isdigit(s[0])) || s[0]== '*' ))
  113.         {
  114.             printf("Invalid number for %s." , e);
  115.             exit(1);
  116.         }
  117.  
  118.     }
  119.     if (strlen(s)==0) // if there is no number then it is a problem in the structure
  120.     {
  121.         printf("Invalid structure for %s." ,e);
  122.         exit(1);
  123.     }
  124.  
  125.     return 1;
  126.  
  127. }
  128.  
  129.  
  130. int inrange (int a , int i, int j, char s[]) // this function's mission is just to make that a given value is in a range while given the range and a string defines what I am testing
  131. {
  132.     if (!(a>=i && a<=j))    // testing the range
  133.     {
  134.         printf("%s is out of range", s);
  135.         exit(1);
  136.     }
  137.     return 1;
  138. }
  139.  
  140. int more_than_one_space(char s[])   //testing the number of spaces if there is more than one it is an invalid structure
  141. {
  142.     if (strlen(s)>1)
  143.     {
  144.         printf("invalid structure.");
  145.         exit(1);
  146.     }
  147.     return 1;
  148. }
  149.  
  150.  
  151. int not_star (char s[], char e[])   // testing if it is a star or nor
  152. {
  153.     if (s[0]=='*')
  154.     {
  155.         printf("Invalid value for the %s.", e);
  156.         exit(1);
  157.     }
  158.     return 1;
  159. }
  160.  
  161. int main()
  162. {
  163.  
  164.     char s[1000];
  165.     s[0]= '\0'; //setting the string to empty
  166.  
  167.     freopen("input.txt", "r", stdin); // Redirecting the input to input.txt so I can use manipulate the input as if am dealing with a standard input
  168.     freopen("AhmadHamdanOutput.txt","w",stdout); // Redirecting the output to AhmadHamdan.txt so I can deal with the output easily as if I am dealing with the standard output
  169.     scanf("%[^ ]", s);  //keeps scanning everything until it reaches a space
  170.     test(s, "number of cities");    //testing it number of cities meets the requirements
  171.     not_star(s,"number of cities");     //number of cities can never be a char
  172.     noc =atoi(s);   //converting the number of cities from string to integer
  173.     inrange(noc, 5, 50, "Number of cities" );     //testing if it is in range
  174.     s[0]='\0';  //emptying the string
  175.     scanf("%[ ]",s);    //scans all consecutive spaces
  176.     more_than_one_space(s);     //not allowed to be more than one space
  177.     s[0]='\0';
  178.     scanf("%[^ ]",s);   //keeps scanning everything until it reaches a space
  179.     test(s,"Initial city");
  180.     not_star(s,"initial city");     //initial city can never a char
  181.     in= atoi(s);
  182.     inrange(in,0,noc-1,"initial city");   //initial city should be in range between 0 and number of cities -1
  183.     s[0]='\0';
  184.     scanf("%[ ]",s);
  185.     more_than_one_space(s);
  186.     s[0]='\0';
  187.     scanf("%[^\n]",s);
  188.     test(s,"destination city");
  189.     not_star(s,"destination city");     //destination is never a star
  190.     d=atoi(s);
  191.     inrange(d,0,noc-1,"destination city");      //destination city is between 0 and number of cities -1
  192.     s[0]='\0';
  193.     ////////////////////////////////////////////////////////////////////////////// first line of input finished
  194.     scanf("%[\n]",s);
  195.     if (strlen(s) != 2){        //reading the empty line between the first and the third line
  196.         printf("Invalid structure");
  197.         exit(1);
  198.     }
  199.     s[0]='\0';
  200.  
  201.     int temp;
  202.     for(int i=0;i<noc;i++)      // reading all elements of the adjacency matrix noc * noc
  203.     {
  204.         for(int j=0;j<noc;j++)
  205.         {
  206.             if(j==noc-1){ // after the last element of each row there is a new line thats why i am reading everything until
  207.                 scanf("%[^ \n]",s);
  208.             }
  209.             else
  210.                 scanf("%[^ ]",s); // not the last element so i am expecting a space after the element
  211.             test(s,"distance");     //checking if the the element meets the requirements
  212.             if (s[0]=='*') // it can be a star
  213.                 adj[i][j] = impossible;  //defined number
  214.             else {
  215.                 temp=atoi(s);
  216.                 inrange(temp,0,20,"distance");  //checking if it is in range
  217.                 adj[i][j]=temp;     //saving to the adjacency matrix
  218.             }
  219.             s[0]='\0';
  220.             if(j != noc-1){     // if it is not the last element i am expecting a space after it
  221.                 scanf("%[ ]",s);
  222.                 more_than_one_space(s); // should be only one space no more than that
  223.                 s[0]='\0';
  224.             }
  225.  
  226.         }
  227.         if(i != noc-1){ // if not the last row i am expecting a new line
  228.         scanf("%[\n]",s);
  229.             if (strlen(s)!= 1)  // should be no empty line between them
  230.             {
  231.                 printf("Invalid structure");
  232.                 exit(1);
  233.             }
  234.             s[0]='\0';
  235.         }
  236.     }
  237.     if(!(fgetc(stdin)==EOF)) // there should reach the end of file if not there is a problem in the input file
  238.     {
  239.         printf("Invalid structure");
  240.         exit(1);
  241.     }
  242.  
  243.     /////////////////////////////////////////////
  244.     //the adjacency matrix has been read successfully now we need to do the algorithmic part
  245.     //now printing everything
  246.  
  247.     dijkstra(adj, in, d);
  248.     printf("The shortest path is %d.\n", dist[d]);
  249.     cntPaths(in);
  250.     printf("The number of shortest paths is %d:\n", number_of_paths);
  251.     number_of_paths = 1;
  252.     memset(visited, sizeof(visited), 0);
  253.     printPaths(in);
  254.  
  255.     return 0;
  256. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement