《编程珠玑》笔记

AI权益加码!Claude Code、Cursor等20+工具免费用! 购周边限时加赠Coding Plan Lite,畅享主流AI工具!学习进阶更高效! 阅读详情

第二章

例子:将一个具有n个元素的一围向量向左旋转i个位置。例如假设n=8,i=3,那么向量abcdefgh旋转后为defghabc

解法:先考虑ab,转置a得到a`b,再转置b得到a`b`,然后再转置整个a`b`得到(a`b`)`,实际上就是ba。这就导致了下面产生 旋转作用的代码,注释显示了abcdefgh向左旋转三个元素的结果。

reverse(0,i-1)  //cbadefgh

reverse(i,n-1)  //cbahgfed

reverse(0,n-1)  //defghabc

程序:

#include <stdio.h>

char *reverse(char str[], int b, int e)
{
 char temp;
 int i,j;
 for (i=b,j=e;i<(b+e)/2;i++,j--)
 {
  temp = str[i];
  str[i] = str[j];
  str[j] = temp;
 }
 return str;
}

void main()
{
 char string[] = "abcdefgh";
 reverse(string,0,2);//cbadefgh
 printf("%s/n",string);
 reverse(string,3,7);//cbahgfed
 printf("%s/n",string);
 reverse(string,0,7);//defghabc
 printf("%s/n",string);
}

第七章

 利特尔法则:系统中物体的平均数量就是系统中物体离开系统的平均比率和每个物体在系统中所花费的平均时间的乘积。

简洁概括:队列中的平均物体数量是进入率和平均滞留时间之乘积。

例子1:一个夜总会可以容纳60个人,平均来说进入的人们会在里头呆上大约3个小时,所以进入率大约就是每小时20个人。队列上已经排着20个人了,所以我们可能还要等一个小时才能进去。我还不如先回家。

例子2:我在地下室中存有150个盛酒容器,每年我都要喝完(和买回)25个容器的酒。请问每个容器我要保存多少年?利特尔法则告诉我们用150个容器除以25个容器/年即得到6年。

第八章

例子:输入是一个具有n个整型数字(原文中是浮点数字)的向量x,输出其在输入的任何相邻子向量中找出的最大和。例如:如果输入向量包含下面10个元素,a[]={31,-41,59,26,-53,58,97,-93,-23,84},那么该程序返回a[2]和a[6]之和187。

解法:方法1,普通解法,运行时间为O(n*n)

方法2,分治解法,运行时间为O(nlogn)

方法3,扫描算法,它从最左端(元素x[0])开始,一直扫描到最右端(元素x[n-1]),记下所碰到过的最大总和子向量。最大值最初是0。前i个元素中,最大总和子数组要么在i-1个元素中(存储在masxsofar中),要么截至到位置i(存储在maxendinghere中)。我们不计算截至于位置i的最大子向量,反而使用截至于位置i-1的最大子向量。这个方法的关键就是变量maxendinghere。在该循环的第一个赋值语句前,maxendinghere包含了截至于位置i-1的最大子向量的值,复制语句修改它以包含截至于位置i的最大子向量的值。运行时间为O(n)

程序:

#include <stdio.h>
int max(int a,int b)
{
 return a>b?a:b;
}

int maxsum1(int b[])
{
 int sum,maxsofar = 0;
 for (int i=0;i<10;i++)
 {
  sum = 0;
  for (int j=i;j<10;j++)
  {
   sum += b[j];
   maxsofar = max(maxsofar,sum);
  }
 }
 return maxsofar;
}

int maxsum2(int b[],int l,int h)
{
 int i,m,lmax,rmax,sum,t;
 if (l > h)
 {
  return 0;
 }
 if (l == h)
 {
  return max(0,b[l]);
 }
 m = (l+h)/2;
 lmax = sum = 0;
 for (i=m;i>=l;i--)//找左半部分最大子分量
 {
  sum += b[i];
  lmax = max(lmax,sum);
 }
 rmax = sum = 0;
 for (i=m+1;i<=h;i++)//找右半部分最大子分量
 {
  sum += b[i];
  rmax = max(rmax,sum);
 }
 t = max(maxsum2(b,l,m),maxsum2(b,m+1,h));
 return max(lmax+rmax,t);
}

int maxsum3(int b[])
{
 int maxsofar = 0;
 int maxendinghere = 0;
 for (int i=0;i<10;i++)
 {
  maxendinghere = max(maxendinghere+b[i],0);
  maxsofar = max(maxsofar,maxendinghere);
 }
 return maxsofar;
}

void main()
{
 int a[]={31,-41,59,26,-53,58,97,-93,-23,84};
 printf("%d/n",maxsum1(a));
 printf("%d/n",maxsum2(a,0,9));
 printf("%d/n",maxsum3(a));
}

第九章

例子1:递归解法和标记值解法返回数组x[0..n-1]中(n值较大)的最大值(用递归时max最好用函数实现而不用宏实现)

程序:

#include <stdio.h>
int max(int a,int b)
{
 return a>b?a:b;
}

int arrmax1(int x[],int n)//递归解法
{
 if (n == 1)
  return x[0];
 else
  return max(x[n-1],arrmax1(x,n-1));
}

int arrmax2(int x[],int n)//标记值解法
{
 int i=0,maxnumber;
 while (i<n)
 {
  maxnumber = x[i];
  i++;
  while (x[i]<maxnumber)
   i++;
 }
 return maxnumber;
}

void main() x
{
 int a[]={1,9,8,7,6,5,4,3,2,10};
 int len = sizeof(a)/sizeof(a[0]);
 printf("The Max Number in Array is :%d/n",arrmax1(a,len));
 printf("The Max Number in Array is :%d/n",arrmax2(a,len));
}

例子2:多项式Y=Anpow(X,n)+An-1pow(X,n-1)+...+A1pow(X,1)+A0求和

程序:

#include <stdio.h>

int polynomial1(int a[],int x,int n)
{
 int y,xi;
 y = a[0];
 xi = 1;
 for (int i=1;i<n;i++)
 {
  xi = x * xi;
  y = y + a[i] * xi;
 }
 return y;
}

int polynomial2(int a[],int x,int n)
{
 int y;
 y = a[n-1];
 for (int i=n-2;i>=0;i--)
 {
  y = x*y +a[i];
 }
 return y;
}

void main()
{
 int arr[]={1,2,3,4,5,6};
 int len = sizeof(arr)/sizeof(arr[0]);
 printf("多项式Y=Anpow(X,n)+An-1pow(X,n-1)+...+A1pow(X,1)+A0求和/n");
 printf("The Sum Of Polynomial is :%d/n",polynomial1(arr,2,len));
 printf("The Sum Of Polynomial is :%d/n",polynomial2(arr,2,len));
}

第十一章

例子:快速排序法找第k小元素

程序:

#include <stdio.h>
#include <stdlib.h>

void swap(int x[],int a, int b)
{
 int temp = x[a];
 x[a] = x[b];
 x[b] = temp;
}

int randint(int l,int u)
{
 return l+rand()%(u-l+1);
}

void select(int x[],int l,int u,int k)
{
 int i,j,temp,t;
 if (l>=u)
  return;
 swap(x,l,randint(l,u));
 t = x[l];
 i = l;
 j = u+1;
 while (1)
 {
  do
  {
   i++;
  } while(i<=u && x[i]<t);
  do
  {
   j--;
  } while(x[j]>t);
  if (i>j)
   break;
  temp = x[i];
  x[i] = x[j];
  x[j] = temp;
 }
 swap(x,l,j);
 if (j<k)
 {
  select(x,j+1,u,k);
 }
 else if (j>k)
 {
  select(x,l,j-1,k);
 }
}

void main()
{
 int x[8] = {1, -2, 3, 10, -4, 7, 2, -5};
 int k;
 printf("输入要找的第k小元素(0<=k<=7):");
 scanf("%d",&k);
 select(x,0, 7, k);
 printf("%d/n", x[k]);
}

扩展:分治法找第k小元素。找到数组第K小元素后,有且只有x[0]至x[k-1]是比x[k]小的。所以同样算法可解决下面问题,复杂度同为O(n)。
“给定一个具有n个元素的整数集,一个整数t以及一个整数k,如何快速确定该整数集是否存在一具有k个元素的子集,其中各元素的总和至多只能为t”http://hi.baidu.com/balancelife/blog/item/619e73243686b628d507424e.html

程序:

#include <stdio.h>
#define MAXN 8
int x[MAXN] = {1, -2, 3, 10, -4, 7, 2, -5};

void swap(int a, int b)
{
 int ntemp = x[a];
 x[a] = x[b];
 x[b] = ntemp;
}
//分治发(二分)类似快速排序
int MinK(int l, int h, int k)
{
 if (l > h)
  return 0;
 
 int m = l;
 for (int i=l+1; i<=h; i++)
 {
  if (x[i] < x[m])
   swap(++m, i);
 }
 swap(m, l);
 
 if (k == m)
  return x[m];
 else if (k < m)
  return MinK(l, m-1, k);
 else
  return MinK(m+1, h, k);
}

int main(int argc, char* argv[])
{
 //第0小元素是最小元素
 int n = MinK(0, MAXN-1, 6);
 printf("%d/n", n);
 return 0;
}

第十二章

例子1:产生随机整数的排序子集:输入m和n(m<=n),输出一个由m个随机数字组成的有序数列,这些随机数范围是0..n-1。

程序:

#include <iostream.h>
#include <stdlib.h>
void genknuth(int m,int n)
{
 for (int i=0;i<n;i++)
 {
  if (rand()%(n-i)<m)
  {
   cout<<i<<"/n";
   m--;
  }
 }
}
void main()
{
 genknuth(40,50);
}

例子2:弄乱数组内元素顺序

程序:

#include <iostream.h>
#include <stdlib.h>

int randint(int l,int u)
{
 return l+rand()%(u-l+1);
}

void swap(int x[],int a, int b)
{
 int temp = x[a];
 x[a] = x[b];
 x[b] = temp;
}

void main()
{
 int i,n;
 cout<<"输入数组元素个数:";
 cin>>n;
 int *arr = new int[n];
 for (i=0;i<n;i++)
 {
  arr[i] = i+1;
 }
 for (i=0;i<n;i++)
 {
  swap(arr,i,randint(i,n-1));
 }
 for (i=0;i<n;i++)
 {
  cout<<arr[i]<<' ';
 }
 delete [] arr;
}

例子3:两个函数分别返回一个较大的随机数和一个指定输入范围内的随机数

程序:

#include <iostream.h>
#include <stdlib.h>

int bigrand()
{
 return RAND_MAX*rand()+rand();
}

int randint(int l,int u)
{
 return l+rand()%(u-l+1);
}

void main()
{
 cout<<"返回一个较大的随机数:"<<bigrand()<<endl;
 cout<<"返回一个制定输入范围内的随机数:"<<randint(1,10)<<endl;
}

例子4:从0..n-1中随机选择m个整数,既允许重复又需要按照随机顺序输出结果

程序:

#include <stdlib.h>
#include <iostream.h>

void main()
{
 int m,n;
 cout<<"Input m and n(m<=n):"<<endl;
 cin>>m>>n;
 for (int i=0;i<m;i++)
 {
  cout<<rand()%n<<' ';
 }
}
 

别再只盯着数据流了!GNU Radio消息传递(Message Passing)保姆级实战指南,从QT GUI交互到外部命令控制 本文深入探讨GNU Radio的消息传递机制(Message Passing),提供从QT GUI交互到外部Python脚本控制的实战指南。通过详细解析PMT数据类型、QT动态交互实现及ZMQ集成方案,帮助开发者突破传统数据流限制,实现高效双向通信。特别适合需要实时参数调整和外部控制的数字信号处理场景。 阅读详情

相关推荐

编程珠玑》读书笔记(一)

第一章 目的是为了引入位向量数据结构。 转载自 http://www.cnblogs.com/wuyuegb2312/p/3136831.html 位向量的定义和应用:位向量/位图在充分利用小空间存储大数据方面很有优势。Linux内核中很多用到了位向量。 一般地,对于多个对象和一个性质,这些对象可能满足(true)也可能不满足(false)这条性质。那么,为了表示所有对象对这个性质的满足情

DengNice的专栏 2090

编程珠玑》阅读笔记

本书的开篇主要讲了要具体分析自己的问题,具体化自己所要解决的问题。文中以a,b对话的形式,然后又具体分析其对话来进行观点的表达。比如在听完文中两个人的对话后,可以这样分析:如果主存容量不是严格的限制在1mb,或是1~2mb之间,那么我们就可以一次性将所有数据都加载到主存中。 如果主存容量严格的限制txt在1mb,因此无法一次载入完成排序。那么我们可以将文件分割为两个文件,再分别用bitma...

weixin_34307464的博客 212

编程珠玑(好书,看了以后让你茅舍顿开)

好书,看了以后让你茅舍顿开,很多公司面试都会用到这里面的题。。。。。。

第十四届北京师范大学程序设计竞赛 [6/11]

虽然只是校赛,但是题目质量真的很高啊,学到了新姿势,自己的思维还是太局限了.,A Check In————————————————————————————————————————————————水题, 注意队伍名可能是bnuu这类B Squared Permutation————————————————————————————————————————————————其实还是一个基础的题目,维护区

Tabris的博客 1630

C++反汇编代码分析——函数调用

代码如下: #include "stdlib.h" int sum(int a,int b,int m,int n) {   return a+b; } void main() {   int result = sum(1,2,3,4);   system("pause"); }   有四个参数的sum函数,接着在main方法中调用sum函数。 在debu

u010488395的专栏 782

三种方法求出一个数组的最大字数组和

方法1:暴力法 遍历数组三次(i in 0..len, j in i..len, k in i..j),在第三次(k in i..j)求和sum+=data[k],并与当前max比较,大则更新max值,小max值不变 时间复杂度为O(n^3); 具体代码实现: int max(int a, int b) { return (a>b ? a : b); } int max_sub_su

千里之行,始于足下 1471

编程珠玑》读书笔记开场白

在正式写述之前,先说一些闲话。 实习期间其实也是看了不少书的,可是几天下来,发觉看过的内容忘记了不少。之前也听说过导师说看了论文就一定要做好笔记,否则很容易忘记的。看来做好读书笔记真的是相当重要啊。在我看来,写笔记至少有两点好处,一是强迫自己总结看过的内容,二是也方便以后阅读重温已学过的知识。何乐而不为呢? 前几天买了《编程珠玑》,里面包含了不少有趣的算法问题,听说一些大公司也喜欢用里面的题来

Leo的博客 1114

编程珠玑》 读书笔记

编程珠玑》 读书笔记 娄雨禛 PB16060356 准确的问题描述   很多时候,我们总是过度关注了解决问题所用的巧妙算法,而将问题本身的重要性忽视。当我们拿到一个问题时,应当反复研读问题的每一个细节,因为正是这些细节的细微偏差导致了我们在解决问题时方案与技巧的重大不同。   如果我们只花很少的时间研读问题本身,而过度专注于问题的解决时,极有可能在百般忙碌之后,发现自己走了一大段弯路。...

weixin_30900589的博客 194

编程珠玑读书笔记

xx

onlyForCloud的专栏 531

编程珠玑》读书笔记

---------------------------基本原则------------------------1、仔细分析小问题有时可带来巨大的实际好处2、要打破概念上的障碍,转而解决一个更简单的问题,才能有效地解决问题3、不要勿勿忙忙将第一灵感编写为程序,应该在编码之前进行充分的思考、权衡和抉择,以找出最有效的算法和设计4、能用小的程序的话就不要编写大程序5、数据结构对软件的贡献极大:   a.

baiwen1979的专栏 1459

编程珠玑笔记

编程珠玑笔记 第一章开篇 友好的对话 在别人不会问问题时,引导他去问问题也是一个很大的学问,Jon与一个程序员问的问题而展开。 问题:如何将1千万条记录排序?(都是七位的电话号码)最好是将时间控制在十秒钟左右,如果不行,几分钟也可以,但是不能超过十分钟,同时不可超过一兆的内存。 Jon先生要求我思考一分钟,并给他一个答案。我的答案有两个,一是使用链表的方式,运用插入排序的方法,二是使...

张念磊的博客 589

编程珠玑》看书笔记

临睡前翻看了下《编程珠玑(续)》这本书,看到第一章就被吸引了,性能监视工具这节从计算素数入手。题目是: 打印所有小于1000的素数 简单直白的方法就是,针对每个小于1000的数字n,从2开始到n-1,如果能被任意一个数整除,那它就不是素数。代码如下: int prime(int n) { int i; for(i = 2; i < n; i++)

captainjackNO1的专栏 793

编程珠玑笔记

2008年8月15日。 昨晚并没有完成理想中的任务,同时昨天也没有完习题第三题的解答。自己思考的结果没有完成,并且解法二也没有自己在机器上实现,所以今天用25分钟来完成习题3的思考以后,便是对后面几题的解答好了,先读一下昨天的思考。 简单总结下昨天的思路,如下图所示。 graph TD A(思路) --&gt;B(自己推导) A --&gt;C(同余定理) ...

张念磊的博客 411

12、编程珠玑笔记十二取样问题

12、编程珠玑笔记十二取样问题          本篇名言:“一个能从别人的观念来看事情,能了解别人心灵活动的人永远不必为自己的前途担心。”          欢迎转载,转载请标明出处:          小的程序往往能够寓教于乐,正如蛤蟆在数据结构中的笔记,基本都是小程序。          当然有些小程序也是可以用来商用的。          该章作者实现关于随机取样的问题。

badman250的专栏 3万+
上一篇: C程序设计(第二版) 第十章习题
下一篇: 致精团队笔试题2道
birdzb
博客等级 码龄22年 53粉丝 29原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值