506 - System Dependencies

来源:互联网 发布:烟台网络党校 编辑:程序博客网 时间:2024/04/29 20:06

Components ofcomputer systems often have dependencies--other components that must beinstalled before they will function properly. These dependencies are frequentlyshared by multiple components. For example, both the TELNET client program andthe FTP client program require that the TCP/IP networking software be installedbefore they can operate. If you install TCP/IP and the TELNET client program,and later decide to add the FTP client program, you do not need to reinstallTCP/IP.


For some components it would not be a problem if the components on which theydepended were reinstalled; it would just waste some resources. But for others,like TCP/IP, some component configuration may be destroyed if the component wasreinstalled.


It is useful to be able to remove components that are no longer needed. Whenthis is done, components that only support the removed component may also beremoved, freeing up disk space, memory, and other resources. But a supportingcomponent, not explicitly installed, may be removed only if all componentswhich depend on it are also removed. For example, removing the FTP clientprogram and TCP/IP would mean the TELNET client program, which was not removed,would no longer operate. Likewise, removing TCP/IP by itself would cause thefailure of both the TELNET and the FTP client programs. Also if we installedTCP/IP to support our own development, then installed the TELNET client (whichdepends on TCP/IP) and then still later removed the TELNET client, we would notwant TCP/IP to be removed.


We want a program to automate the process of adding and removing components. Todo this we will maintain a record of installed components and componentdependencies. A component can be installed explicitly in response to a command(unless it is already installed), or implicitly if it is needed for some othercomponent being installed. Likewise, a component, not explicitly installed, canbe explicitly removed in response to a command (if it is not needed to supportother components) or implicitly removed if it is no longer needed to supportanother component. Installing an already implicitly-installed component won'tmake that component become explicitly installed.

Input 

The input willcontain a sequence of commands (as described below), each on a separate linecontaining no more than eighty characters. Item names are case sensitive, andeach is no longer than ten characters. The command names(DEPEND, INSTALL, REMOVE and LIST) always appear inuppercase starting in column one, and item names are separated from the commandname and each other by one or more spaces. Allappropriate DEPEND commands will appear before the occurrence ofany INSTALL command that uses them. There will be no circulardependencies. The end of the input is marked by a line containing only theword END.

 

Command Syntax

Interpretation/Response

DEPEND item1 item2 [item3 ...]

item1 depends on item2 (and item3 ...)

INSTALL item1

install item1 and those on which it depends

REMOVE item1

remove item1, and those on which it depends, if possible

LIST

list the names of all currently-installed components

Output 

Echo each line ofinput. Follow each echoed INSTALL or REMOVE line with theactions taken in response, making certain that the actions are given in theproper order. Also identify exceptional conditions (see Sample Output, below,for examples of all cases). For the LIST command, display the names of thecurrently installed components in the installation order. No output, except theecho, is produced for a DEPEND command or the linecontaining END. There will be at most one dependency list per item.

Sample Input 1 

DEPEND  TELNET TCPIP NETCARD

DEPEND TCPIP NETCARD

DEPEND DNS TCPIP NETCARD

DEPEND BROWSER   TCPIP  HTML

INSTALL NETCARD

INSTALL TELNET

INSTALL foo

REMOVE NETCARD

INSTALL BROWSER

INSTALL DNS

LIST

REMOVE TELNET

REMOVE NETCARD

REMOVE DNS

REMOVE NETCARD

INSTALL NETCARD

REMOVE TCPIP

REMOVE BROWSER

REMOVE TCPIP

END

SampleOutput 1 

DEPEND   TELNETTCPIP NETCARD

DEPEND TCPIP NETCARD

DEPEND DNS TCPIP NETCARD

DEPEND  BROWSER   TCPIP HTML

INSTALL NETCARD

   InstallingNETCARD

INSTALL TELNET

   InstallingTCPIP

   InstallingTELNET

INSTALL foo

   Installingfoo

REMOVE NETCARD

   NETCARD isstill needed.

INSTALL BROWSER

   InstallingHTML

   InstallingBROWSER

INSTALL DNS

   InstallingDNS

LIST

   NETCARD

   TCPIP

   TELNET

   foo

   HTML

   BROWSER

   DNS

REMOVE TELNET

   RemovingTELNET

REMOVE NETCARD

   NETCARD isstill needed.

REMOVE DNS

   Removing DNS

REMOVE NETCARD

   NETCARD isstill needed.

INSTALL NETCARD

   NETCARD isalready installed.

REMOVE TCPIP

   TCPIP isstill needed.

REMOVE BROWSER

   RemovingBROWSER

   Removing HTML

   RemovingTCPIP

REMOVE TCPIP

   TCPIP is notinstalled.

END

Sample Input 2 

DEPEND A B

INSTALL A

INSTALL B

REMOVE A

END

Sample Output 2 

DEPEND A B

INSTALL A

   Installing B

   Installing A

INSTALL B

   B is already installed.

REMOVE A

   Removing A

   Removing B

END

代码:

// UVa506 System Dependencies

// Rujia Liu

// 注意:显式安装的必须显式删除

#include<iostream>

#include<cstring>

#include<string>

#include<sstream>

#include<vector>

#include<algorithm>

#include<map>

using namespacestd;

 

const int maxn =10000;

 

int cnt = 0;

map<string,int> name2id;

string name[maxn];

 

vector<int>depend[maxn], depend2[maxn];

int status[maxn];// 0-not installed, 1-explicitly installed, 2-implicitly installed

vector<int>installed;

 

int ID(conststring& item) {

  if(!name2id.count(item)) {

    name[++cnt] = item;

    name2id[item] = cnt;

  }

  return name2id[item];

}

 

bool needed(intitem) {

  for(int i = 0; i < depend2[item].size();i++)

    if(status[depend2[item][i]]) return true;

  return false;

}

 

void install(intitem, bool toplevel) {

  if(!status[item]) {

    for(int i = 0; i < depend[item].size();i++)

      install(depend[item][i], false);

    cout << "   Installing " << name[item]<< "\n";

    status[item] = toplevel ? 1 : 2;

    installed.push_back(item);

  }

}

 

void remove(intitem, bool toplevel) {

  if((toplevel || status[item] == 2) &&!needed(item)) {

    status[item] = 0;

    installed.erase(remove(installed.begin(),installed.end(), item), installed.end());

    cout << "   Removing " << name[item] <<"\n";

    for(int i = 0; i < depend[item].size();i++)

      remove(depend[item][i], false);

  }

}

 

// 按照安装顺序输出

void list() {

  for(int i = 0; i < installed.size(); i++)

    cout << "   " << name[installed[i]] <<"\n";

}

 

int main() {

  string line, cmd;

  memset(status, 0, sizeof(status));

  while(getline(cin, line)) {

    cout << line << "\n";

    stringstream ss(line);

    ss >> cmd;

    if(cmd[0] == 'E') break;   

    string item1, item2;

    if(cmd[0] == 'L') list();

    else {

      ss >> item1;

      int i1 = ID(item1);

      if(cmd[0] == 'D') {

        while(ss >> item2) {

          int i2 = ID(item2);

          depend[i1].push_back(i2);

         depend2[i2].push_back(i1);

        }

      }

      else if(cmd[0] == 'I') {

        if(status[i1]) cout <<"   " << item1 <<" is already installed.\n";

        else install(i1, true);

      }

      else {

        if(!status[i1]) cout <<"   " << item1 <<" is not installed.\n";

        else if(needed(i1)) cout <<"   " << item1 <<" is still needed.\n";

        else remove(i1, true);

      }

    }

  }

  return 0;

}

0 0
原创粉丝点击