选票统计问题与稀疏矩阵压缩存储的转置

(一)选票统计问题

问题:
现有10个候选人,对这10个候选人分别标号为1–10;有两万人对他们进行选举,产生了两万张选票;每张选票上写的分别是1–10中的其中一个数字,以表示支持那一位候选人,先要求对这两万张选票进行统计,得到每个候选人的票数。

怎么实现?

一般思路:

定义一个11个空间大小的数组(a[0]不使用),每个空间代表一个一位候选人的票数计数。然后对两万张选票进行遍历,票上数字是几,对应数组元素就加一。
代码实现如下:

int main()
{
    int num[11];
    int x;
    for (int i; i <= 20000; i++)
    {
        scanf("%d", &x);
        switch (x)
        {
        case 1:
            num[1]++;
            break;
        case 2:
            num[2]++;
            break;
			.
			.
			.
			.
        }
    }
}

其实,在候选人数量仅仅为10这样小的数量,这样方法没问题。
那如果候选人有100人,那是否要写100个case语句呢?

另一种方法:

其实,可以这样实现:
将输入的数字同时作为数组下标,实现对代码简化。实现代码如下:

int main()
{
    int num[11];
    int x;
    for (int i; i <= 20000; i++)
    {
        scanf("%d", &x);
        num[x]++;

    }
}

这样,那怕一万个候选人,也只需要改一下申请数组空间就行了。实现代码简直简单到不行。

(二)稀疏矩阵压缩存储形式的转置

稀疏矩阵的压缩存储

稀疏矩阵是指矩阵中只有较少的部分为非零部分,其他部分均为0的矩阵;因为非零部分较少,若按正常存储时,就需要存储大量的零元素。其实,这样浪费了存储空间。为此,我们仅仅存储矩阵中的非零元素的信息就行。以实现对矩阵的压缩。每一个非零元素的存储包括:行信息、列信息、值信息。故一个稀疏矩阵存储下来就是如下这样的二维数组:
在这里插入图片描述

因为是转置,其实就是行列的互换.
但是,我们希望在存储的稀疏矩阵依旧是按行存储的,也就是所=说,希望转置过后,存储空间里的顺序依然是按照第一行元素、第二行元素、第三行元素、…这个顺序的。
其实,保持这个按行存取的顺序才是我们分出两个实现方法的原因。

转置方法一:

顺序遍历列方法

为了保持向上面所说的,要实现转置后,矩阵依旧按照行顺序存储,所以我们由小到大依次遍历转置前的矩阵,分别扫描,第一遍,按列扫描列为1的元素,找到了就放进去;第二遍,再次按列扫描列为2的元素,找到了放进去;第三遍…

按照这个顺序依次扫描,依次填入,就能够实现对矩阵转置。但是,这样有一个问题,当非零元素有len个,那么就要对相同的数组进行反复的扫描,这样并不好。一、时间复杂度是len*len这么高;二、反复遍历同一个数据,意义不大。

是否能够实现依次扫描就能够完成转置呢?这样就引出了我们的另一个方法。

转置方法二:

按照上面所说,该方法要是实现对数组的依次遍历就可以完成转置。
首先对新数组的每一行(原数组每一列)进行计数,记录第一列、第二列、第三列分别由多少个非零元素。这里计数就用到了前面我们谈到的选票统计问题,使代码简单。
然后由有一个位置信息,他讲新数组的第一行的起始位置定位1,然后其他行,是改行前一行的行元素个数加前一行的起始位置。

如下图所示:
在这里插入图片描述
这两个运算都是对数组进行预处理。为什么这样处理,因为,经过处理后。我们能知道每一行的起始位置在新数组的第几行,所以在遍历旧数组时,见到第n列(新数组的第n行)的元素时,直接将该元素放于新数组的第n列(新数组的第n行)的起始位置,然后当再发现第二个第n列(新数组的第n行)的元素时,就在第n列(新数组的第n行)的起始位置后加一放置。
这样就实现了对原数组的转置。
该算法仅仅只需要对原数组遍历一次,就可以实现对数组的转置。时间复杂度为len。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值