Skip to content

Commit

Permalink
Merge pull request #1 from julycoding/master
Browse files Browse the repository at this point in the history
Merge
  • Loading branch information
jackingod committed Mar 21, 2014
2 parents d1da759 + a2c8f7c commit 304de08
Show file tree
Hide file tree
Showing 436 changed files with 5,600 additions and 1,760 deletions.
17 changes: 10 additions & 7 deletions Readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,33 +4,36 @@

原编程艺术系列从2011年4月至今,写了42个编程问题,在创作的过程当中,得到了很多朋友的支持,特别是博客上随时都会有朋友不断留言,或提出改进建议,或show出自己的思路、代码,或指正bug。

为了方便大家更好的改进、优化、增补编程艺术系列,特把原来博客上的编程艺术系列和其它部分精选文章同步到此,邀请各位一起协作:若发现任何问题、错误、bug,或可以优化的每一段代码,欢迎随时贡献。
为了方便大家更好的改进、优化、增补编程艺术系列,特把博客上的这个程序员编程艺术系列和博客内其它部分经典文章同步到此,邀请各位一起协作:若发现任何问题、错误、bug,或可以优化的每一段代码,欢迎随时贡献。

# Start Reading
* [中文目录](ebook/zh/Readme.md) Enhancement in progress
* [English Contents](ebook/en/Readme.md) Translation in progress


# How To Contribute
* 添补剩下的章节,参考本书[中文目录](ebook/zh/Readme.md)未完成的章节。「必选,优先级最高,目前剩9篇文章尚未同步https://github.com/julycoding/The-Art-Of-Programming-By-July/issues/182
* 指正 bug 「必选」
* 优化原文章上的C/C++ 代码,可以添加在原代码的后面,或者放到[ebook/code](ebook/code/)文件夹内。 「必选」
* 添补剩下的章节,参考本书[中文目录](ebook/zh/Readme.md)未完成的章节。「必选,目前剩2篇文章尚未同步https://github.com/julycoding/The-Art-Of-Programming-By-July/issues/182
* 一章一章的测试所有代码,指正 bug,修正错误。 「必选,可到这里认领:https://github.com/julycoding/The-Art-Of-Programming-By-July/issues/210
* 优化原文章上的C/C++ 代码,优化后的代码可以放到[ebook/code](ebook/code/)文件夹内。 「必选」
* 添加其它语言如Java、python、go 的代码,放在[ebook/code](ebook/code/)文件夹内。 「可选」
* 重绘所有的图片:https://github.com/julycoding/The-Art-Of-Programming-by-July/issues/80
* 翻译成英文版,参考[中文目录](ebook/zh/Readme.md),把翻译后的文章编辑到这[English Version](ebook/en/Readme.md),注:不必逐字翻译,精简大气即可(如有兴趣翻译,请到这里领取感兴趣的章节翻译:https://github.com/julycoding/The-Art-Of-Programming-by-July/issues/84 )
* 自己主导续写新的章节,如第四十一章
* 自己主导续写新的章节;
* 任何你想做的事情。

你可以做以上任何一件或几件事情,如遇到任何问题或疑惑,咱们可以随时讨论:
<https://github.com/julycoding/The-Art-Of-Programming-by-July/issues?state=open>
「如不知如何在github上提交及同步作者的更新,可参考此文:http://www.cnblogs.com/rubylouvre/archive/2013/01/24/2874694.html

# Contributors
为示鼓励,所有贡献了本 github 的朋友,可以随时向 July 索取他博客内所有博文集锦的最新CHM文件,或任何一个系列的最新PDF或WORD,以此感谢所有贡献的朋友:https://github.com/julycoding/The-Art-Of-Programming-by-July/graphs/contributors ,并非常期待你的加入,thanks。
为示鼓励,所有贡献了本 github 的朋友,可以随时向 July 索取他博客内所有博文集锦的最新CHM文件,或任何一个系列的最新PDF或WORD,甚者,本系列集结出版成书后,愿赠送所有contributors 一人一本新书,以此感谢所有贡献的朋友:https://github.com/julycoding/The-Art-Of-Programming-by-July/graphs/contributors ,并非常期待你的加入,thanks。

集结令:欢迎所有已经贡献过本github的66位朋友加入此QQ群:149638123,验证信息为你贡献本项目时用的github昵称。

孤军奋战的时代早已远去,我们只有团结起来,才能帮助到更多更无数的人。[@研究者July](http://weibo.com/julyweibo),始于二零一三年十二月十四日。

# Copyright
本《程序员编程艺术》的版权属于July 等原作者们,严禁其他任何人出版,严禁用于任何商业用途,违者必究法律责任。July、二零一四年一月二十一日晨。
本电子书的版权属于July 等原作者们,严禁其他任何人出版,严禁用于任何商业用途,违者必究法律责任。July、二零一四年一月二十一日晨。

# July' PDF
* 支持向量机通俗导论(理解SVM的三层境界)Latex版PDF:http://vdisk.weibo.com/s/zrFL6OXKgnlcp
Expand Down
2 changes: 1 addition & 1 deletion ebook/build/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ $(BUILD)/html/$(BOOKNAME).html:
cp TAOP.png $(BUILD)/html
@tmpdir=`pwd`;\
cd $(BUILD)/html;\
mdtogh --css --user=$(GHUSER) --pass=$(GHPASS) --toc --book=$$tmpdir/book.json --file_reg='^\d.+\.md$$' $$tmpdir/$(SRC_DIR);
mdtogh --css --user=$(GHUSER) --pass=$(GHPASS) --toc --toc_file=$$tmpdir/$(SRC_DIR)Readme.md --book=$$tmpdir/book.json --file_reg='^\d.+\.md$$' $$tmpdir/$(SRC_DIR);

$(BUILD)/pdf/$(BOOKNAME).pdf: $(TITLE)
mkdir -p $(BUILD)/pdf
Expand Down
5 changes: 5 additions & 0 deletions ebook/build/book.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"title": "The Art of Programming By July",
"description": "本书是July和他伙伴们的《程序员编程艺术》的电子书",
"coverimage": "TAOP.png"
}
120 changes: 120 additions & 0 deletions ebook/code/c/LCAProblem.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
/**
* Copyright (c) 2014 The TAOPP book Authors. All rights reserved.
* Use of this source code is governed by a BSD-style license that can be found
* in the LICENSE file.
*
* Filename: LCAProblem.c
* Brief: The C program for solving LCA problem
* Version: 0.1
* Created: Tue Mar 18 21:25:58 2014
*
* Author(s): Liang Wang<fairywell28@yahoo.com>
* eriol
* July
*
*/

/**
* @brief 在二叉排序树中查找给定两个节点的LCA节点
*
* @author C version 0.1, 2014/3/18, Liang Wang<fairywell28@yahoo.com>
* C++ version 0.2, 2014, July
* C++ version 0.1, 2011, eriol
* @brief 在二叉排序树中查找给定两个节点的LCA节点
*
* @param root 该二叉排序树的根节点指针
* @param u 给定节点一的指针
* @param v 给定节点二的指针
*
* @return 找到LCA节点返回其指针;否则返回NULL
*/
Node* FindLowestCommonAncestorBst(Node* root, Node* u, Node* v)
{
int left_value = u->value;
int right_value = v->value;
Node* parent_node = NULL;
Node* cur_node = root;

// 参数检查
if (NULL == root || NULL == u || NULL == v
|| root == u || root == v || u == v) {
fprintf(stderr, "Wrong input data! Exit!");
return NULL;
}

// 调整左右节点值到正确
if (left_value > right_value) {
swap(left_value, right_value);
}

while (cur_node) {
// 如果cur_node的值小于u、v的值,说明LCA节点应该在其右子树中
if (cur_node->value < left_value) {
parent_node = cur_node;
cur_node = cur_node->right;
} else if (cur_node->value > right_value) {
// 如果cur_node的值大于u、v的值,则应该查询其左子树
parent_node = cur_node;
cur_node = cur_node->left;
} else if (cur_node->value == left_value || cur_node->value == right_value) {
// 找到节点u或者v处,说明其父节点即为所求
return parent_node;
} else {
// 现在cur_node的值处于u和v的值之间,显然即为所求
return cur_node;
}
}

// 数据有误,找不到任何的LCA节点
return NULL;
}

/**
* @brief 在二叉排序树中查找给定两个节点的LCA节点,递归版本
*
* @author C version 0.1, 2014/3/19, Liang Wang<fairywell28@yahoo.com>
*
* @param root 该二叉排序树的根节点指针
* @param u 给定节点一的指针
* @param v 给定节点二的指针
*
* @return 找到LCA节点返回其指针;否则返回NULL
*/
Node* FindLcaBstRecursively(Node* root, Node* u, Node* v)
{
// 参数检查
// NOTICE:特别包含了u、v即是root节点的情况,此时应该返回NULL
if (NULL == root || NULL == u || NULL == v
|| root == u || root == v || u == v) {
fprintf(stderr, "Wrong input data: Arguments check failed! Exit!");
return NULL;
}

int left_value = u->value;
int right_value = v->value;

// 调整左右节点值到正确
if (left_value > right_value) {
swap(left_value, right_value);
}

// 判断当前节点是否为所求LCA节点
// 情形1:u、v分别在root的左右子树上
if (root->value > left_value
&& root->value < right_value) {
return root;
}

// 情形2:u、v都在root的同一棵子树且u、v有一个节点是root的子节点
if (root->right == u || root->right == v
|| root->left == u || root->left == v) {
return root;
}

// 当前节点不是所求LCA,则递归返回左右子树的LCA节点
if (root->value < left_value) { // 查找右子树
return FindLcaBstRecursively(root->right, u, v);
} else if (root->value > right_value) { // 查找左子树
return FindLcaBstRecursively(root->left, u, v);
}
}
61 changes: 61 additions & 0 deletions ebook/code/cpp/chapter35.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
//compiled with g++
#include <iostream>
#include <vector>
#include <algorithm>
#include <iterator>
#include <cassert>
using namespace std;

void cycle_leader(vector<int> &a,int from, int mod) {
for (int i = from * 2 % mod;i != from; i = i * 2 % mod)
swap(a[from],a[i]);
}

void perfect_shuffle(vector<int> &a,int n){
int n2,m,i,k,t;
vector<int>::iterator iter = a.begin()+1; //exclude index 0
for(;n > 1;){
//step 1
n2 = n * 2;
for(k = 0,m = 1; n2 / m >=3; ++k,m *= 3)
;
m /= 2;
// 2m = 3^k - 1 , 3^k <= 2n < 3^(k + 1)

//step 2 STL/algorithm-rotate
rotate(iter+m, iter+n, iter+m+n ); //right cyclic shift of the index[m+1,...,n+m] O(n)

//step 3
for(i = 0,t = 1;i < k; ++i,t *= 3)
cycle_leader(a,t,m * 2 +1);

//step 4
iter += (m * 2);
n -= m;
}
//n = 1
swap(a[1],a[2]);
}

int main(){
vector<int > a;
a.push_back(0);//to make index start from 1
int num = 0,length = 0;
cout<<"Please input your number to be shuffled and '0' to end up \n";
cin>>num;
while(num != 0){
a.push_back(num);
cin>>num;
}
cout<<"The input number is \n";
copy(a.begin()+1,a.end(),ostream_iterator<int> (cout," "));
cout<<"\n";

length = a.size();
assert(length % 2 == 1); //the size of input number is even
perfect_shuffle(a,length / 2);

cout<<"After shuffered,the number is \n";
copy(a.begin()+1,a.end(),ostream_iterator<int> (cout," "));
cout<<"\n";
}
157 changes: 157 additions & 0 deletions ebook/code/js/chapter04/chapter04.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
/*
* By Frederick-S
* 2014-03-08
*/

// 1. 穷举

/*
* @param {Array} arr 目标数组
* @param {Number} number 在数组中查找两个数,使得其和为 number
* @example
* var arr = solution1([1, 2], 3);
*/
function solution1(arr, number) {
for (var i = 0, length = arr.length; i < length; i++) {
for (var j = i + 1; j < length; j++) {
if (arr[i] + arr[j] == number) {
return [arr[i], arr[j]];
}
}
}

return [];
}

// 2. 二分查找

/*
* @param {Array} arr 目标数组
* @param {Number} number 在数组中查找两个数,使得其和为 number
* @example
* var arr = solution2([1, 2], 3);
*/
function solution2(arr, number) {
arr.sort(function (a, b) {
return a - b;
});

var index = 0;
for (var i = 0, length = arr.length; i < length; i++) {
index = binarySearch(arr, number - arr[i], 0, length - 1);

if (index >= 0 && index != i) {
return [arr[i], arr[index]];
}
}

return [];
}

function binarySearch(arr, key, low, high) {
var mid = 0;

while (low <= high) {
mid = Math.floor((low + high) / 2);

if (arr[mid] == key) {
return mid;
} else if (arr[mid] > key) {
high -= 1;
} else if (arr[mid] < key) {
low += 1;
}
}

return -1;
}

// 3. 双数组指针扫描

/*
* @param {Array} arr 目标数组
* @param {Number} number 在数组中查找两个数,使得其和为 number
* @example
* var arr = solution3([1, 2], 3);
*/
function solution3(arr, number) {
var subtraction = arr.map(function (value, index, array) {
return number - value;
});

arr.sort(function (a ,b) {
return a - b;
})

subtraction.sort(function (a, b) {
return b - a;
})

var i = 0, length = arr.length, j = length - 1;

while (i < length && j > -1) {
if (arr[i] < subtraction[j]) {
i++;
} else if (arr[i] > subtraction[j]) {
j--;
} else {
if (i != j) {
return [arr[i], number - arr[i]];
}
}
}

return [];
}

// 4. 借助 hash

/*
* @param {Array} arr 目标数组
* @param {Number} number 在数组中查找两个数,使得其和为 number
* @example
* var arr = solution4([1, 2], 3);
*/
function solution4(arr, number) {
var hash = {};

arr.forEach(function (value, index, array) {
hash[value] = value;
});

for (var i = 0, length = arr.length; i < length; i++) {
if (hash[number - arr[i]]) {
return [arr[i], number - arr[i]];
}
}

return [];
}

// 5. 双指针两端扫描

/*
* @param {Array} arr 目标数组
* @param {Number} number 在数组中查找两个数,使得其和为 number
* @example
* var arr = solution5([1, 2], 3);
*/
function solution5(arr, number) {
var i = 0, j = arr.length - 1;

arr.sort(function (a, b) {
return a - b;
})

while (i < j) {
if (arr[i] + arr[j] > number) {
j--;
} else if (arr[i] + arr[j] < number) {
i++;
} else {
return [arr[i], arr[j]];
}
}

return [];
}
Loading

0 comments on commit 304de08

Please sign in to comment.