プログラミング珠玉第一章の授業後の練習問題


1、ライブラリ関数を使用して並べ替え
この異なる言語には異なるライブラリ関数のソートcにqsortがあり、javaにはsortソートがあり、具体的にはコードを貼らない.
2、ビットロジックでビット演算を実現する
この問題の核心は,あるbitを0にし,そのビットを直接0と操作し,あるbitビットを一定に保つために,そのビットと1を操作し,あるbit位置1を1とし,そのビットを1と操作することである.
#define SHIFT 5
#define MASK 0x1F
#define N 10000000
int a[1 + N/BITSPERWORD];

void set(int i) {        a[i>>SHIFT] |=  (1<<(i & MASK)); }
void clr(int i) {        a[i>>SHIFT] &= ~(1<<(i & MASK)); }
int  test(int i){ return a[i>>SHIFT] &   (1<<(i & MASK)); }

原書の例i>>SHIFTは、iを32(intは4バイト、32 bit)除いた商がi位がi/32に属するintを得るbitビットの範囲内に相当し、
i&MASKは、i/32を取得する残高、すなわちintのbit範囲の数位に相当します.
4、k個[0,n]の重複しない数字を生成し、k#include <stdio.h> #include <windows.h> #include <algorithm> #include <stdlib.h> #include <iostream> #include <time.h> #define MAXNUM 10000000 void swap(int *a, int *b) { int tmp = *a; *a = *b; *b = tmp; } int main(void) { int i = 0; int *tmp = new int[MAXNUM+1]; // 1-MAXNUM LENGTH , 1-MAXNUM, MAXNUM , // r, tmp[i] tmp[r] , for(i = 0; i < MAXNUM; i++) { tmp[i] = i; } for(i = 0;i < MAXNUM; i++) { int p = rand(); // rand() RAND_MAX, 10000000, RAND_MAX , swap(&tmp[i],&tmp[MAXNUM - p]) if(i%2 == 0) { swap(&tmp[i],&tmp[p]); } else { swap(&tmp[i],&tmp[MAXNUM - p]); } } delete[] a; delete[] tmp; return 0; }
3、ビットマップの並べ替え(現在の4番目の問題の上で重複しない数字を得てからこの問題をやります)
#include <stdio.h>
#include <windows.h>
#include <algorithm>
#include <stdlib.h>
#include <iostream>
#include <time.h>
#define BITSPERWORD 32
#define SHIFT 5
#define MASK 0x1F
#define MAXNUM 10000000
int a[1 + MAXNUM/BITSPERWORD];

void set(int i) {        a[i>>SHIFT] |=  (1<<(i & MASK)); }
void clr(int i) {        a[i>>SHIFT] &= ~(1<<(i & MASK)); }
int  test(int i){ return a[i>>SHIFT] &   (1<<(i & MASK)); }
void swap(int *a, int *b)
{
	int tmp = *a;
	*a = *b;
	*b = tmp;
}
int main(void)
{

	int i = 0;
	int *tmp = new int[MAXNUM+1];
	// 1-MAXNUM     LENGTH      ,      1-MAXNUM,          MAXNUM ,    
	//     r,  tmp[i] tmp[r]  ,              
	for(i = 0; i < MAXNUM; i++)
	{
		clr(i);
		tmp[i] = i;
	}
	srand((unsigned)time(NULL));
	for(i = 0;i < MAXNUM; i++)
	{
		int p = rand();
		
		if(i%2 == 0)
		{
			swap(&tmp[i],&tmp[p]);
		}
		else
		{
			swap(&tmp[i],&tmp[MAXNUM - p]);
		}
	}
	
	DWORD start, stop;
    start = GetTickCount();
    

	for(i = 0; i < MAXNUM;i++)
		set(i);
	for(i = 0; i < MAXNUM; i++)
	{
		if(test(i))
		{
			printf("%d
",i); } } stop = GetTickCount(); printf("time: %lld ms
", stop - start); delete[] tmp; return 0; }
私が運転した後の時間はこんなに多いです
426040ms
ソート後の出力操作時間が
438ms
5、空きメモリは1 Mあるが、実際のコードは1.25 Mあり、どのようにコードを1 M以内に制御するか.
この問題の核心は、一度に1000000個の数を読み込むとメモリが足りなくなるため、1000000に対してグループ読み込みを行う必要があり、4つのグループに分けると仮定し、まず[0250000000]の範囲の本を読み、並べ替えて出力し、読み込み[250000,000,000,000,000,000,000]の数を並べ替えて、このようにします.方法がわかった以上、まず考えられる最初の問題は、いくつかのグループに分けることです.この問題は比較的簡単な1 Mメモリが8388608 bitで、1つのint 32 bit 8388608/32=261456で、250000に近いので、40グループに分けられます.現在の2番目の問題は、この40グループのデータをどのように読み込むかです.コードは以下の通りです.
 
 
#include <stdio.h>
#include <windows.h>
#include <algorithm>
#include <stdlib.h>
#include <iostream>
#include <time.h>
#define GROUPNUM 40
#define BITSPERWORD 32
#define SHIFT 5
#define MASK 0x1F
#define MAXNUM 10000000
int a[MAXNUM/GROUPNUM+1];
void set(int i) {        a[i>>SHIFT] |=  (1<<(i & MASK)); }
void clr(int i) {        a[i>>SHIFT] &= ~(1<<(i & MASK)); }
int  test(int i){ return a[i>>SHIFT] &   (1<<(i & MASK)); }
void swap(int *a, int *b)
{
	int tmp = *a;
	*a = *b;
	*b = tmp;
}
int main(void)
{

	int i,j,n = 0;
	int range = MAXNUM/GROUPNUM;
	int *tmp = new int[MAXNUM+1];
	// 1-MAXNUM     LENGTH      ,      1-MAXNUM,          MAXNUM ,    
	//     r,  tmp[i] tmp[r]  ,              
	for(i = 0; i < MAXNUM; i++)
	{
		tmp[i]=i;
	}
	srand((unsigned)time(NULL));
	for(i = 0;i < MAXNUM; i++)
	{
		int p = rand();
		
		if(i%2 == 0)
		{
			swap(&tmp[i],&tmp[p]);
		}
		else
		{
			swap(&tmp[i],&tmp[MAXNUM - p]);
		}
	}
	DWORD start, stop;
    start = GetTickCount();
	//        
	for(i = 0; i < GROUPNUM; i++)
	{
		//       
		for(j = 0; j < range; j++)
		{
			clr(j);
		}
		//    [range*i,range*i+range)        
		for(j = 0; j < MAXNUM; j++)
		{
			if(range*i <= tmp[j]  && tmp[j] < range*(i+1))
			{
				set(tmp[j]%range);
			}
		}
		//  [range*i,range*i+range)    
		for(j = 0; j < range; j++)
		{
			if(test(j))
			{
				printf("%d
",j); } } } stop = GetTickCount(); printf("time: %lld ms
", stop - start); delete[] tmp; return 0; }

ソート を すると
printf("%d
",j);

は3250 msパケット のみでメモリ の は したが, にすべてのデータを 40 し, に した.
6もし1つの が1 だけではないならば、10が れることができて、どのようにします
この は は 5 のアップグレード で、 のメモリを けて を することに して、 りのメモリは 5 の によって をグループ して べ えて、1つの は 10 れて、4 bitビットが1つの の を することに して、4*10^7 の を けます.
7、
1つの を し、test(i)がtrueを たと した 、この の み りを し、0より きい は、 をするときに することができ、 ではなく み まなくてもよい.
8、もし の が8008877888があるならば、メモリは として1 Mだけあって、どのように べ えます
この は が えることができるのは、1つの の の を むたびにソートするだけで、 の4 の とあまり がありません.
9、 の をどのように いて、 めてこのベクトルにアクセスするたびに することを します.
この はネット のgoogleでやっと えの を した. な は、2つの from toと1つの top=0を することである.
if(from[i] < top && to[from[i]] == i)
{
	printf("has used!
") } else { a[i] = 1; from[i] = top; to[top] = i; top++; }

top は、 された の を するために され、from[i]=topは、a[i]がいくつかの された であることを することに し、to[top]=iは、top の を するために される がdataの にどれだけあるかを す.したがって、1つのdata にアクセスするたびに、from[i]10、 コストの まで、 は が で を し、 に して で ることを した.ショップ・データベースは、 の を の なキーワードとして します( は を っており、これらのキーワードはほとんど です).どのようにしてショップのデータベースを して、 な と を にしますか?
の の2 が のハッシュインデックスとして され、 が で したとき、 な に かれる.そして、 が して を すると、 は に を します.これは、ハッシュ を する な です. に します. の の2 の はかなりランダムで、 の 2 はインデックスとして じません. くの の 2 は じですから.
11、 つのデータ を してコストを する
えはハトに わって、 にはハトがこんなに い を って べると いますか?この は な に ているようだ.
12、 で なペンを く
この はずいぶん に いたようです. です.