双向链表也叫双链表,是链表的一种,它的每个数据 结点 中都有两个 指针 ,分别指向直接后继和直接前驱。 所以,从双向链表中的任意一个结点开始,都可以很方便地访问它的前驱结点和后继结点。
#include <stdio.h>
#include <malloc.h>
/**
* 定义字符双向链表。
*/
typedef struct DoubleLinkNode{
char data;
struct DoubleLinkNode *previous;
struct DoubleLinkNode *next;
} DLNode, *DLNodePtr;
/**
* 初始化头节点。
* @return 返回头节点的指针。
*/
DLNodePtr initLinkList(){
DLNodePtr tempHeader = (DLNodePtr)malloc(sizeof(struct DoubleLinkNode));
tempHeader->data = '\0';
tempHeader->previous = NULL;
tempHeader->next = NULL;
return tempHeader;
}
/**
* 打印链表。
* @param paraHeader 是链表的头结点。
*/
void printList(DLNodePtr paraHeader){
DLNodePtr p = paraHeader->next;
if(p == NULL){
printf("The list is empty.");
}
while(p != NULL){
printf("%c", p->data);
p = p->next;
}
printf("\r\n");
}
/**
* 在给定的位置加入元素。
* @param paraHeader 是链表的头结点。
* @param paraChar 给定的char元素。
* @param paraPosition 给定的位置。
*/
void insertElement(DLNodePtr paraHeader, char paraChar, int paraPosition){
DLNodePtr p, q, r;
// Step 1. 搜索给定的位置。
p = paraHeader;
for(int i = 0; i < paraPosition; i ++){
p = p->next;
if(p == NULL){
printf("The position %d is beyond the scope of the list.", paraPosition);
return;
}
}
// Step 2. 创建一个新节点
q = (DLNodePtr)malloc(sizeof(struct DoubleLinkNode));
q->data = paraChar;
// Step 3. 链接链表和节点。
printf("linking\r\n");
r = p->next;
q->next = p->next;
q->previous = p;
p->next = q;
if (r != NULL){
r->previous = q;
}
}
/**
* 删除链表中的元素。
* @param paraHeader 是链表的头结点。
* @param paraChar 给定的char元素。
*/
void deleteElement(DLNodePtr paraHeader, char paraChar){
DLNodePtr p, q, r;
p = paraHeader;
// Step 1. 定位
while((p->next != NULL) && (p->next->data != paraChar)){
p = p->next;
}
// Step 2. 检查错误
if(p->next == NULL){
printf("The char %c does not exist.\r\n", paraChar);
return;
}
// Step 3. 改变链接
q = p->next;
r = q->next;
p->next = r;
if(r != NULL){
r->previous = p;
}
// Step 4. 释放内存
free(q);
}
/**
* 找到双向链表中特定的数据的位置
*/
void locateElement(DLNodePtr paraHeader, char paraChar){
DLNodePtr p;
p = paraHeader;
while(p->next != NULL){
p = p->next;
if(p->data == paraChar){
printf("Found the char %c\r\n", paraChar);
return;
}
}
printf("The char %c is not been found.\r\n", paraChar);
return ;
}
void LinkDestory(DLNodePtr paraHeader){
DLNodePtr p;
p = paraHeader;
p->next = NULL;
printf("The list has been destoryed.\r\n");
return;
}
/**
* 功能测试。
*/
void insertDeleteTest(){
// Step 1. 初始化一个空链表。
DLNodePtr tempList = initLinkList();
printList(tempList);
// Step 2. 加入一些字符。
insertElement(tempList, 'H', 0);
printList(tempList);
insertElement(tempList, 'e', 1);
printList(tempList);
insertElement(tempList, 'l', 2);
printList(tempList);
insertElement(tempList, 'l', 3);
printList(tempList);
insertElement(tempList, 'o', 4);
printList(tempList);
insertElement(tempList, '!', 5);
printList(tempList);
// Step 3. 删除一些字符(第一次出现的)。
deleteElement(tempList, 'e');
printList(tempList);
deleteElement(tempList, 'a');
printList(tempList);
deleteElement(tempList, 'o');
printList(tempList);
// Step 4. 在链表给定位置插入特定元素。
insertElement(tempList, 'o', 1);//首位插入
printList(tempList);
insertElement(tempList, 'o', 5);//末位插入
printList(tempList);
insertElement(tempList, 'o', 3);//中间插入
printList(tempList);
// Step 5. 查找指定元素
locateElement(tempList, 'H');
locateElement(tempList, 'l');
locateElement(tempList, 'o');
locateElement(tempList, 'a');
// Step 6. 清空链表
LinkDestory(tempList);
printList(tempList);
}
在老师的基础上,加入了对插入功能的更进一步的测试,同时加入了更多的打印函数来更好地了解函数地运行规律,之后又加入了对locateElement函数地测试。
/**
* 地址测试.
*/
void basicAddressTest(){
DLNode tempNode1, tempNode2;
tempNode1.data = 4;
tempNode1.next = NULL;
tempNode2.data = 6;
tempNode2.next = NULL;
printf("The first node: %d, %d, %d\r\n",
&tempNode1, &tempNode1.data, &tempNode1.next);
printf("The second node: %d, %d, %d\r\n",
&tempNode2, &tempNode2.data, &tempNode2.next);
tempNode1.next = &tempNode2;
}
/**
* 程序入口。
*/
int main(){
insertDeleteTest();
basicAddressTest();
}
The list is empty.
linking
H
linking
He
linking
Hel
linking
Hell
linking
Hello
linking
Hello!
Hllo!
The char a does not exist.
Hllo!
Hll!
linking
Holl!
linking
Holl!o
linking
Holol!o
Found the char H
Found the char l
Found the char o
The char a is not been found.
The list has been destoryed.
The list is empty.
The first node: 6421968, 6421968, 6421984
The second node: 6421936, 6421936, 6421952
静态链表,也是线性存储结构的一种,它兼顾了顺序表和链表的优点于一身,可以看做是顺序表和链表的升级版。
使用静态链表存储数据,数据全部存储在数组中(和顺序表一样),但存储位置是随机的,数据之间"一对一"的逻辑关系通过一个整形变量(称为"游标",和指针功能类似)维持(和链表类似)。
例如,使用静态链表存储 {1,2,3}
的过程如下:
创建一个足够大的数组,假设大小为 6,如图一所示:
图 一 空数组
接着,在将数据存放到数组中时,给各个数据元素配备一个整形变量,此变量用于指明各个元素的直接后继元素所在数组中的位置下标,如图 2 所示:
图 二 静态链表存储数据
通常,静态链表会将第一个数据元素放到数组下标为 1 的位置(a[1])中。
图 2 中,从 a[1] 存储的数据元素 1 开始,通过存储的游标变量 3,就可以在 a[3] 中找到元素 1 的直接后继元素 2;同样,通过元素 a[3] 存储的游标变量 5,可以在 a[5] 中找到元素 2 的直接后继元素 3,这样的循环过程直到某元素的游标变量为 0 截止(因为 a[0] 默认不存储数据元素)。
类似图 2 这样,通过 "数组+游标" 的方式存储具有线性关系数据的存储结构就是静态链表。
#include <stdio.h>
#include <malloc.h>
#define DEFAULT_SIZE 5
typedef struct StaticLinkedNode{
char data;
int next;
} *NodePtr;
typedef struct StaticLinkedList{
NodePtr nodes;
int* used;
} *ListPtr;
/**
* 初始化头节点。
* @return 返回头节点的指针。
*/
ListPtr initLinkedList(){
// 指向整个链表空间的指针
ListPtr tempPtr = (ListPtr)malloc(sizeof(struct StaticLinkedList));
// 分配总空间
tempPtr->nodes = (NodePtr)malloc(sizeof(struct StaticLinkedNode) * DEFAULT_SIZE);
tempPtr->used = (int*)malloc(sizeof(int) * DEFAULT_SIZE);
// 第一个节点是头结点
tempPtr->nodes[0].data = '\0';
tempPtr->nodes[0].next = -1;
// 初始化时只有头结点使用
tempPtr->used[0] = 1;
for (int i = 1; i < DEFAULT_SIZE; i ++){
tempPtr->used[i] = 0;
}
return tempPtr;
}
/**
* 打印链表。
* @param paraHeader 是链表的头结点。
*/
void printList(ListPtr paraListPtr){
int p = 0;
while (p != -1) {
printf("%c", paraListPtr->nodes[p].data);
p = paraListPtr->nodes[p].next;
}
printf("\r\n");
}
/**
* 在给定的位置加入元素。
* @param paraHeader 是链表的头结点。
* @param paraChar 给定的char元素。
* @param paraPosition 给定的位置。
*/
void insertElement(ListPtr paraListPtr, char paraChar, int paraPosition){
int p, q, i;
// Step 1. 搜索位置
p = 0;
for (i = 0; i < paraPosition; i ++) {
p = paraListPtr->nodes[p].next;
if (p == -1) {
printf("The position %d is beyond the scope of the list.\r\n", paraPosition);
return;
}
}
// Step 2. 创建一个新的节点
for ( i; i < DEFAULT_SIZE; i ++){
if (paraListPtr->used[i] == 0){
printf("Space at %d allocated.\r\n", i);
paraListPtr->used[i] = 1;
q = i;
break;
}
}
if (i >= DEFAULT_SIZE){
printf("No space.\r\n");
return;
}
paraListPtr->nodes[q].data = paraChar;
// Step 3. 链接节点
printf("linking\r\n");
paraListPtr->nodes[q].next = paraListPtr->nodes[p].next;
paraListPtr->nodes[p].next = q;
}
/**
* 删除链表中的元素。
* @param paraHeader 是链表的头结点。
* @param paraChar 给定的char元素。
*/
void deleteElement(ListPtr paraListPtr, char paraChar){
int p, q;
p = 0;
while ((paraListPtr->nodes[p].next != -1) && (paraListPtr->nodes[paraListPtr->nodes[p].next].data != paraChar)){
p = paraListPtr->nodes[p].next;
}
if (paraListPtr->nodes[p].next == -1) {
printf("Cannot delete %c\r\n", paraChar);
return;
}
q = paraListPtr->nodes[p].next;
paraListPtr->nodes[p].next = paraListPtr->nodes[paraListPtr->nodes[p].next].next;
// 此语句和free(q)功能相同
paraListPtr->used[q] = 0;
}
/**
* 功能测试。
*/
void appendInsertDeleteTest(){
// Step 1. 初始化一个空链表
ListPtr tempList = initLinkedList();
printList(tempList);
// Step 2. 加入一些元素
insertElement(tempList, 'H', 0);
insertElement(tempList, 'e', 1);
insertElement(tempList, 'l', 2);
insertElement(tempList, 'l', 1);
insertElement(tempList, 'l', 3);
insertElement(tempList, 'o', 4);
printList(tempList);
// Step 3. 删除一些元素(首次出现的该元素)
printf("Deleting 'e'.\r\n");
deleteElement(tempList, 'e');
printf("Deleting 'a'.\r\n");
deleteElement(tempList, 'a');
printf("Deleting 'o'.\r\n");
deleteElement(tempList, 'o');
printList(tempList);
insertElement(tempList, 'x', 1);
printList(tempList);
}
增加了部分的打印函数以更好地理解函数功能。
/**
* 程序入口
*/
void main(){
appendInsertDeleteTest();
}
Space at 1 allocated.
linking
Space at 2 allocated.
linking
Space at 3 allocated.
linking
Space at 4 allocated.
linking
No space.
No space.
Hlel
Deleting 'e'.
Deleting 'a'.
Cannot delete a
Deleting 'o'.
Cannot delete o
Hll
Space at 2 allocated.
linking
Hxll
#include <stdio.h>
#include <malloc.h>
/**
* 定义字符双向链表。
*/
typedef struct DoubleLinkNode{
char data;
struct DoubleLinkNode *previous;
struct DoubleLinkNode *next;
} DLNode, *DLNodePtr;
/**
* 初始化头节点。
* @return 返回头节点的指针。
*/
DLNodePtr initLinkList(){
DLNodePtr tempHeader = (DLNodePtr)malloc(sizeof(struct DoubleLinkNode));
tempHeader->data = '\0';
tempHeader->previous = NULL;
tempHeader->next = NULL;
return tempHeader;
}
/**
* 打印链表。
* @param paraHeader 是链表的头结点。
*/
void printList(DLNodePtr paraHeader){
DLNodePtr p = paraHeader->next;
if(p == NULL){
printf("The list is empty.");
}
while(p != NULL){
printf("%c", p->data);
p = p->next;
}
printf("\r\n");
}
/**
* 在给定的位置加入元素。
* @param paraHeader 是链表的头结点。
* @param paraChar 给定的char元素。
* @param paraPosition 给定的位置。
*/
void insertElement(DLNodePtr paraHeader, char paraChar, int paraPosition){
DLNodePtr p, q, r;
// Step 1. 搜索给定的位置。
p = paraHeader;
for(int i = 0; i < paraPosition; i ++){
p = p->next;
if(p == NULL){
printf("The position %d is beyond the scope of the list.", paraPosition);
return;
}
}
// Step 2. 创建一个新节点
q = (DLNodePtr)malloc(sizeof(struct DoubleLinkNode));
q->data = paraChar;
// Step 3. 链接链表和节点。
printf("linking\r\n");
r = p->next;
q->next = p->next;
q->previous = p;
p->next = q;
if (r != NULL){
r->previous = q;
}
}
/**
* 删除链表中的元素。
* @param paraHeader 是链表的头结点。
* @param paraChar 给定的char元素。
*/
void deleteElement(DLNodePtr paraHeader, char paraChar){
DLNodePtr p, q, r;
p = paraHeader;
// Step 1. 定位
while((p->next != NULL) && (p->next->data != paraChar)){
p = p->next;
}
// Step 2. 检查错误
if(p->next == NULL){
printf("The char %c does not exist.\r\n", paraChar);
return;
}
// Step 3. 改变链接
q = p->next;
r = q->next;
p->next = r;
if(r != NULL){
r->previous = p;
}
// Step 4. 释放内存
free(q);
}
/**
* 找到双向链表中特定的数据的位置
*/
void locateElement(DLNodePtr paraHeader, char paraChar){
DLNodePtr p;
p = paraHeader;
while(p->next != NULL){
p = p->next;
if(p->data == paraChar){
printf("Found the char %c\r\n", paraChar);
return;
}
}
printf("The char %c is not been found.\r\n", paraChar);
return ;
}
void LinkDestory(DLNodePtr paraHeader){
DLNodePtr p;
p = paraHeader;
p->next = NULL;
printf("The list has been destoryed.\r\n");
return;
}
/**
* 功能测试。
*/
void insertDeleteTest(){
// Step 1. 初始化一个空链表。
DLNodePtr tempList = initLinkList();
printList(tempList);
// Step 2. 加入一些字符。
insertElement(tempList, 'H', 0);
printList(tempList);
insertElement(tempList, 'e', 1);
printList(tempList);
insertElement(tempList, 'l', 2);
printList(tempList);
insertElement(tempList, 'l', 3);
printList(tempList);
insertElement(tempList, 'o', 4);
printList(tempList);
insertElement(tempList, '!', 5);
printList(tempList);
// Step 3. 删除一些字符(第一次出现的)。
deleteElement(tempList, 'e');
printList(tempList);
deleteElement(tempList, 'a');
printList(tempList);
deleteElement(tempList, 'o');
printList(tempList);
// Step 4. 在链表给定位置插入特定元素。
insertElement(tempList, 'o', 1);//首位插入
printList(tempList);
insertElement(tempList, 'o', 5);//末位插入
printList(tempList);
insertElement(tempList, 'o', 3);//中间插入
printList(tempList);
// Step 5. 查找指定元素
locateElement(tempList, 'H');
locateElement(tempList, 'l');
locateElement(tempList, 'o');
locateElement(tempList, 'a');
// Step 6. 清空链表
LinkDestory(tempList);
printList(tempList);
}
/**
* 地址测试.
*/
void basicAddressTest(){
DLNode tempNode1, tempNode2;
tempNode1.data = 4;
tempNode1.next = NULL;
tempNode2.data = 6;
tempNode2.next = NULL;
printf("The first node: %d, %d, %d\r\n",
&tempNode1, &tempNode1.data, &tempNode1.next);
printf("The second node: %d, %d, %d\r\n",
&tempNode2, &tempNode2.data, &tempNode2.next);
tempNode1.next = &tempNode2;
}
/**
* 程序入口。
*/
int main(){
insertDeleteTest();
basicAddressTest();
}
#include <stdio.h>
#include <malloc.h>
#define DEFAULT_SIZE 5
typedef struct StaticLinkedNode{
char data;
int next;
} *NodePtr;
typedef struct StaticLinkedList{
NodePtr nodes;
int* used;
} *ListPtr;
/**
* 初始化头节点。
* @return 返回头节点的指针。
*/
ListPtr initLinkedList(){
// 指向整个链表空间的指针
ListPtr tempPtr = (ListPtr)malloc(sizeof(struct StaticLinkedList));
// 分配总空间
tempPtr->nodes = (NodePtr)malloc(sizeof(struct StaticLinkedNode) * DEFAULT_SIZE);
tempPtr->used = (int*)malloc(sizeof(int) * DEFAULT_SIZE);
// 第一个节点是头结点
tempPtr->nodes[0].data = '\0';
tempPtr->nodes[0].next = -1;
// 初始化时只有头结点使用
tempPtr->used[0] = 1;
for (int i = 1; i < DEFAULT_SIZE; i ++){
tempPtr->used[i] = 0;
}
return tempPtr;
}
/**
* 打印链表。
* @param paraHeader 是链表的头结点。
*/
void printList(ListPtr paraListPtr){
int p = 0;
while (p != -1) {
printf("%c", paraListPtr->nodes[p].data);
p = paraListPtr->nodes[p].next;
}
printf("\r\n");
}
/**
* 在给定的位置加入元素。
* @param paraHeader 是链表的头结点。
* @param paraChar 给定的char元素。
* @param paraPosition 给定的位置。
*/
void insertElement(ListPtr paraListPtr, char paraChar, int paraPosition){
int p, q, i;
// Step 1. 搜索位置
p = 0;
for (i = 0; i < paraPosition; i ++) {
p = paraListPtr->nodes[p].next;
if (p == -1) {
printf("The position %d is beyond the scope of the list.\r\n", paraPosition);
return;
}
}
// Step 2. 创建一个新的节点
for ( i; i < DEFAULT_SIZE; i ++){
if (paraListPtr->used[i] == 0){
printf("Space at %d allocated.\r\n", i);
paraListPtr->used[i] = 1;
q = i;
break;
}
}
if (i >= DEFAULT_SIZE){
printf("No space.\r\n");
return;
}
paraListPtr->nodes[q].data = paraChar;
// Step 3. 链接节点
printf("linking\r\n");
paraListPtr->nodes[q].next = paraListPtr->nodes[p].next;
paraListPtr->nodes[p].next = q;
}
/**
* 删除链表中的元素。
* @param paraHeader 是链表的头结点。
* @param paraChar 给定的char元素。
*/
void deleteElement(ListPtr paraListPtr, char paraChar){
int p, q;
p = 0;
while ((paraListPtr->nodes[p].next != -1) && (paraListPtr->nodes[paraListPtr->nodes[p].next].data != paraChar)){
p = paraListPtr->nodes[p].next;
}
if (paraListPtr->nodes[p].next == -1) {
printf("Cannot delete %c\r\n", paraChar);
return;
}
q = paraListPtr->nodes[p].next;
paraListPtr->nodes[p].next = paraListPtr->nodes[paraListPtr->nodes[p].next].next;
// 此语句和free(q)功能相同
paraListPtr->used[q] = 0;
}
/**
* 功能测试。
*/
void appendInsertDeleteTest(){
// Step 1. 初始化一个空链表
ListPtr tempList = initLinkedList();
printList(tempList);
// Step 2. 加入一些元素
insertElement(tempList, 'H', 0);
insertElement(tempList, 'e', 1);
insertElement(tempList, 'l', 2);
insertElement(tempList, 'l', 1);
insertElement(tempList, 'l', 3);
insertElement(tempList, 'o', 4);
printList(tempList);
// Step 3. 删除一些元素(首次出现的该元素)
printf("Deleting 'e'.\r\n");
deleteElement(tempList, 'e');
printf("Deleting 'a'.\r\n");
deleteElement(tempList, 'a');
printf("Deleting 'o'.\r\n");
deleteElement(tempList, 'o');
printList(tempList);
insertElement(tempList, 'x', 1);
printList(tempList);
}
/**
* 程序入口
*/
void main(){
appendInsertDeleteTest();
}
文章浏览阅读932次。一、案例背景许多朋友在首次购车时,一般会比较纠结自己该如何选车,用什么标准选车。因此从购车人角度制作了一个仪表板,来辅助购车人高效做出决策。二、仪表板1、每个人购买倾向不同,所以应该提供给他们更多选择自由度。因此在仪表板上方设置了多个卡片图切片器,包括价格档、车系、车类、品牌、级别、车型等2、柱形图和切片器配合,展示了规模和销量各自的信息。规模:每个车型规模和总车型平均规模之间的对..._商业分析案例 汽车行业
文章浏览阅读6.9k次,点赞2次,收藏12次。W801上跑LuaOS, 两个点灯程序的比较_海凌科w801开发板 luatos
文章浏览阅读1.1k次。挂载NFS文件系统到云服务器(Linux)参考链接:https://support.huaweicloud.com/qs-sfs/zh-cn_topic_0034428728.html弹性文件服务简介弹性文件服务(Scalable File Service,SFS)提供按需扩展的高性能文件存储(NAS),可为云上多个弹性云服务器(Elastic Cloud Server,ECS),容器(CCE&CCI)、裸金属服务器(BMS)提供共享访问。如图1所示。图1 访问弹性文件服务与传统的文件共_在华为云中同一个弹性文件服务sfs的文件系统能给不同region挂载吗
文章浏览阅读509次,点赞2次,收藏6次。目录第 1 章 引论第 2 章 文法和语言2.1 句型分析和语法树2.2 文法设计第 3 章 词法分析第 4 章 自顶向下语法分析方法第 6 章 LR分析第 7 章 语法制导的语义计算第 8 章 静态语义分析和中间代码生成第 9 章 运行时存储组织第 10 章 代码优化和目标代码生成第 1 章 引论第 2 章 文法和语言2.1 句型分析和语法树令文法G[E]为:E->T | E+T | E-T T->F | T*F F->(E)|i证明 E+T*F 是它的一个句型,给出该句型的所_请构造一文法,使文法产生的语言是十进制正偶数集合,并规定偶数非0开头
文章浏览阅读747次。return "redirect:/index": 不管前面的路径是什么,满足条件后会跳转到index比如8080/a/b/c/跳转后变成8080/index_redirect:/index
文章浏览阅读971次。相较于值的比较,Python也支持身份的比较。身份比较运算符:运算符 说明 is 结果为True,运算符两端是同一个对象,如果是False,则为不同对象。 is not 结果为True,运算符两端不是同一个对象,结果为False,则为同一个对象。 什么是身份比较所谓身份比较,即判断两个或更多的不同名称的对象是否为同一个对象。>>> ..._python 身份
文章浏览阅读286次。一、JSON 格式简析。{"person_num": 1,"person_info": [{"body_parts": {"nose": {"x": 96.34375,"y": 101.53125},"right_knee": {"x": 89.6875,"y": 314.53125},"location": {"width": 91.40377044677734,"height": 354.71..._java string json 解析
文章浏览阅读7.2w次,点赞246次,收藏923次。1. 写在前面的话 天天都在PC端运行Python代码的我,今天突然灵光一现,想着是不是能够在移动端运行Python代码呢?如果能够实现的话,家里的废旧手机就有用武之地了。2. 安装环境2.1 安装APK 根据搜索和调研,需要安装以下三个APK,即QPython3、QPython、QPy3.6。打包下载链接为https://download.csdn.net/download/herosunly/16683910 安装后依次为下列三个APP(QPython 3S、QPython OS、QP_安卓 python
文章浏览阅读580次。学习资源B站优质视频教程—TheCWVim教程网—北航小姐姐玩转Vim 从放弃到爱不释手—PegasusWangVim Tutorial—Youtube视频Vim中文手册基本操作思维导图概述学了vim几个月,也看了网上很多教程后,我有时会觉得我们总是喜欢处于舒适区,而对接触让我们一开始感觉别扭的新内容和新工具总是有所抗拒。我希望自己能够多去尝试新内容和新工具,因为我们技能的提升就..._简述vim概念及目标
文章浏览阅读1k次,点赞2次,收藏2次。入选ICCV2021,官方page website,暂未开源paper还是很有创意的,只是pipeline搭建起来很繁琐,还有很大的改进空间。背景styleGAN等生成对抗网络可以生成逼真的图像,生成器的中间特征已经有了前景和背景的特征学习能力,但目前没有方法研究让GAN生成图像的同时,还生成前景目标的mask。本篇paper正是为了解决该问题。作者基于两种假设前景和背景是独立的,因此独立生成然后组合,也能生成逼真的图像。生成器的中间特征学习到了前背景特征分布,是可以利用起来,用于生成前景目标_label4free github
文章浏览阅读1.6w次,点赞10次,收藏134次。无_linux c++ 串口收发
文章浏览阅读3.5k次。https://www.2cto.com/kf/201203/124608.html function validateXML(xmlContent) { //errorCode 0是xml正确,1是xml错误,2是无法验证 var xmlDoc,errorMessage,errorCode = 0; ..._js判断xml