文件传输

文件传输


一、目的

-掌握函数的自定义
-掌握bool的用法

二、实验内容与设计思想

文件传输

当两台计算机双向连通的时候,文件是可以在两台机器间传输的。给定一套计算机网络,请你判断任意两台指定的计算机之间能否传输文件?

输入格式:
首先在第一行给出网络中计算机的总数 n (2≤n≤10^4 ),于是我们假设这些计算机从 1 到 n 编号。随后每行输入按以下格式给出:

I c1 c2
其中I表示在计算机c1和c2之间加入连线,使它们连通;或者是

C c1 c2
其中C表示查询计算机c1和c2之间能否传输文件;又或者是

S
这里S表示输入终止。

输出格式:
对每个C开头的查询,如果c1和c2之间可以传输文件,就在一行中输出"yes",否则输出"no"。当读到终止符时,在一行中输出"The network is connected."如果网络中所有计算机之间都能传输文件;或者输出"There are k components.",其中k是网络中连通集的个数。

输入样例 1:
5
C 3 2
I 3 2
C 1 5
I 4 5
I 2 4
C 3 5
S
输出样例 1:
no
no
yes
There are 2 components.
输入样例 2:
5
C 3 2
I 3 2
C 1 5
I 4 5
I 2 4
C 3 5
I 1 3
C 1 5
S
输出样例 2:
no
no
yes
yes
The network is connected.


题目分析:

代码重点在于如何计算集合数和哪些可互相联通

函数相关伪代码

1. find函数
if (p[x] != x) 
|p[x] = find(p, p[x]);
|return p[x];
2.unite函数
r = find(p, x);
r1 = find(p, y);
if (r != r1) 
|p[r1] = r;
3.connect函数
if(find(p, x) == find(p, y))
|return true;
 return false;
4.主函数
for (int i = 0; i < n; i++) 
|p[i] = i;
while (cin >> x) 
|if (x == 'S') 
||count = 0;
|for ( i = 0; i < n; i++)
||if (p[i] == i)
|||count++;
||if (count == 1)
|||cout << "The network is connected." << endl;
||else 
|||cout << "There are " << count << " components." << endl;
||break;
|else if (x == 'C') 
||cin >> c1 >> c2;
||if (connect(p, c1 - 1, c2 - 1)) 
|||cout << "yes" << endl;
||else 
|||cout << "no" << endl;
||else if (x == 'I') {
|||cin >> c1 >> c2;
|||unite(p, c1 - 1, c2 - 1);

函数代码

#include <iostream>
#include <vector>
using namespace std;
int find(vector<int>& p, int x) {
    if (p[x] != x) {
        p[x] = find(p, p[x]);
    }
    return p[x];
}
void unite(vector<int>& p, int x, int y) {
    int r = find(p, x);
    int r1 = find(p, y);
    if (r != r1) {
        p[r1] = r;
    }
}
bool connected(vector<int>& p, int x, int y) {
    if (find(p, x) == find(p, y)) {
        return true;
    }
    return false;
}

int main() {
    int n, i, count;
    char x;
    int c1, c2;
    cin >> n;
    vector<int> p(n);
    for (int i = 0; i < n; i++) {
        p[i] = i;
    }
    while (cin >> x) {
        if (x == 'S') {
            count = 0;
            for (i = 0; i < n; i++) {
                if (p[i] == i) {
                    count++;
                }
            }
            if (count == 1) {
                cout << "The network is connected." << endl;
            }
            else {
                cout << "There are " << count << " components." << endl;
            }
            break;
        }
        else if (x == 'C') {
            cin >> c1 >> c2;
            if (connected(p, c1 - 1, c2 - 1)) {
                cout << "yes" << endl;
            }
            else {
                cout << "no" << endl;
            }
        }
        else if (x == 'I') {
            cin >> c1 >> c2;
            unite(p, c1 - 1, c2 - 1);
        }
    }

    return 0;
}

三、实验使用环境

以下请根据实际情况编写

  • 操作系统:Windows 11专业版
  • 编程语言:C++
  • 开发工具:[Visual Stdio 2022]

四、实验步骤和调试过程

文件传输

本机运行截图

运行分析

由于我是一行一行的判断,首先判断是C还是I,如果是C,就判断两个计算机是否联通,所以当询问后结果就会输出,如果是I就只是并入到集合里,不会有输出,直到输入S,判断计算机的连通性,按特定格式输出,结束循环。


五、实验小结

遇到的问题及解决方法:

  1. 问题:代码unite函数逻辑有问题
  • 解决方法:修改代码

实验体会和收获:

该程序实现了一个简单的计算机连接状态检查系统,主要功能包括:检查计算机之间是否连通、判断联通集。
首先,程序定义一个大小为n的数组p,并初始化节点为p[i]=i,表明每个节点最初都是独立的,不互相联通。
然后,程序进入一个循环,处理用户输入的命令(由于不确定输入行数,循环条件直接为1,直到用户输入S时结束循环):
1.'S’命令:用count来统计当前计算机中的连通集合。如果count为1,表示所有计算机都是连通的(因为find函数的构造,一个p[i]=i就表示一个集合,使其最少会有一个p[i]=i,此时就是全联通状态);否则,输出count的值,最后用break结束循环。
2.'C’命令:查询两个指定节点是否连接。用connect函数来判断两个节点的是否联通,由于是判断语句,connect可以用bool来表示返回值。用find函数来判断返回true还是false,如果find(p,x)是否等于find(p,y)来判断,因为如果返回值相同表示之间联通。
3.'I’命令:连接两个指定节点。通过unite函数来合并节点(因为从0开头,所有传入的值要-1才能表示对应的计算机),表示它们之间的连接。由于find函数要找到p[x]=x才结束(表示一个联通集合的结束),如果输入的值之间已经联通,那么最后会等会相同值,不连通(即两个不连通的集合)才会为不相同的值,这时候使其中一个p[r]的值等于r1(或 p[r1] = r)就可使两个集合变为一个集合。


posted @ 2025-05-10 22:23  穗和  阅读(24)  评论(0)    收藏  举报