用数组解决问题
数组基础知识概述:
数组的主要的属性直接来自它的定义,一个数组所储存的每个值具有相同点的类型。
固定数据的数组,一般而言可以作为表查询,代替一系列笨拙的控制语句。
非标量数组,程序员常常需要处理复合数据类型的数组,例如结构和对象。
struct student {
int grade;
int studentid;
string name;
};
const int array_size = 10;
student studentarray[array_size] = {
{87, 1001, "fred"},
{65, 1002, "tom" }
};
通过追踪数组位置允许我们在以后提取学生的任何数据。studentaray[i].name。
多维数组
有时候使用多维数组是合理的,假设我们需要处理3个销售代表的月销售数据,把所有的数据储存在一个3 X 12的数组中意味着我们可以用嵌套循环一次性处理整个数组:
const int num_agent = 3;
const int num_months = 12;
int sale[3][12] = {
{1,2,3,4,5,6,7,8,9,10,11,12},
{1,2,3,4,5,6,7,8,9,10,11,12},
{1,2,3,4,5,6,7,8,9,10,11,12}
};
int maxsale = sale[0][0];
for (int agent = 0; agent < num_agent; agent++)
{
for (int month = 0; month < num_months; month++)
{
if (sale[agent][month] > maxsale)
maxsale = sale[agent][month];
}
}
即使是用了多维数组,有时候最好的办法还是一次只处理一维的数据
把一个层次的数组放在一个结构或一个类中。假设我们创建一个agentstruct结构:
struct agentstruct {
int monthlysales[12];
};
有了这个结构之后,我们就不需要创建一个二维数组sale了,而是创建一个一维数组:
ggentstruct agent[3];
当我们调用求数组平均值的函数时,只要向它传递一个一维数组就可以了:
int average = arrayaverage(agent[1].monthlysales, 12)
数组的基本操作列表:
储存:1.数组是每个变量的集合,我们可以对其中的每个变量进行赋值,2。数组在使用之前应该初始化。初始化为一个相同值。
int array[10];
for (int i = 0; i < 10; i++) array[i] = 0;
复制:1.当我们需要对数组进行大量的操作,但仍然还需要数组的原来得形式供以后处理。2.把数据的一部分元素从一个数组复制到另一个数组,作为一种重新排列元素顺序的方法。
int array[5] = {4,5,6,7,8 };
int copy[5];
for (int i = 0; i < 5; i++) copy[5] = array[i];
提取和搜索:1,提取 int a = array[0];
2,搜索 搜索一个特定的值
const int array_size = 5;
int array[array_size]= {4,5,6,7,8 };
int target = 6;
int targetpos = 0;
while ((array[targetpos] != target) && (targetpos < array_size))
targetpos++;
基于标准的搜索 (最大值)
const int array_size = 5;
int array[array_size]= {4,5,6,7,8 };
int max = array [0];
for (int i = 0; i < array_size; i++)
{
if (array[i] > max) max = array[i];
}
排序:1,用qsort进行快速方便的排序
c/c++标准库所提供的qsort函数,为了使用qsort,必须编写一个比较函数。这个函数被qsort函数调用,用于比较数组中的两个元素。
int compare(const void * voida, const void *voidb)
{
int * inta = (int *)(voida);
int * intb = (int *)(voidb);
return * inta - *intb;
}
有了比较函数之后,下面是qsort的一个示例用法:
const int array_size = 5;
int array[array_size] = {4,5,6,7,8 };
qsort(array, array_size, sizeof(int), compare);
我们所传递的是函数本身,而不是调用这个函数并传递调用的结果
???????????
2,容易修改的插入排序 算法
int start = 0;
int end = array_size - 1;
for (int i = start + 1; i <= end; i++)
{
for (int j = i; j > start && array[j - 1] > array[j]; j--)
{
int temp = array[j - 1] ;
array[j - 1] = array[j];
array[j] = temp;
}
}
它仅仅适用于长度较小或中等的数组,可以将它看成一种定式思维。不管选择的是这种排序还是其他,我们应该有一种体面的或者更好的排序方法,可以让自己在编写代码时充满信心。
计算统计数据:它返回数组中的所有值所进行计算所产生的统计数据。计算平均数,中位数或众数。
数据验证
const int array_size = 5;
int count = 0;
for (int i = 0; i < array_size; i++)
{
if (array[i] < 0) count++;
}
保存柱状图的数组:如果直接从用户处读取数据,而不直接拥有一个包含数据的数组或其他数据结构。只需要一个保存柱状图的数组,在调查数据时,处理它们。
const int max_response = 5;
int histogram [max_response];
for (int i = 0; i < max_response; i++)
{histogram[i] = 0; }
for (int i = 0; i < array_size; i++)
{ histogram[surveydata[i]-1]++; }
决定什么时候使用数组
最为常见的情况是需要处理聚合数据但并没有告诉我们怎么组织处理数据。处理之前需要读取所有的数据或多次处理数据。
如果我们确定需要多次处理数据,并且对数据集的最大长度相当有把握,那么决定是否使用数组的最后一个标准就是随机访问。随机访问意味着可以在任何时间访问数组或vector中的任何元素,链表只能按顺序访问。
在创建数组之后,我们就无法改变它的长度。c++ 允许我们创建在运行时确定长度的数组(只有在预先得知调查答案的数量的前提下才能使用动态数组)。
在不同的情况下,不同的解决方案具有不同的利弊,我们必须在空间效率和时间效率之间做出决定。我们必须关注性能调教,这是对程序的时间和空间效率的系统性的分析和改进。这是一项讲究精确的工作,任何微小的调整都可能产生巨大的影响,需要深入理解幕后的工作机制。但是即使我们没有时间,精力或专业知识对程序的性能进行完美的优化,还是可以避免那些可能降低整体效率的决定。不必要的使用vector类或数组相当于用一辆本田思域就可以装下所有行李的情况下却开一辆大巴士去海滩度假。
注:vector类
c++标准模板库中的vector类可以作为一种能够根据需要增加长度的数组。一旦声明并初始化之后,vector就可以和数组一样使用了。
vector<int> surveydata; 声明
surveydata.reserve(30); 为调查答案保留了30个空间,防止添加元素时频繁改变长度。
调查结果使用push_back方法添加到vector中的。