15.9 一个更合理的距离矩阵

最后更新于:2022-04-01 06:25:14

虽然这段代码可以工作,但它本可以组织的更好。既然我们已经写了一个原型,那么我们就处于评价其设计并改进之的有利位置了。 那现在的代码有些什么问题呢? 1. 我们提前不知道要创建多大的距离矩阵,所以我们选择了一个任意大的数字(50),然后创建了一个固定大小的矩阵。更好的方式是允许距离矩阵以类似Set的方式扩充,而apmatrix类的resize函数使之成为可能。 2. 矩阵中的数据没有很好的封装。我们不得不以城市名的集合与矩阵本身作为参数传给processLine,这样很不合适。再就是,因为我们没提供执行错误检查的访问函数,所以使用距离矩阵容易出错。有个好的想法是,将表示城市名的Set对象和表示距离的apmatrix对象组合到DistMatrix类中。 下面是DistMatrix类头文件大概形式的一个草稿: ~~~ class DistMatrix { private: Set cities; apmatrix<int> distances; public: DistMatrix (int rows); void add (const apstring& city1, const apstring& city2, int dist); int distance (int i, int j) const; int distance (const apstring& city1, const apstring& city2) const; apstring cityName (int i) const; int numCities () const; void print (); }; ~~~ 我们可以使用这个接口来简化main函数: ~~~ void main () { apstring line; ifstream infile ("distances"); DistMatrix distances (2); while (true) { getline (infile, line); if (infile.eof()) break; processLine (line, distances); } distances.print (); } ~~~ 也可以简化 processLine函数: ~~~ void processLine (const apstring& line, DistMatrix& distances) { char quote = ’\"’; apvector<int> quoteIndex (4); quoteIndex[0] = line.find (quote); for (int i=1; i<4; i++) { quoteIndex[i] = find (line, quote, quoteIndex[i-1]+1); } // 将行分割为子串 int len1 = quoteIndex[1] - quoteIndex[0] - 1; apstring city1 = line.substr (quoteIndex[0]+1, len1); int len2 = quoteIndex[3] - quoteIndex[2] - 1; apstring city2 = line.substr (quoteIndex[2]+1, len2); int len3 = line.length() - quoteIndex[2] - 1; apstring distString = line.substr (quoteIndex[3]+1, len3); int distance = convertToInt (distString); // 将新数据添加到距离矩阵中 distances.add (city1, city2, distance); } ~~~ 我把实现DistMatrix类的成员函数留作练习请读者完成。
';