编程要素:入门

在线环境 |
Python文档

1. 抽象是什么?

抽象就是人对世间万物的一种感受,通过符号表达出来的过程。就像”红色”就是一个抽象的概念,你脑海中不存在”色彩”这种概念的时候,它就是一个很抽象的东西,当我们第一次接触”红色”这个词语时,并不清楚,”红色”是甜的,酸的,软的,硬的?还是说是一种”颜色”,这是通过我们在生活中不断的从周围的环境中慢慢感知出来的。

简单来说,抽象就是将内心的感受使用一种特定的符号表示出来的”过程“。

数学 就是一门抽象的学科, 0,1,2,3,4,+,-,*,=,>,< 这些符号本身是没有意义的,他们是一种抽象的表现,就像我们前面提到的“红色”。 人有2只眼睛,1个嘴巴,这里的“数量” 是人类对生活的观察和感受,“2”,“1”则是人类对“数量”的抽象符号表示。

2. 数学为什么是抽象的?

数学的发展史告诉我们,数学起源于“算”,即起源于物体个数、田亩面积、物体长度等的计算。要计算就要有计算方法,当各种计算方法积累到一定数量的时候,数学家就进行分类,抽象出某类问题的计算公式、法则、原理,统称为算法。所以数学的童年时期叫做算术,它表现为一种经验知识。

3. 计算机和编程与抽象的关系

通过理解了抽象是什么,应该明白:“编程语言”不应该是你要学习的东西,而是用来理解表达你经验知识的工具。
计算机,则是你掌握和控制这些抽象概念的一个机器。
如果做比喻的话:

  • “1,2,3,4” 经过人脑的转换,被理解成人脑海中所理解的“数量”
  • “编程语言” 经过计算机的转换,变成了计算机执行的一系列“操作”

而“编程”就是,人类将自己对于世界的感受,用自己能够理解的方式整理之后(算法+数据结构),然后通过语言符号和基本规则(a,b,c,d,1,2,3,4,+,-,%)抽象成计算机能够理解和执行的程序代码。

4. 编程语言

不同的编程语言,有着自己的规范或是规则。但是它们的本质是一样的,就是对数学计算的抽象。我们采用的编程语言Python,就是一种“简单”的编程语言,为什么说它简单,就是因为Python的抽象更加接近人类理解的语言“英语”。

  • 注意:人类的语言“汉语”,“英语”也是一种抽象的表现。

“红” 和 “red” 只是两个不同的符号,但它们的意义是一样的。
就像Java中的“true” 和 Python中的“True”,代表的意义没什么不同。

5. 实践

from urllib.request import urlopen    # (2)

# 计算机程序只干两件事:
# (1) 计算一些值    
# (2) 执行一些动作

# 后面用符号标记每行代码的功能: (1),(2)

tianqi = urlopen('http://t.weather.sojson.com/api/weather/city/101020100')  # (2)

# 一、 什么是函数(function) ?
# 函数就是将处理数据的过程封装起来,“抽象”成一个符号来代替这些过程。
# urlopen() 就是Python库中的一个函数,url网址是一条数据,返回的结果
# 是另外一条数据,也就获得了内容,简化: B = urlopen(A)  
# 这就用了简单的一句话完成了一些动作,而复杂的过程存在于函数中。
# 这里将这些复杂过程抽象成一个函数名“urlopen”

data = set(tianqi.read().decode().split(',')) # (1)

# 二、 什么是对象(object)?
# set() 函数中经过 read() decode() split() 等一系列函数的复杂计算
# 最终得到data (对象),将“数据”和“处理数据的逻辑”紧密的联系在一起
# 最终简化: C = set(B)    B是开始的数据,C是“抽象”处理后的数据。


result = [w for w in data if len(w) > 0]    # (2)

# 三、 计算机如何理解程序?解释器 (Interpreters)
# 语法中的表达式: result是经过了语言特定的表达式,获得的数据。
# 而在不同的编程语言,可能会有着各自的语法规则(特色)
# 那么计算机是如何理解不同的编程语言的? 解释器/编译器
# Python、Java、Go、C# 每种语言都有自己特定的解释器。


# 最后, 我们将发现所有这些核心概念都是紧密相关的:
# 函数就是对象,对象就是函数,解释器是两者的实现表达的过程。
# 这些概念的清晰理解对于掌握编程技术至关重要。

6. 学习

  • 实例1 双指针法
给定一个排序数组,你需要在原地删除重复出现的元素,使得每个元素只出现一次,返回移除后数组的新长度。
不要使用额外的数组空间,你必须在原地修改输入数组并在使用 O(1) 额外空间的条件下完成。
示例 1:
给定数组 nums = [1,1,2], 
函数应该返回新的长度 2, 并且原数组 nums 的前两个元素被修改为 1, 2。 
你不需要考虑数组中超出新长度后面的元素。
示例 2:
给定 nums = [0,0,1,1,1,2,2,3,3,4],
函数应该返回新的长度 5, 并且原数组 nums 的前五个元素被修改为 0, 1, 2, 3, 4。
你不需要考虑数组中超出新长度后面的元素。
说明:
为什么返回数值是整数,但输出的答案是数组呢?
请注意,输入数组是以“引用”方式传递的,这意味着在函数里修改输入数组对于调用者是可见的。
你可以想象内部操作如下:

// nums 是以“引用”方式传递的。也就是说,不对实参做任何拷贝
int len = removeDuplicates(nums);

// 在函数里修改输入数组对于调用者是可见的。
// 根据你的函数返回的长度, 它会打印出数组中该长度范围内的所有元素。
for (int i = 0; i  int:
        # 先排序
        nums.sort()
        i = 0
        while i < len(nums) - 1:
            if nums[i] == nums[i + 1]:
                nums.remove(nums[i])
            else:
                i = i + 1
        return len(nums)


  • 实例2 哈希表遍历
"""
给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那两个整数,并返回他们的数组下标。
你可以假设每种输入只会对应一个答案。但是,你不能重复利用这个数组中同样的元素。
示例:
给定 nums = [2, 7, 11, 15], target = 9
因为 nums[0] + nums[1] = 2 + 7 = 9
所以返回 [0, 1]
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/two-sum

"""

class Solution:
    def twoSum(self, nums: list, target: int) -> list:
        nl = []
        k = {}
        if len(nums) < 2:
            return []
        elif (len(nums) == 2) and (target == nums[0] + nums[1]):
            return [0, 1]

        for i in range(len(nums)):
            k[nums[i]] = i

        for i in range(len(nums)):
            c = target - nums[i]  # 差值
            if (c in nums) and (k[c] != i):
                # 添加下标
                nl.append(k[c])
                nl.append(i)
        nl = list(set(nl))
        return nl

nums = [3, 2, 3]
target = 6
# [0, 2]
r = Solution().twoSum(nums, target)
print(r)