ARTS_week4

A

Leetcode算法题(easy)
ARTS_week4_第1张图片
题目及示例

我的代码如下:

class Solution {
 public:
  vector twoSum(vector& nums, int target) {
    vector result;
    for (int i = 0; i < nums.capacity(); i++) {
      for (int j = i + 1; j < nums.capacity(); j++) {
        if (nums[i] + nums[j] == target) {
          result.push_back(i);
          result.push_back(j);
        }
      }
    }
    return result;
  }
};

由于本题使用了vector,于是在网上查询了一些基本的使用方法,除了一些特殊的成员函数之外,与数组的使用大同小异。当然,对于vector一类的迭代器,利用下标访问虽然可行,但是直接使用begin()end()等是更典型的做法。

我的提交结果如下:


ARTS_week4_第2张图片
提交结果

很明显,运行时间的差距十分显著,于是再对比运行时间较短者(代码如下):

class Solution {
public:
    vector twoSum(vector& nums, int target) {
        unordered_map indices;
        for (int i = 0; i < nums.size(); i++) {
            if (indices.find(target - nums[i]) != indices.end()) {
                return {indices[target - nums[i]], i};
            }
            indices[nums[i]] = i;
        }
        return {};
    }
};
  • 可以发现,该作者并不是使用vector进行操作,而是使用了map这一迭代器。搜寻相关资料,发现map这一迭代器最大的特点在于其为一键值对,类似python中的字典。这一迭代器在此题目中的最大优势在于它的查找功能,利用find()可以更快地找到目标元素并操作;参照其他运行时间短的代码,发现这些代码普遍使用了map迭代器。
  • 而在我的代码中,我使用的为vector迭代器,在查找元素时,利用了两层的for循环嵌套,当数据量较大时,显然极为不利。
  • 总结:对于元素的查找,使用map中的find()能具有更高的效率。

R

本周阅读文章:Zero-shot learning:Using text to more accurately identify images
  • 研究内容:本文主要讲述的是零镜头学习,是一种使用文本更准确地识别图像的机器学习。零镜头学习(ZSL)是机器学习认知它从未见过的对象的过程。Facebook的研究者开发了一种新的、更精确的ZSL模型,它使用被称为对抗神经网络(GANS)的神经网络框架来阅读分析文本,然后将文本中所描述的对象可视化识别。与其他模型将每一个对象独立分开地学习不同,这种新颖的ZSL方法使机器得以根据种类将对象进行分类处理,然后再使用这些信息识别其他相似对象
  • 工作方式:研究人员训练了这个模型,称为对抗零镜头模型 (GAZSL),它依据两个包含了60,000多个图象的数据库,识别了超过600多种鸟类。接着,再让它读取网络文章,让它使用文章上的信息识别它从未识别过的鸟类。这个模型从该文本中提取了七个关键的视觉特点,将这些特点合成可视化,并使用这些特征识别正确的鸟类。之后,研究人员将GAZSL模型与其他七个ZSL算法模型测试比较,它再四个不同的基准中始终更为精确。总体上看,GAZSL模型的表现相较其他模型要优于4%~7%,有时甚至要好得更多。
  • 其重要性:为了变得更有效用,计算机的可视化系统需要识别它们从来没有被特殊训练过的对象。例如:据估计,共有10,000种存活的鸟类,但是大多数计算机的视觉数据中只包含了几百种的鸟类。这种新的开源的ZSL模型已被证实可以产生更好的结果,并为未来的机器学习研究提供了一条有希望的道路。许多AI的研究依旧是基础性的,但是如何改进系统理解文本的方式以及正确识别对象的工作,仍然是为更好、更可信的AI系统打基础。
本文主要介绍了Facebook的研究人员开发的一种新的机器学习的方法,它能有效地通过对图像以及文本的学习(尤其是对文本的学习)对机器从未学习过的对象并分类,是一种非常优秀的方法。

T

本周,程序设计课程迎来了上机期中考,发现了一个极易被我忽视的问题。在考题中其中的一题题目为:定义一个类PowerArray,该类是一个强大的数组类,包含一个私有成员int *ptr,指向实际的存储数组元素的地址空间,用户在构造该类对象时需要指定数组的大小作为参数,然后根据大小从堆中分配空间。 该类还需包含一个成员函数countElement(),返回当前实际存储的数组元素的个数。仔细考虑需要定义哪些成员函数,在Main中进行充分测试。
我写了如下代码:

class PowerArray {
 private:
  int len;
  int *ptr;
  int count;

 public:
  PowerArray(int size);
  ~PowerArray();
  int countElement();
  void get_number(int i);
};


PowerArray::PowerArray(int size) {
  len = size;
  ptr = new int[size];
  count = 0;
}

PowerArray::~PowerArray() { delete[] ptr; }

void PowerArray::get_number(int i) {
  if (count <= len) {
    ptr[count] = i;
    count = count + 1;
  } 
  else {
    cout << "OUT OF RANGE!" << endl;
  }
}

int PowerArray::countElement() { return count; }

我使用了get_number()函数获取数值,再利用countElement()记录当前数组内的元素个数,经充分检验运行正常;之后,我打算再为这个类添加一个新的功能:该数组类能获取一个新的数组里的全体元素,并对当前数组内所含元素计数,加入的代码如下:

class PowerArray {
 private:
//---(此处省略)
 public:
//---(此处省略)
 void get_array(int &a); //添加数组功能的函数
};

//---(此处省略)

//添加数组功能的函数
void PowerArray::get_array(int &a) {
  if (count <= len) {
    for (int j = 0; j < sizeof(a); j++) {
      ptr[count] = a[j];
      count++;
      cout << count << endl;
    }
  } else {
    cout << "OUT OF RANGE!" << endl;
  }
}
  • 本以为一切都能够正常运行,但是却出现了严重的问题:经检验,发现sizeof(a)的值并不是想象中的数组长度,实际运行结果为4。
  • 问题在于:当我将数组名作为参数传递时,传递到函数内的参数其实是数组首地址(一个指针变量),而不是想象中的仍然作为一个数组名处理。即:用参数传递数组名时,数组名退化为指针。
  • 换言之,当array只作为数组名处理时,sizeof(array)返回的值是数组元素 * 每个元素数据类型的长度;而在作为参数传至至函数后,sizeof(array)的操作实际等效于sizeof(array[0]),即返回了首元素的地址变量(int类型)的长度,结果为4。

结论:简单地在将数组名用作参数传递的做法显然并不明智,如要使用此方法,应当先知道数组的长度,并在将数组名作为参数传递时使用如下方法:void get_array(int (&a)[N])(其中N为数组长度);另一方法是使用模板操作。


S

  • 由于临近期中考,本周暂未学习新的算法,仅进行了一些简单的复习,敲代码时间严重不足。
    下周目标:
    1. 固定每天的学习时间,目标可根据下周的考试复习任务、每天的作业量更改,但是每天必须有必要的学习和思考;
    2. ARTS的任务最好能在每天有所想法时添加,多次分工,而非一次性写完,如此耗时费力;
    3. 算法仍然需要大量投入时间学习:根据这几次Leetcode的题目提交结果来看,时间普遍过长,如此低效的算法显然是不行的,仍需多加学习和总结。
  • 推荐网页:Facebook AI

你可能感兴趣的:(ARTS_week4)