- 浏览: 49259 次
文章分类
- 全部博客 (25)
- Android (19)
- startActivityForResult() (1)
- Intent (3)
- HTML (1)
- onCreate (1)
- Button (3)
- OnClick (3)
- Activity (2)
- savedInstanceState (1)
- Service (2)
- message (1)
- Notification (1)
- Broadcast (1)
- SQLite (1)
- SharePreferences (1)
- Galaxy 9300 (1)
- 刷机 (1)
- root (1)
- ContentProvider (1)
- 笔记本 (1)
- 散热 (1)
- 算法 (3)
- C (4)
- socket (0)
- java (0)
最新评论
C语言中数组必须在编写程序时定义,在定义一个数组时,还必须定义它的大小。
假如需要编写一个程序,从输入文件中读取城市的名称及气温信息。最后按照温度和城市进行排序,并确定中间气温。
对于这个问题,使用数组并不是一个好的选择。因为你不知道应该创建多大的数组才合适。或许可以声明一个认为足够大的数组,但是这会浪费内存空间,并且还有输入文件超出预期的风险。
一种方案是读两遍输入文件,第一遍确定大小,第二遍再进行数据处理。但是因为磁盘I/O是非常慢的(它几乎是总是程序中最慢的),这样效率非常低,并不可取。
一个好的方法是利用链表,它按接收到的数据来存储它们。
下面是一个利用链表,读入输入文件,并按照气温城市进行排序的算法:
/*--- citytemp.c--------------------------- Listing 2-1 ---------
* Reads a text file of cities and temperatures in the
* following format: TempCity
* where Temp is a number of three digits or
* a sign and two digits; City is a string of length < 124
* Examples: -10Duluth
* 096Phoenix
* The records are read into a singly linked list by order
* of temperature and city; duplicates are discarded. At EOF,
* the whole list is printed with an indication of the median
* temperature. And then, the list is progressively shortened
* and reprinted showing the median.
* Usage: citytemp filename.ext
*-------------------------------------------------------------*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/*--- data definitions ---*/
struct Node { /* a node in our linked list */
char *City;
int Temp;
struct Node *Next;
};
typedef struct Node * Link; /* Links are pointers to nodes */
Link Head; /* head of our linked list */
int NodeCount; /* how many nodes in the list */
/*--- functions declarations for linked lists ---*/
int AddNodeAscend ( Link ); /* add a node */
void CreateList ( void ); /* initialize list */
int DeleteNode ( Link ); /* delete a node */
int DuplicateNode ( Link, Link ); /* handle duplicate inserts */
void FreeNode ( Link ); /* free a node's memory */
void ShowNodes ( void ); /* show list of nodes */
int NodeCmp ( Link, Link ); /* compare two nodes */
/*--- function definitions ---*/
int AddNodeAscend ( Link to_add )
{
Link pn, /* 指向将被插入的节点*/
prev, /* 指向当前被检查节点的前一节点 */
curr; /* 指向当前被检查的节点 */
struct Node dummy;
int i;
/* 拷贝插入节点 */
pn = ( Link ) malloc ( sizeof ( struct Node ));
if ( pn == NULL )
return 0;
memcpy ( pn, to_add, sizeof ( struct Node ));
/* 建立头节点,使逻辑更简单 */
dummy.Next = Head;
prev = &dummy;
curr = Head;
/* 插入pn指向的节点 */
for ( ;; prev = curr, curr = curr->Next )
{
if ( curr == NULL )
break; /* 到达链表尾 */
i = NodeCmp ( pn, curr );//比较pn节点与curr节点
if ( i <= 0 )
break; /* pn节点值小于当前节点curr */
}
if ( curr && i == 0 ) /* 判断是否重复节点 */
if ( DuplicateNode ( curr, pn ) == 0 )
return ( 1 ); /* 释放重复节点的空间 */
//插入
prev->Next = pn;
pn->Next = curr;
Head = dummy.Next;//重新定位head,因为若是插入成第一个节点,
//不重新定位,head就不是指向第一个节点了
NodeCount+=1;//节点数加1
return ( 1 );
}
/*--------------------------------------------------------------
* Handle the duplicate node. In this program,
* we just delete the duplicate.
*-------------------------------------------------------------*/
int DuplicateNode ( Link inlist, Link duplicate )//处理重复节点
{
FreeNode ( duplicate );//调用FreeNode,释放重复节点的空间
return ( 0 );
}
int DeleteNode ( Link to_delete )
{
Link curr, /* 指向当前节点 */
prev; /* 指向当前节点的前一节点 */
int i;
/*---判断是不是空表 ---*/
if ( Head == NULL )
return ( 0 );
/*--- 非空,寻找要删除的节点 ---*/
for ( prev = NULL, curr = Head;
curr != NULL && ( i = NodeCmp ( to_delete, curr )) > 0;
prev = curr, curr = curr->Next )
/* loop around */ ;
/*--- 找到匹配条件的,删除之---*/
if ( curr != NULL && i == 0 )//compare之后,若是相同的节点,返回值是0
{
if ( prev )
prev->Next = curr->Next;
else /* deleting Head */
Head = curr->Next;//第一个节点就是匹配待删除的节点
FreeNode ( curr );//释放内存
NodeCount -= 1;//节点数量减1
return ( 1 );
}
return ( 0 );
}
//按温度、城市的规则比较两个节点
int NodeCmp ( Link a, Link b )
{
/* 如果温度不同,按温度排序 */
if ( a->Temp != b->Temp )
return ( a->Temp - b->Temp );
/*温度相同,按城市排序 */
return strcmp ( a->City, b->City );
}
//创建空链表(并没有头结点)
void CreateList ( void )
{
Head = NULL;
NodeCount = 0;
}
//释放节点内存
void FreeNode ( Link n )
{
free ( n->City );
free ( n );
}
//展示节点群
void ShowNodes( void )
{
Link pn;
int count, median;
median = NodeCount/2+1;
//遍历链表城市与温度,并指出中点
if ( NodeCount ) /* 当且仅当存在节点才展示 */
{
count = 0; /* 计算打印的节点 */
for ( pn = Head; pn; pn = pn->Next )
{
printf ( "%-20s: %3d", pn->City, pn->Temp );
count += 1;
if ( count == median )
printf ( " --Median--" );
printf ( "\n" );
}
}
else
printf ( "Empty list\n" );
}
/*--- main line ---*/
int main ( int argc, char *argv[] )
{
FILE *fin; /* file we'll be reading from */
char buffer[128]; /* where we'll read the file into */
struct Node n; /* the node we add each time */
if ( argc != 2 )
{
fprintf ( stderr, "Usage: citytemp filename.ext\n" );
exit ( EXIT_FAILURE );
}
fin = fopen ( argv[1], "rt" );
if ( fin == NULL )
{
fprintf ( stderr, "Cannot open/find %s\n", argv[2] );
exit ( EXIT_FAILURE );
}
/* 创建并初始化链表 */
CreateList();
/*--- main loop ---*/
while ( ! feof ( fin ))//循环直到文件流末EOF
{
if ( fgets ( buffer, 127, fin ) == NULL )//从文件指针fin中读取127-1个字符,存到以buff为起始地址的空间里,直到读完一行,如果成功则返回s的指针,否则返回NULL。
break;
/* 置行末字符为结束符 */
buffer [ strlen ( buffer ) - 1 ] = '\0';
/* 复制从buff+3开始的字符串 */
n.City = strdup ( buffer + 3 );
/* 置行上第4个字符为结束符 */
buffer[3] = '\0';
n.Temp = atoi ( buffer );//把行上前3个数字字符转换成整型数
/* 设置好n节点后,插入链表 */
if ( AddNodeAscend ( &n ) == 0 )
{
fprintf ( stderr, "Error adding node. Aborting\n" );
exit ( EXIT_FAILURE );
}
}
ShowNodes();
/* Now, delete something */
printf( "\n" );
DeleteNode ( Head );
ShowNodes();
//从第一个节点开始,依次删除一个节点并展示节点群
while (Head && Head->Next)
{
printf ( "\n" );
DeleteNode ( Head->Next );
ShowNodes();
}
printf ( "\n" );
DeleteNode ( Head );
ShowNodes();
fclose ( fin );//关闭流
return ( EXIT_SUCCESS );
}
涉及的一些函数:
void *memcpy(void *dest, const void *src, int n);
从源src所指的内存地址的起始位置开始拷贝n个字节到目标dest所指的内存地址的起始位置中
函数返回一个指向dest的指针。
char *fgets(char *s, int n, FILE *stream);
参数:
*s: 字符型指针,指向将存储到的数据地址。
n: 整型数据,将从流中读取 n - 1 个字符。
*stream: 指针数据,欲读取的流。
功能:
从文件指针stream中读取n-1个字符,存到以s为起始地址的空间里,直到读完一行,如果成功则返回s的指针,否则返回NULL。
int atoi(const char *nptr);
功 能: 把字符串转换成整型数.
名字来源:array to integer 的缩写.
函数说明: 参数nptr字符串,如果第一个非空格字符不存在或者不是数字也不是正负号则返回零,否则开始做类型转换,之后检测到非数字(包括结束符 \0) 字符时停止转换,返回整型数。
extern char *strdup(char *s);
用法:char *strdup(char *s);
功能:复制字符串s
说明:strdup()在内部调用了malloc()为变量分配内存,当程序结束后,必须用free()释放相应的内存空间,否则会造成内存泄漏
extern int strcmp(const char *s1,const char * s2);
用法:#include <string.h>
功能:比较字符串s1和s2。
一般形式:strcmp(字符串1,字符串2)
说明:
当s1<s2时,返回值<0
当s1=s2时,返回值=0
当s1>s2时,返回值>0
即:两个字符串自左向右逐个字符相比(按ASCII值大小相比较),直到出现不同的字符或遇'\0'为止。如:
算法实际运行截图:
相关推荐
书籍的第2章便是一个C语言的入门教程,内容非常易懂,并且十分实用,阅读完这章就可以对本书需要的C语言基础有一个较好的掌握。 本书已经覆盖了大部分基础经典算法,不仅可以作为考研机试和PAT的学习教材,对其他的...
包含了素数筛和线性筛算法的实现和理解,是很实用的一种筛选算法, 筛选算法的本质是一种标记算法
本书还有配套的《算法笔记上机训练实战指南》本书的作者是同样经历过考研机试和各类算法考试的专家型学长,知晓这类考试中的痛点,以及考生在学习算法时容易产生困惑的地方,因此可以把本书看作是学长为你奉献的满满...
书籍的第2章便是一个C语言的入门教程,内容非常易懂,并且十分实用,阅读完这章就可以对本书需要的C语言基础有一个较好的掌握。 本书已经覆盖了大部分基础经典算法,不仅可以作为考研机试和PAT的学习教材,对其他的...
对其他的一些算法考试(例如CCF的CSP考试)或者考研初试的数据结构科目的学习和理解也很有帮助,甚至仅仅想学习经典算法的读者也能从本书中学到许多知识,本书还有配套的《算法笔记上机训练实战指南》 本书的作者是...
4 持续学习进步:算法学习是一条持续的道路,我会不断地更新笔记内容,记录自己的学习进步,与你一起成长。 5 分享交流:如果你对我的笔记有任何疑问或建议,都欢迎在评论区与我交流,让我们一起探讨算法的乐趣! ...
“实用算法(基础算法-递推法)”使你熟练的掌握递推算法
《某国一Python算法做题笔记-算法模板》是一本专为Python编程爱好者与算法学习者精心打造的实用指南。本书通过一系列精心设计的算法模板,帮助读者快速掌握Python算法的核心技巧,提升编程能力。书中详细介绍了各种...
作者: 胡凡 / 曾磊 豆瓣评分9.4,C语言零基础也能看懂。省下纸书钱,下载不后悔。...书籍的第2章便是一个C语言的入门教程,内容非常易懂,并且十分实用,阅读完这章就可以对本书需要的C语言基础有一个较好的掌握。
更重要的是,不仅得到理论基础的学习,而且获得那些需要快速和强大的应用技术解决问题的实用技术。最后,会学到一些硅谷利用机器学习和人工智能的最佳实践创新。本课程提供了一个广泛的介绍机器学习、数据挖掘、统计...
本书内容丰富,对本科生的数据结构课程和研究生的算法课程都是很实用的教材。本书在读者的职业生涯中,也是一本案头的数学参 考书或工程实践手册。 在有关算法的书中,有一些叙述非常严谨,但不够全面,另一些涉及...
DeepLearning.ai学习笔记(二)改善深层神经网络:超参数调试、正则化以及优化--Week2优化算法 DeepLearning.ai学习笔记(二)改善深层神经网络:超参数调试、正则化以及优化--week3 超参数调试、Batch正则化和程序...
更重要的是,你会不仅得到理论基础的学习,而且获得那些需要快速和强大的应用技术解决问题的实用技术。最后,你会学到一些硅谷利用机器学习和人工智能的最佳实践创新。 本课程提供了一个广泛的介绍机器学习、数据...
讲的都是实用算法,没有那些高大上听着名字就让人感到很害怕的东西,个人觉得比CLRS实用性要强,更加适合入门的学习。 大一,推荐这本书入门 【有C语言基础即可,自己去搜索下如何用Java写出Hello World就没有...
实用性强,非理论性的算法: CSDN-算法精华(收集) 麻省理工学院《算法导论》 JAVA上加密算法的实现用例 数据结构与算法分析学习笔记 C语言常用算法源代码 遗传算法从入门到精通 ...
版本控制命令以及更多实用程序 如何使用GoogleCloud以及一些资源 与linux相关的命令和学习资源,例如为实验设置环境等。 数据科学学习资源 使用Python面试问题以及如何准备问题 关于python不同功能的清单。 如何使用...
本书内容丰富,对本科生的数据结构课程和研究生的算法课程都是很实用的教材。本书在读者的职业生涯中,也是一本案头的数学参 考书或工程实践手册。 在有关算法的书中,有一些叙述非常严谨,但不够全面,另一些涉及...
Hybrid A*是首次由斯坦福于2010年提出:一个实用的路径规划算法,该算法可以为在未知环境中运行的自主车辆生成平滑的路径,其中障碍物由机器人的传感器在线检测。 因为不想让这篇交流笔记变为数学课,所以我省略了很...
更重要的是,你会不仅得到理论基础的学习,而且获得那些需要快速和强大的应用技术解决问题的实用技术。最后,你会学到一些硅谷利用机器学习和人工智能的最佳实践创新。 本课程提供了一个广泛的介绍机器学习、数据...
旨在展示ML如何以实用而全面的方式为算法交易策略增加价值。 它涵盖了从线性回归到深度强化学习的广泛的机器学习技术,并演示了如何建立,回测和评估由模型预测驱动的交易策略。 本书分为四个部分,共23章,另加...