《C++编程思想》第二章 数 据 抽 象(原书代码+习题+答案)

相关代码例如以下:

1.

<span style="font-size:18px;">/*声明与定义的差别*/

#include <iostream>
using namespace std;

extern int i;//声明
extern float f(float);//声明

float b;//定义+声明
float f(float a)//定义
{

	return a + 1.0;
}

int i;//定义
int h(int x)//定义+声明
{
	return x + 1;
}

int main()
{
	b = 1.0;
	i = 2;
	cout<<f(b)<<endl;
	cout<<h(i)<<endl;

	return 0;
}</span>

2.

<span style="font-size:18px;">/*test.h*/
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
/* 一个袖珍C库    C     */
typedef struct STASHtag
{
	int size;              //Size of each space
	int quantity;          //Number of storage spaces
	int next;              //Next empty space
	unsigned char* storage;//storage指针是一个unsigned char*。

这是 C 编译器支持的最小的存储片。虽然在某些机器
                           //上它可能与最大的一般大,这依赖于详细实现。 storage指向的内存从堆中分配
}Stash;

void initialize(Stash* S, int Size);//initialize()完毕对 struct stash 的必要的设置。即设置内部变量为适当的值。

最初,设置
                                    //storage指针为零。设置size 指示器也为零,表示初始存储未被分配。

void cleanup(Stash* S);             //清除
int add(Stash* S, void* element);   //add()函数在stash的下一个可用位子上插入一个元素。首先,它检查是否有可用空间,如
                                    //果没有,它就用后面介绍的 inflate() 函数扩展存储空间。
void* fetch(Stash* S, int index);   //fetch()首先看索引是否越界,假设没有越界,返回所希望的变量地址,地址的计算採用与
                                    //add()中同样的方法
int count(Stash* S);                //返回所存储空间大小
void inflate(Stash* S, int increase);
/*inflate()函数使用realloc()为stash得到更大的空间块。 realloc()把已经分配而又希望重分配
的存储单元首地址作为它的第一个參数(假设这个參数为零,比如 initialize()刚刚被调用时。
realloc()分配一个新块)。第二个參数是这个块新的长度,假设这个长度比原来的小。这个块
将不须要作拷贝。简单地告诉堆管理器剩下的空间是空暇的。

假设这个长度比原来的大。在堆
中没有足够的相临空间,所以要分配新块,而且要拷贝内存。 assert()检查以确信这个操作成
功。(假设这个堆用光了。 malloc()、 calloc()和realloc()都返回零。

)*/</span>
<span style="font-size:18px;">/*test.c*/

/*如果有一个程序设计工具,当创建时它的表现像一个数组。但它的长度能在执行时建
立。我称它为stash*/

#include "test.h"

void initialize(Stash* S, int Size)
{
	S->size = Size;
	S->quantity = 0;
	S->storage = 0;
	S->next = 0;
}

void cleanup(Stash* S)
{
	if(S->storage)
	{
		puts("freeing storage");
		free(S->storage);
	}
}

int add(Stash* S, void* element)
{
	if(S->next >= S->quantity)
	{
		inflate(S,100);
	}
	memcpy(&(S->storage[S->next * S->size]),element,S->size );
	/*我们必须用标准 C 库函数memcpy( )一个字节一个字节地拷贝这个变量,第一个參数是 memcpy()
	開始拷贝字节的目的地址,由以下表达式产生:
	                &(S->storage[S->next * S->size])
	它指示从存储块開始的第 next个可用单元结束。这个数实际上就是已经用过的单元号加一
	的计数,它必须乘上每一个单元拥有的字节数,产生按字节计算的偏移量。

这不产生地址。而是
	产生处于这个地址的字节。为了产生地址,必须使用地址操作符 &。
	memcpy()的第二和第三个參数各自是被拷贝变量的開始地址和要拷贝的字节数。 n e x t计数
	器加一。并返回被存值的索引。

这样。程序猿能够在后面调用 fetch( )时用它来取得这个元素。

*/
	S->next ++;
	return (S->next - 1);
}

void* fetch(Stash* S, int index)
{
	if(index >= S->next || index < 0)
	{
		return 0;
	}
	return &(S->storage[index * S->size]);
}

int count(Stash* S)
{
	return S->next;
}

void inflate(Stash* S, int increase)
{
	void* v = realloc(S->storage,(S->quantity + increase)*S->size );
	assert(v);
	S->storage = v;//在 C 库中的 inflate()中,能够将void *赋给其它不论什么指针。比如S->storage = v;并且编译器能够通过。
	S->quantity += increase;
}</span>
<span style="font-size:18px;">/*main.c*/

#include "test.h"

#define BUFSIZE 80

int main()
{
	Stash intStash,stringStash;
	int i;
	FILE* file;
	char buf[BUFSIZE];
	char* cp;

	initialize(&intStash,sizeof(int));
	for(i = 0;i < 100;++i)
	{
		add(&intStash,&i);
	}

	initialize(&stringStash,sizeof(char)*BUFSIZE);
	file = fopen("main.c","r");
	assert(file);
	while(fgets(buf, BUFSIZE, file))
	{
		add(&stringStash, buf);
	}
	fclose(file);

	for(i = 0;i < count(&intStash);++i)
	{
		printf("fetch(&intStash, %d) = %d\n",i ,
			*(int*)fetch(&intStash,i));
	}
	i = 0;
	while((cp = fetch(&stringStash,i++)) != 0)
	{
		printf("fetch(&stringStash, %d) = %s",
			i-1,cp);
	}
	putchar(‘\n‘);
	cleanup(&intStash);
	cleanup(&stringStash);

	return 0;
}</span>

3.

<span style="font-size:18px;">#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
//C++
struct stash
{
	int size;                 //Size of each space
	int quantity;             //Number of storage spaces
	int next;                 //Next empty space
	unsigned char* storage;   //storage指针是一个unsigned char*。这是 C 编译器支持的最小的存储片,虽然在某些机器
	                          //上它可能与最大的一般大,这依赖于详细实现。 storage指向的内存从堆中分配
	void initialize(int Size);//initialize()完毕对 struct stash 的必要的设置,即设置内部变量为适当的值。最初,设置
	                          //storage指针为零。设置size 指示器也为零,表示初始存储未被分配。
	void cleanup();           //清除
	int add(void* element);   //add()函数在stash的下一个可用位子上插入一个元素。首先,它检查是否有可用空间,如
	                          //果没有,它就用后面介绍的 inflate() 函数扩展存储空间。

void* fetch(int index);   //fetch()首先看索引是否越界,假设没有越界,返回所希望的变量地址,地址的计算採用与
	                          //add()中同样的方法
	int count();              //返回所存储空间大小
	void inflate(int increase);
	/*inflate()函数使用realloc()为stash得到更大的空间块。 realloc()把已经分配而又希望重分配
	的存储单元首地址作为它的第一个參数(假设这个參数为零,比如 initialize()刚刚被调用时。
	realloc()分配一个新块)。第二个參数是这个块新的长度,假设这个长度比原来的小。这个块
	将不须要作拷贝,简单地告诉堆管理器剩下的空间是空暇的。假设这个长度比原来的大,在堆
	中没有足够的相临空间。所以要分配新块,而且要拷贝内存。 assert()检查以确信这个操作成
	功。

(假设这个堆用光了。 malloc()、 calloc()和realloc()都返回零。

)*/
};
</span>
<span style="font-size:18px;">/*test.cpp*/

/*如果有一个程序设计工具。当创建时它的表现像一个数组,但它的长度能在执行时建
立。我称它为stash*/

#include "test.h"

void stash::initialize(int Size)
{
	size = Size;
	quantity = 0;
	storage = 0;
	next = 0;
}

void stash::cleanup()
{
	if(storage)
	{
		puts("freeing storage");
		free(storage);
	}
}

int stash::add(void* element)
{
	if(next >= quantity)
	{
		inflate(100);
	}
	memcpy(&(storage[next * size]),element,size );
	/*我们必须用标准 C 库函数memcpy( )一个字节一个字节地拷贝这个变量,第一个參数是 memcpy()
	開始拷贝字节的目的地址,由以下表达式产生:
	                &(S->storage[S->next * S->size])
	它指示从存储块開始的第 next个可用单元结束。这个数实际上就是已经用过的单元号加一
	的计数,它必须乘上每一个单元拥有的字节数,产生按字节计算的偏移量。这不产生地址,而是
	产生处于这个地址的字节,为了产生地址。必须使用地址操作符 &。
	memcpy()的第二和第三个參数各自是被拷贝变量的開始地址和要拷贝的字节数。 n e x t计数
	器加一,并返回被存值的索引。这样,程序猿能够在后面调用 fetch( )时用它来取得这个元素。*/
	next ++;
	return (next - 1);
}

void* stash::fetch(int index)
{
	if(index >= next || index < 0)
	{
		return 0;
	}
	return &(storage[index * size]);
}

int stash::count()
{
	return next;
}

void stash::inflate( int increase)
{
	void* v = realloc(storage,(quantity + increase)*size );
	assert(v);
	storage = (unsigned char*)v;
	quantity += increase;
}</span>
<span style="font-size:18px;">#include "test.h"
#define BUFSIZE 80

int main()
{
	stash intStash,stringStash;
	int i;
	FILE* file;
	char buf[BUFSIZE];
	char* cp;

	intStash.initialize(sizeof(int));
	for(i = 0;i < 100;++i)
	{
		intStash.add(&i);
	}

	stringStash.initialize(sizeof(char)*BUFSIZE);
	file = fopen("main.cpp","r");
	assert(file);
	while(fgets(buf, BUFSIZE, file))
	{
		stringStash.add(buf);
	}
	fclose(file);

	for(i = 0;i < intStash.count();++i)
	{
		printf("intStash.fetch(%d) = %d\n",i,
			*(int*)intStash.fetch(i));
	}
	i = 0;
	while((cp = (char*)stringStash.fetch(i++)) != 0)
	{
	     printf("stringStash.fetch(%d) = %s",
			i-1,cp);
	}
	putchar(‘\n‘);
	intStash.cleanup();
	stringStash.cleanup();
	return 0;
}</span>

4.

<span style="font-size:18px;">/*1.h     C     */
typedef struct STASHtag
{
	int size;              //Size of each space
	int quantity;          //Number of storage spaces
	int next;              //Next empty space
	unsigned char* storage;//storage指针是一个unsigned char*。这是 C 编译器支持的最小的存储片,虽然在某些机器
                           //上它可能与最大的一般大,这依赖于详细实现。 storage指向的内存从堆中分配
}Stash;

void initialize(Stash* S, int Size);//initialize()完毕对 struct stash 的必要的设置,即设置内部变量为适当的值。最初,设置
                                    //storage指针为零,设置size 指示器也为零,表示初始存储未被分配。

void cleanup(Stash* S);             //清除
int add(Stash* S, void* element);   //add()函数在stash的下一个可用位子上插入一个元素。首先,它检查是否有可用空间。如
                                    //果没有,它就用后面介绍的 inflate() 函数扩展存储空间。

void* fetch(Stash* S, int index);   //fetch()首先看索引是否越界,假设没有越界,返回所希望的变量地址,地址的计算採用与
                                    //add()中同样的方法
int count(Stash* S);                //返回所存储空间大小
void inflate(Stash* S, int increase);
/*inflate()函数使用realloc()为stash得到更大的空间块。

realloc()把已经分配而又希望重分配
的存储单元首地址作为它的第一个參数(假设这个參数为零。比如 initialize()刚刚被调用时,
realloc()分配一个新块)。第二个參数是这个块新的长度。假设这个长度比原来的小,这个块
将不须要作拷贝,简单地告诉堆管理器剩下的空间是空暇的。假设这个长度比原来的大,在堆
中没有足够的相临空间。所以要分配新块,而且要拷贝内存。 assert()检查以确信这个操作成
功。(假设这个堆用光了。 malloc()、 calloc()和realloc()都返回零。

)*/</span>
<span style="font-size:18px;">//C++2.h
struct stash
{
	int size;                 //Size of each space
	int quantity;             //Number of storage spaces
	int next;                 //Next empty space
	unsigned char* storage;   //storage指针是一个unsigned char*。这是 C 编译器支持的最小的存储片,虽然在某些机器
	                          //上它可能与最大的一般大。这依赖于详细实现。 storage指向的内存从堆中分配
	void initialize(int Size);//initialize()完毕对 struct stash 的必要的设置,即设置内部变量为适当的值。

最初,设置
	                          //storage指针为零,设置size 指示器也为零。表示初始存储未被分配。
	void cleanup();           //清除
	int add(void* element);   //add()函数在stash的下一个可用位子上插入一个元素。

首先,它检查是否有可用空间,如
	                          //果没有,它就用后面介绍的 inflate() 函数扩展存储空间。
	void* fetch(int index);   //fetch()首先看索引是否越界。假设没有越界。返回所希望的变量地址,地址的计算採用与
	                          //add()中同样的方法
	int count();              //返回所存储空间大小
	void inflate(int increase);
	/*inflate()函数使用realloc()为stash得到更大的空间块。 realloc()把已经分配而又希望重分配
	的存储单元首地址作为它的第一个參数(假设这个參数为零,比如 initialize()刚刚被调用时,
	realloc()分配一个新块)。第二个參数是这个块新的长度,假设这个长度比原来的小。这个块
	将不须要作拷贝。简单地告诉堆管理器剩下的空间是空暇的。假设这个长度比原来的大,在堆
	中没有足够的相临空间,所以要分配新块,而且要拷贝内存。 assert()检查以确信这个操作成
	功。(假设这个堆用光了, malloc()、 calloc()和realloc()都返回零。)*/
};
</span>
<span style="font-size:18px;">#include "1.h"
#include "2.h"
#include <stdio.h>

struct A
{
	int I[100];
};

struct B
{
	void f();
};

void B::f()
{}

int main()
{
	printf("sizeof struct A = %d bytes\n",
		sizeof(A));//每一个 int 占二个字节
	printf("sizeof struct B = %d bytes\n",
		sizeof(B));//struct B 是神秘的,由于它是没有数据成员的 struct
	printf("sizeof Stash in C = %d bytes\n",
		sizeof(Stash));
	printf("sizeof stash in C++ = %d bytes\n",
		sizeof(stash));
	/*最后两个 sizeof 语句表明在 C++ 中的结构长度与 C 中等价版本号的长度同样。

C++ 尽力不
    添加不论什么花费*/

	return 0;
}</span>

5.

<span style="font-size:18px;">#ifndef NESTED_H_
#define NESTED_H_

struct stack//这个嵌套 struct 称为 link。它包含指向这个表中的下一个 link 的指针和指向存放在 link 中的数据的指针。假设 next 指针是零。意味着表尾。
{
	struct link
	{
		void* data;
		link* next;
		void initialize(void* Data, link* Next);
	}*head;
	void initialize();
	void push(void* Data);
	void* peek();
	void* pop();
	void cleanup();//cleanup 去除每一个栈元素,并释放data 指针
};
#endif</span>
<span style="font-size:18px;">#include "nested.h"
#include <stdlib.h>
#include <assert.h>

void stack::link::initialize(void* Data, link* Next)
//简单地两次使用范围分解运算符,以指明这个嵌套 struct 的名字。

stack::link::initialize( ) 函数取參数并把參数赋给它的成员们
{
	data = Data;
	next = Next;
}

void stack::initialize()
//stack::initialize( ) 函数置 head 为零。使得这个对象知道它有一个空表
{
	head = 0;
}

void stack::push(void* Data)
//stack::push( ) 取參数,也就是一个指向希望用这个 stack 保存的一块数据的指针。而且把
//这个指针放在栈顶
{
	link* newlink = (link*)malloc(sizeof(link));
	assert(newlink);
	newlink->initialize(Data, head);
	head = newlink;
}

void* stack::peek()
//返回head的值
{
	return head->data;
}

void* stack::pop()
//stack::pop( )取出当前在该栈顶部的 data 指针,然后向下移 head 指针,删除该栈老的栈顶元素
{
	if(head == 0)
	{
		return 0;
	}
	void* result = head->data;
	link* oldHead = head;
	head = head->next;
	free(oldHead);
	return result;
}

void stack::cleanup()
//stack::cleanup()创建cursor 在整个栈上移动。用free()释放每一个link的data和link 本身
{
	link* cursor = head;
	while(head)
	{
		cursor = cursor->next;
		free(head->data);
		free(head);
		head = cursor;
	}
}</span>
<span style="font-size:18px;">#include "nested.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>

#define BUFSIZE 100

int main(int argc, char** argv)
{
	stack textlines;
	FILE* file;
	char* s;
	char buf[BUFSIZE];
	assert(argc == 2);
	textlines.initialize();
	file = fopen(argv[1],"r");
	assert(file);
	while(fgets(buf, BUFSIZE, file))
	{
		char* string = (char*)malloc(strlen(buf)+1);
		assert(string);
		strcpy(string, buf);
		textlines.push(string);
	}

	while((s = (char*)textlines.pop()) != 0 )
	{
		printf("%s",s);
		free(s);
	}
	textlines.cleanup();

	return 0;
}</span>

6.

<span style="font-size:18px;">#include <iostream>
using namespace std;
//假设在 S::f() 中没有范围分解。
//编译器会缺省地选择 f() 和 A 的成员版本号
int A;
void f()
{}

struct S
{
	int A;
	void f();
};

void S::f()
{
	::f();
	::A++;
	A--;
}
int main()
{
	return 0;
}</span>

1) 创建一个 struct 声明,它有单个成员函数。然后对这个成员函数创建定义。创建这个新数据类型的对象,再调用这个成员函数。

#include <iostream>
using namespace std;

struct Student
{
	void play();
};

void Student::play()
{
	cout<<"Funny!"<<endl;
}

int main()
{
	Student s;
	s.play();
	return 0;
}

2) 编写而且编译一段代码,这段代码完毕数据成员选择和函数调用。

#include <iostream>
#include <string>
using namespace std;

struct Student
{
	string address;
	void play(string address);
};

void Student::play(string address)
{
	cout<<address<<" "<<"is Funny!"<<endl;
}

int main()
{
	Student s;
	s.play("Xi‘an");
	return 0;
}

3) 写一个在还有一个结构中的被声明结构的样例(嵌套结构)。并说明怎样定义这个结构的成员。

#include <iostream>
#include <string>
using namespace std;

#ifndef TEST_H_
#define TSET_H_

struct family
{
	struct school
	{
		string address;
		void schools(string address);
	}*addr;
	int number;
	void families(int number);
};

#endif
#include "test.h"

void family::school::schools(string address)//取參数并输出
{
	cout<<"The school‘s address: "<<address<<endl;
}
void family::families(int number)//取參数并输出
{
	cout<<"The family‘s people number: "<<number<<endl;
}
#include "test.h"

int main()
{
	family f;
	f.families(5);

	return 0;
}

4) 结构有多大?写一段能打印各个结构的长度的代码。创建一些结构。它们仅仅有数据成员。还有一些有数据成员和函数成员。然后创建一个结构,它根本没有成员。打印出全部这些结构的长度。

对于根本没有成员的结构的结果作出解释。

#include <stdio.h>

struct A
{
	char a;
	int  b;
};

struct B
{
	void f();
	double d;
};

struct C
{

};

void B::f()
{}

int main()
{
	printf("sizeof struct A = %d bytes\n",
		sizeof(A));//每一个 int 占四个字节,char占一个字节,可是要是四的倍数即为八
	printf("sizeof struct B = %d bytes\n",
		sizeof(B));//每一个double占八个字节,函数字节数为八
	printf("sizeof struct C = %d bytes\n",
		sizeof(C));//struct C 是神秘的,由于它是没有数据成员的 struct

	return 0;
}

5) C++对于枚举、联合和 struct 自己主动创建 typedef 的等价物,正如在本章中看到的。

写一个能说明这一点的小程序。

#include <iostream>
#include <string>
using namespace std;

typedef struct
{
	int age;
	string address;
}student;

typedef union
{
	int a;
	double d;
}number;

typedef enum
{
	white,black,blue,green
}colour;

int main()
{
	student s;
	s.address = "Xi‘an";
	s.age = 18;
	cout<<"student‘s address: "<<s.address<<endl;
	cout<<"student‘s age: "<<s.age<<endl;

	number n;
	n.a = 5;
	cout<<"people number:"<<n.a<<endl;

	colour c = white;
	cout<<"number of enum: "<<c<<endl;

	return 0;
}

对于上述答案仅供參考,如有错误希望大家指出,谢谢大家。

时间: 2024-11-07 16:27:41

《C++编程思想》第二章 数 据 抽 象(原书代码+习题+答案)的相关文章

《C++编程思想》 第十三章 继承和组合 (原书代码+习题+解答)

一.相关知识 使用其他人已经创建并调试过的类: 关键是使用类而不是更改已存在的代码.这一章将介绍两种完成这件事的方法.第一种方法是很直接的:简单地创建一个包含已存在的类对象的新类,这称为组合,因为这个新类是由已存在类的对象组合的. 第二种方法更巧妙,创建一个新类作为一个已存在类的类型,采取这个已存在类的形式,对它增加代码,但不修改它.这个有趣的活动被称为继承,其中大量的工作由编译器完成.继承是面向对象程序设计的基石,并且还有另外的含义,将在下一章中探讨. 对于组合和继承(感觉上,它们都是由已存在

《C++编程思想》第四章 初始化与清除(原书代码+习题+解答)

相关代码: 1. #include <stdio.h> class tree { int height; public: tree(int initialHeight); ~tree(); void grow(int years); void printsize(); }; tree::tree(int initialHeight) { height = initialHeight; } tree::~tree() { puts("inside tree destructor&quo

java编程思想 第二章

这篇时间较之前篇章时间靠后,是由于,某一天晚上看完Java编程思想文献之后来不及做笔记了. 以下笔记基本为转载,不是原创 第二章   一切都是对象 目录: 2.1 用引用操纵对象 2.2 必须由你创建所有对象 2.3 永远不需要销毁对象 2.4 创建新的数据类型:类 2.5 方法.参数和返回值 2.6 构建一个Java程序 2.7 你的第一个Java程序 2.8 注释和嵌入式文档 2.9 编码风格 2.1 用引用操纵对象 一切都看作对象,操纵的标识符实际上是对象的一个“引用”,遥控器(引用)操纵

《C++编程思想》第二章 数 据 抽 象(习题+答案)

相关代码如下: 1. <span style="font-size:18px;">/*声明与定义的区别*/ #include <iostream> using namespace std; extern int i;//声明 extern float f(float);//声明 float b;//定义+声明 float f(float a)//定义 { return a + 1.0; } int i;//定义 int h(int x)//定义+声明 { ret

java编程思想--第二章 一切都是对象

如果不做引申的话,本章没有多少可总结的内容.有些以前没有注意的细节可以写下来. 1.数据存储的位置 (1).寄存器.程序控制不了. (2).堆栈.对象的引用.基本类型. (3).堆.各种对象. (4).常量存储.和代码在一起. (5).非RAM存储.主要指流对象和持久化对象,前者准备网络传输,后者被丢到了硬盘上. 2.java中的数组会被自动初始化: (1).基本类型数组元素会被初始化为0 (2).引用类型数组元素会被初始化为null 3.变量作用域 (1).基本类型的跟C一样 (2).引用类型

《C++编程思想》 第十四章 多态和虚函数 (原书代码+习题+讲解)

一.相关知识点 函数调用捆绑 把函数体与函数调用相联系称为捆绑(binding).当捆绑在程序运行之前(由编译器和连接器)完成时,称为早捆绑.我们可能没有听到过这个术语,因为在过程语言中是不会有的:C编译只有一种函数调用,就是早捆绑.上面程序中的问题是早捆绑引起的,因为编译器在只有 instrument地址时它不知道正确的调用函数.解决方法被称为晚捆绑,这意味着捆绑在运行时发生,基于对象的类型.晚捆绑又称为动态捆绑或运行时捆绑.当一个语言实现晚捆绑时,必须有一种机制在运行时确定对象的类型和合适的

编程珠玑第二章

编程珠玑第二章 A题 给定一个最多包含40亿个随机排列的32位整数的顺序文件,找出一个不在文件中一32位整数. 1.在文件中至少存在这样一个数? 2.如果有足够的内存,如何处理? 3.如果内存不足,仅可以用文件来进行处理,如何处理? 答案: 1.32位整数,包括-2146473648~~2146473647,约42亿个整数,而文件中只有40亿个,必然有整数少了. 2.如果采用位数思想来存放,则32位整数最多需要占用43亿个位.约512MB的内存空间. 可以采用前一章的位处理方法.然后判断每个in

一维向量旋转算法 编程珠玑 第二章

看了编程珠玑第二章,这里面讲了三道题目,这里说一下第二题,一维向量旋转算法. 题目:将一个n元一维向量(例数组)向左旋转i个位置. 解决方法:书上讲解了5种方法,自己只想起来2种最简单方法(下面讲的前两种). 1.原始方法. 从左向右依次移动一位,对所有数据平移:这样循环i次,算法最坏时间复杂度达n^2.耗时不推荐. 2.空间换时间. 顾名思义,申请一个i长度的空间,把前i半部分放到申请空间中,再把后面的所有数据向左移动i个位置,最后把申请的空间中的数据放到后半部分.浪费空间,不推荐. 3.杂技

集体智慧编程_第二章(提供推荐)_1

前言:最近正在拜读Toby Segaran先生写的集体智慧编程,首先感谢Toby Segaran先生将知识以书本的方式传播给大家,同时也感谢莫映和王开福先生对此书的翻译,谢谢各位的不辞辛苦.首先在写随笔之前,跟各位分享一下我的编程环境:win7系统,python版本是2.7.10,开发环境我选择的是pycharm程序.本书的第一章为集体智慧导言,主要介绍的何为集体智慧和机器学习的相关概念和其局限性,以及与机器学习相关的例子和应用场景.下面开始机器学习第二章--提供推荐的相关内容. 本章主要内容: