ARTS

每周完成一个 ARTS:

Algorithm 来源 LeetCode 11. Container With Most Water

Review 阅读了关于 Go 语言的一篇文章

Tip 总结 Unix 套接字编程的知识

Share 分享 一个分类详细的 Unix / Linux 命令网站

一 Algorithm

LeetCode 11. Container With Most Water 链接 难度:[Medium]

【题意】

Given n non-negative integers a1, a2, …, an , where each represents a point at coordinate (i, ai). n vertical lines are drawn such that the two endpoints of line i is at (i, ai) and (i, 0). Find two lines, which together with x-axis forms a container, such that the container contains the most water.

给定 n 个非负整数 a1,a2,…,an,其中每个代表一个点坐标(i,ai)。 n 个垂直线段例如线段的两个端点在(i,ai)和(i,0)。 找到两个线段,与 x 轴形成一个容器,使其包含最多的水。

Note: You may not slant the container and n is at least 2.

Example:

12
Input: [1,8,6,2,5,4,8,3,7]Output: 49

【思路】

双指针法

  • 分别定义两个指针,或者变量从两边往中间扫描,然后这里需要注意的是,对于两条直立竖起的线段,中间能够储存的水量的多少一定取决于最短的那块线段,因为一旦超过了最短的那块线段,水就溢出来了。理解了这点,此题也就会做了。
  • 将每次扫描的两个指针指向的线段的高度和水平距离之间的差值的乘积就是计算的到的临时最大水量,也就是(min(height[i],height[j])*(j-i))。
  • 最后一边计算得到临时最大水量一边更新最大值便是答案

时间复杂度 O(n),空间复杂度 O(1)。

【参考代码】

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758
Author: rongweiheTime:  2018-12-29*/

using namespace  std;class  {public:    int maxArea(vector<int>& height) {        int size = height.size();        int ret = 0;        int i = 0;        int j = size - 1;        while( i<j ){            ret = max(ret,min(height[i],height[j])*(j-i));            height[i]<height[j]?++i:--j;        }        return ret;    } };

void trimLeftTrailingSpaces(string &input) {    input.erase(input.begin(), find_if(input.begin(), input.end(), [](int ch) {        return !isspace(ch);    }));}

void trimRightTrailingSpaces(string &input) {    input.erase(find_if(input.rbegin(), input.rend(), [](int ch) {        return !isspace(ch);    }).base(), input.end());}

vector<int> stringToIntegerVector(string input) {    vector<int> output;    trimLeftTrailingSpaces(input);    trimRightTrailingSpaces(input);    input = input.substr(1, input.length() - 2);    stringstream ss;    ss.str(input);    string item;    char delim = ',';    while (getline(ss, item, delim)) {        output.push_back(stoi(item));    }    return output;}

int main() {    string line;    while (getline(cin, line)) {        vector<int> height = stringToIntegerVector(line);        int ret = Solution().maxArea(height);        string out = to_string(ret);        cout << out << endl;    }    return 0;}

二 Review

本次 Review 阅读了关于 Go 语言的一篇文章: Concurrency in Golang(英文)。

(PS:参考引用自 https://github.com/zouyingjie/arts/blob/master/2018-12-11.md 的 Review 部分)。

觉得写得很不错,分享给大家。

作者大致讲述了自己对 Go 语言中并发模型的理解。Go 语言的并发模型是基于 CSP(Communicating Sequential Processes),在 Go 语言的世界里,流传着这样一句名言:

Do not communicate by sharing memory; instead, share memory by communicating. 不要通过共享内存来通信,而应该通过通信来共享内存

这两句话到底意味着什么呢?下面是作者对此的理解:

1. Do not communicate by sharing memory

熟悉 C++/Java 等面向对象的语言的同学都知道,在多数情况下,我们需要通过多线程来实现并发。对于某些多个线程都要用到的数据,我们需要使用锁来避免同一时间多个线程访问同一个数据。

为什么要加锁?很简单,是为了共享数据段操作的互斥。

何时需要加锁?在形成资源竞争的时候,也就是说,多个线程有可能访问同一共享资源的时候。

其实就是锁住了某块在线程间共享内存,避免该块内存被同时访问,这就是所谓的 communicate by sharing memory 。但是这种方式会造成锁的竞争、内存管理、死锁以及难以解释的随机唤醒等问题。

2. share memory by communicating

既然传统的加锁共享内存机制存在问题,Go 语言又是如何实现并发的呢?

Go 语言允许我们将数据从一个线程发送到另一个线程。类似于 Unix 下 I/O 多路复用的原理。当一个线程处理完数据后将数据发出,另一个线程等待接收数据。当数据没有处理完时,线程会一直等待,这样就大大降低了出现锁冲突的概率。这就是所谓的 share memory by communicating

下面是一段简单的例子,通过开启两个协程和通道,简单说明 Go 语言进行数据的发送和处理。

12345678910111213141516171819202122232425262728293031323334353637383940
package main

import (    "fmt"    "time")

func main() {

	// 创建发送数据的通道	ch := make(chan int)	// 接收数据的通道	done := make(chan bool)

	// 开启协程	go sendingGoRoutine(ch)	go receivingGoRoutine(ch,done)

	// 这里会阻塞,直到数据接收完毕	<- done}

func sendingGoRoutine(ch chan int){	//start a timer to wait 5 seconds	t := time.NewTimer(time.Second*5)大专栏  ARTS/>	<- t.C	fmt.Println("Sending a value on a channel")

    // 发送数据    ch <- 45}

func receivingGoRoutine(ch chan int, done chan bool){

	// 接收 ch 通道的数据	v := <- ch	fmt.Println("Received value ", v)	// 处理完成后向 done 通道发送数据告知操作已完成	done <- true}

个人 Review

在使用 Go 的并发模型时,需要注意的地方是避免过度使用,某些地方还是需要通过传统的锁机制来实现的,比如引用计数、文件读写等,这些都可以通过 Go 提供的 sync 包实现。

阿尔伯特-爱因斯坦曾经说过“学习一门新知识之后,如果你还不能简单地解释它,说明你并没有理解它。”

对于任何一门新语言或者新知识,如果我们学习之后还不能将其中的要点通俗易懂地给别人讲清楚,那只能说明我们掌握的还不够,理解的还不深。及时复习和总结归纳显得尤为必要。

三 Tip

Unix 套接字编程系列之套接字介绍

在 Linux 系统中,有很多进程间通信方式,套接字(Socket)就是其中的一种。

由于项目涉及到 Linux 网络编程的知识,最近又重新看了一下《Unix网络编程 第三版》,将一些学习笔记总结一下。

1.套接字地址结构

大多数套接字函数都需要一个指向套接字地址结构的指针作为参数。每个协议族都定义它自己的套接字地址结构。这些结构的名字均以sockaddr_开头,并以对应每个协议族的唯一后缀结尾。

1.要学习套接字编程,就要先理解套接字地址结构,这些结构可以在两个方向传递:从进程到内核和从内核到进程。其中从内核到进程方向传递是值-结果参数。

2.地址转换函数在地址的文本表达和它们存放在套接字地址结构中的二进制值之间进行转换,多数现存的 IPv4 代码使用 inet_addr 和 inet_ntoa 这两个函数,但是有最新的函数 inet_pton 和 inet_ntop 同时适用于IPv4 和 IPv6 两种代码。要注意的是,地址转换函数存在的一个问题是它们与所转换的地址类型协议相关。

首先来看一下不同的套接字地址结构

IPv4 套接字地址结构

IPv4 套接字地址结构通常称为“网际套接字地址结构”,它以 sockaddr_in 命名,定义在 <netinet/in.h> 头文件中,下图给出了它的 POSIX 定义。

123456789101112131415
struct in_addr {	in_addr_t	s_addr;		/* 32-bit IPv4 address */};					/* network byet orered */

stuct sockaddr_in{	uint8_t		sin_len;	/* length of structure */	sa_familyt	sin_family;	/* AF_INET */	in_port_t 	sin_port;	/* 16-bit TCP or UDP port number */					/* network byet orered */	struct in_addr	sin_addr;	/* 32-bit IPv4 address */					/* network byet orered */	char		sin_zero[8]	/* unused */};

当作为一个参数传递进任何套接字函数时,套接字地址结构总是以引用形式(也就是以指向该结构的指针)来传递。然而以这样的指针作为参数之一的任何套接字函数必须处理来自所支持的任何协议族的套接字地址结构。

对套接字地址结构做几点一般性的说明

长度字段 sin_len 是为了增加对 OSI 协议的支持而添加的,在此之前,第一个成员是 sin_family ,它是一个无符号短整数(unsigned short)。并不是所有的厂家都支持套接字地址结构的长度字段,而且 POSIX 规范也不要求有这个成员。该成员的数据类型是 uint8_t 。正是因为有了长度字段,才简化了长度可变套接字地址结构的处理。

POSIX 的规范只需要这个结构中的 3 个字段:sin_family,sin_addr,sin_port。对于符合 POSIX 的实现来说,定义额外的结构字段是可以接受的,这对于网际套接字地址结构来说也都是正常的,几乎所有的实现都增加了 sin_zero 字段,所以所有的套接字地址结构大小都至少是 16 字节。

IPv4 地址和 TCP 或 UDP 端口号在套接字地址结构中总是以网络字节序来存储。在使用这些字段时,我们必须牢记这一点。

套接字地址结构仅在给定主机上使用:虽然结构中的某些字段(例如 IP 地址和端口号)用在不同主机之间的通信中,但是结构本身并不在主机之间传递。

1.2 通用的套接字地址结构

当作为一个参数传递进任何套接字函数时,套接字地址结构总是以引用形式(也就是以指向该结构的指针)来传递。为了以这样的指针作为参数之一的任何套接字函数必须处理来自所支持的任何协议族的套接字地址结构,在<sys/socket.h>头文件中定义了一个通用的套接字地址结构。

123456
struct sockaddr{	uint8_t		sa_len;	sa_family_t	sa_family;	/* address family: AF_XXX value */	char		sa_data[14];	/* protocol-specific address */};

这些通用套接字地址结构的唯一用途就是对指向特定于协议的套接字地址结构的指针执行类型强制转换。

IPv6 套接字地址结构

定义在 <netinet/in.h> 头文件中

12345678910111213141516171819
struct in6_addr{	uint8_t		s6_addr[16];	/* 128-bit IPv6 address */					/* network byet orered */};

#define SIN6_LEN	/* required for compile-time tests */

stuct sockaddr_in6{	uint8_t		sin6_len;	/* length of this structure (28)*/	sa_family_t	sin6_family;	/* AF_INET6 */	in_port_t 	sin6_port;	/* transport layer port# */					/* network byet orered */	uint32_t	sin6_flowinfo;	/* flow information,undefined */	struct in6_addr	sin6_addr;	/* IPv6 address */					/* network byet orered */	uint32_t	sin6_scope_id;	/* set of interfaces for a scope */		};
  • 如果系统支持套接字地址结构中的长度字段,那么SIN6_LEN常值必须定义。
  • IPv6的地址族是AF_INET6,而IPv4的地址族是AF_INET。

1.4 新的通用套接字地址结构

作为 IPv6 套接字 API 的一部分而定义的新的通用套接字地址结构克服了现有 stuct sockaddr 的 一些缺点。不像 stuct sockaddr,新的 struct sockaddr_storage 足以容纳系统所支持的任何套接字地址结构。该结构在<netinet/in.h> 头文件中定义。

1234567891011
struct sockaddr_storage{	uint8_t		ss_len;		/* length of this structure (implementation dependent)*/	sa_family_t	ss_family;	/* address family :AF_xxx value */	/* implementation-dependent elements to provide:	 * a) alignment sufficient to fulfill the alignment requirements of	 *    all socket address types that the system supports.	 * b) enough storage to hold any type of socket address that the	 *    system supports.         */};

如果系统支持的任何套接字地址结构有对齐需要,那么 sockaddr_storage 能够满足最苛刻的对齐要求。
sockaddr_storage 足够大,能够容纳系统支持的任何套接字地址结构。

注意,除了 ss_len 和 ss_family 外(如果有的话),sockaddr_storage 结构中的其他字段对用户来说是透明的。sockaddr_storage 结构必须类型强制转换成或复制到适合与 ss_family 字段所给出地址类型的套接字地址结构中,才能访问其他字段。

1.5 套接字地址结构比较

四 Share

UNIX / LINUX CHEAT SHEET 英文

一个总结了常用的 Unix / Linux 命令的网站,分类比较详细,包括以下类别下的各种具体的命令的用法

文件系统

操作系统

进程管理

网络

IO

压缩

内存管理

快捷键

公众号 加贝君的理想国

12/29/2018

加贝木苇

原文地址:https://www.cnblogs.com/lijianming180/p/12284388.html

时间: 2024-10-05 14:18:56

ARTS的相关文章

error:Please check whether you installed aRts correctly or use

编译kdelibs-3.5.10.tar.gz checking whether uic supports -L ... yes checking whether uic supports -nounload ... yes checking if Qt needs -ljpeg... no checking for rpath... yes checking for KDE... will be installed in /usr/local/kdelibs3checking grepping

KDE声音服务器 arts

arts介绍arts是KDE的核心声音系统,支持多音频流.全双工.网络声音请求.ALSA与OSS驱动后端.JACK声音服务器后端等扩展,它既是声音服务器,也 提供一套音频软件的开发类库.对于KDE3.x系统来说arts是不可缺少的一部分,KDE中几乎所有与声音有关的特性都和arts有平滑稳定的集成.由于arts是其作者的个人秀,在2004年底作者宣布终止对arts的维护后它已经很难再作出进一步的突破,这之后的更新大多都是其他志愿者的零敲碎 打,而且其艰涩的开发框架对后来者也是一个接手门槛.尽管a

ARTS第五周

ARTS第五周 ARTS是什么? Algorithm:每周至少做一个leetcode的算法题: Review:阅读并点评至少一篇英文技术文章: Tip/Techni:学习至少一个技术技巧: Share:分享一篇有观点和思考的技术文章. Algorithm 题目:买卖股票的最佳时机 IV 解题思路 这是LeetCode上买卖股票系列的最后一题,也是难度最大的一题.这里我们用标准的动态规划算法来解这道题,既然是用动态规划的办法,那就要先定义出动态规划的状态和状态转移方程. 状态:根据题意,我们需要定

ARTS第六周

ARTS第六周 ARTS是什么? Algorithm:每周至少做一个leetcode的算法题: Review:阅读并点评至少一篇英文技术文章: Tip/Techni:学习至少一个技术技巧: Share:分享一篇有观点和思考的技术文章. Algorithm 题目:141. Linked List Cycle 解题思路 本题是链表相关的一道题,题目给出一个链表,问我们这个链表中是否有环.题目中给出了三个例子来帮助我们分析是否有环,我们可以简单理解为,判断链表中是否有节点被超过两个节点的next指针指

ARTS第七周

ARTS是什么? Algorithm:每周至少做一个leetcode的算法题: Review:阅读并点评至少一篇英文技术文章: Tip/Techni:学习至少一个技术技巧: Share:分享一篇有观点和思考的技术文章. Algorithm 本周的算法题是一道关于链表的题目19. Remove Nth Node From End of List,给定一个列表,要求移除倒数第n个节点,并返回头结点. ? 解题思路 由于我们并不知道列表有多长,所以得遍历列表探测当前节点是否是列表尾节点,又因为我们需要

ARTS第八周

ARTS是什么? Algorithm:每周至少做一个leetcode的算法题: Review:阅读并点评至少一篇英文技术文章: Tip/Techni:学习至少一个技术技巧: Share:分享一篇有观点和思考的技术文章. Algorithm 题目:206. Reverse Linked List 解题思路 题目要求反转列表,即原本指向后一个节点的当前节点转而指向它的前一个节点,因此我们使用两个指针来分别表示当前节点和前一个节点,调转当前节点指针指向前一个后,然后依次遍历.. 代码 public L

ARTS第九周

ARTS第九周 ARTS是什么? Algorithm:每周至少做一个leetcode的算法题: Review:阅读并点评至少一篇英文技术文章: Tip/Techni:学习至少一个技术技巧: Share:分享一篇有观点和思考的技术文章. Algorithm 题目:21. Merge Two Sorted Lists 解题思路 此题要求我们合并两个排好序的链表,合并之后的链表要求也是有序的,因此我们在每次做合并操作的时候需要比较两个链表头节点的大小,较小的那个节点加到新链表的尾端. 同时,取较小节点

ARTS第十周

ARTS第十周 ARTS是什么? Algorithm:每周至少做一个leetcode的算法题: Review:阅读并点评至少一篇英文技术文章: Tip/Techni:学习至少一个技术技巧: Share:分享一篇有观点和思考的技术文章. Algorithm 题目:20. Valid Parentheses 解题思路 1.根据题意需要进行括号配对,当遇到左括号的时候需要存起来,以便遇到右括号的时候去取出来进行配对:当遇到右括号的时候就直接去和保存的左括号进行配对. 2.根据配对的特性我们采用栈这种数

AI太复杂?别怕!华为云Model Arts让你分分钟玩转AI!

近两年来,随着全球科学技术的高速发展,AI人工技术已经成了世界各先进国家未来科技发展的焦点,为了能够跟上全球科技发展的大潮流,各国科技界都已集结全部力量,希望能在AI人工智能领域取得有效突破. "未来科技世界是属于AI人工智能的"--仿佛一夜之间,家居,电子产品,电商,汽车,互联网等各种产业都想要搭上AI人工智能这辆通往未来的高速列车,"AI+xx"也成了最新潮的产业布局模式.可是,市场上还有一部分,准确地说是很大一部分传统产业在推进AI的过程中遭遇了瓶颈期--AI

ARTS起始篇

ARTS简要说明(每周需要完成以下四项): Algorithm:每周至少做一道 leetcode 的算法题,编程训练.刻意练习. Review:需要阅读并点评至少一篇英文技术文章,这个是四项里面对我最难的一项.要成为技术高手,英文是必修课. Tip:学习至少一个技术技巧,可以是日常工作中遇到的问题.踩的坑,学习的点滴记录. Share:分享一篇有观点和思考的技术文章.持续的输出,建立自己的影响力. —— 2019.06.08 原文地址:https://www.cnblogs.com/jxl001