编程珠玑——第二章习题

2023-12-11 17:18
文章标签 编程 第二章 习题 珠玑

本文主要是介绍编程珠玑——第二章习题,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1、考虑查找给定输入单词的所有变位词的问题。仅给定单词和字典的情况下,如何解决该问题?如果有一些时间和空间可以在响应任何查询之前预先处理字典,又会如何?

答:现给每个单词做标记,然后给予某一规则对标记之后的单词排序(标记相同的单词相邻),最后将标记相同的单词归到某一集合(写在一行或者输出到某一个文件)。

在查找某一个单词的变位词的时候,先按相同的规则得到标记,然后根据标记的值找到某一行(或某一个文件)。


在有预处理的情况下,可以将上述算法的第一步和第二步预先处理;查询的时候只需要根据单词得到标记,查询结果就行。(相当于copy了一份字典,并将copy的字典改造成可查询变位词的格式)。


2、给定包含4 300 000 000个32位整数的顺序文件,如何找出一个出现至少两次的整数?

答:1,2,3,3,4,5....这样的可以用二分查找

3、前面涉及了两个需要精巧代码来实现的向量旋转算法。将其分别作为独立的程序实现。在每个程序中,i和n的最大公约数如何出现?

答:

方法一:海豚算法

[cpp]  view plain copy
  1. void Shifting(char * pArry, int rotdistance, int len)  
  2. {  
  3.     int i, j;  
  4.     char temp;  
  5.     int igcd = gcd(rotdistance, len);   
  6.     for (i = 0; i < igcd; i++)  
  7.     {  
  8.         temp = pArry[i];  
  9.         j = i;  
  10.         for (; ;)  
  11.         {  
  12.             int k = j + rotdistance;  
  13.             k %= len;  
  14.             if ( k == i)  
  15.             {  
  16.                 break;  
  17.             }  
  18.             pArry[j] = pArry[k];  
  19.             j = k;  
  20.         }  
  21.         pArry[j] = temp;  
  22.     }  
  23. }  

     方法二:块交换算法

[cpp]  view plain copy
  1. #include <iostream>  
  2. using namespace std;  
  3.   
  4. //交换pArry[a...a+m-1]和pArry[b...b+m-1]  
  5. void myswap(char *pArry, int a, int b, int m)  
  6. {  
  7.     char temp;  
  8.     for (int i = 0; i < m; i++)  
  9.     {  
  10.         temp = pArry[a + i];  
  11.         pArry[a + i] = pArry[b + i];  
  12.         pArry[b + i] = temp;  
  13.     }  
  14.   
  15. }  
  16.   
  17. void Shifting(char * pArry, int rotdistance, int len)  
  18. {  
  19.     if (rotdistance == 0 || rotdistance == len)   
  20.     {  
  21.         return;  
  22.     }  
  23.   
  24.     int i, j, p;  
  25.     i = p = rotdistance;  
  26.     j = len - p;  
  27.   
  28.     while (i != j)  
  29.     {  
  30.         if (i > j)  
  31.         {  
  32.             myswap(pArry, p - i, p, j);  
  33.             i -= j;  
  34.         }  
  35.         else  
  36.         {  
  37.             myswap(pArry, p - i, p + j - i, i);  
  38.             j -= i;  
  39.         }  
  40.     }  
  41.     myswap(pArry, p - i, p, i);  
  42. }  
  43.   
  44. int _tmain(int argc, _TCHAR* argv[])  
  45. {  
  46.     char arry[] = "abcdefghijklmn";  
  47.     int len = strlen(arry);  
  48.     Shifting(arry, 10, len);  
  49.     return 0;  
  50. }  

     方法三:求逆算法

     根据矩阵的转置理论,对于矩阵AB,要得到BA,则分别求A和B的转置A', B',然后对(A'B')转置,即(A'B')' = BA。同理,可以得到另一种一维向量向左旋转的算法。将要被旋转的向量x看做两部分ab,这里a代表x中的前rotdistance个元素。首先对a部分进行反转,再对b部分进行反转,最后对整个向量x进行反转即可。

    对于字符串“abcdefgh”, rotdistance = 3, len = 8:

    reverse(1, rotdistance);          //cbadefgh

    reverse(rotdistance+1, len);  //cbahgfed

    reverse(1, len);                       //defghabc

[cpp]  view plain copy
  1. #include <iostream>  
  2. using namespace std;  
  3.   
  4. //对字符串中第i个字符到第j个字符进行反转,i、j>=1  
  5. void MyReverse(char * pArry, int i, int j)  
  6. {  
  7.     int front = i;  
  8.     int tail = j;  
  9.     char temp;  
  10.     while (front != tail && front < tail)  
  11.     {  
  12.         temp = pArry[front - 1];  
  13.         pArry[front - 1] = pArry[tail - 1];  
  14.         pArry[tail - 1] = temp;  
  15.         ++front;  
  16.         --tail;  
  17.     }  
  18. }  
  19.   
  20. //将字符串左旋转rotdistance个字符  
  21. void Shifting(char * pArry, int rotdistance, int len)  
  22. {  
  23.     if (rotdistance == 0 || rotdistance == len)  
  24.     {  
  25.         return;  
  26.     }  
  27.     MyReverse(pArry, 1, rotdistance);  
  28.     MyReverse(pArry, rotdistance + 1, len);  
  29.     MyReverse(pArry, 1, len);  
  30. }  
  31.   
  32. int _tmain(int argc, _TCHAR* argv[])  
  33. {  
  34.     char arry[] = "abcdefgh";  
  35.     int len = strlen(arry);  
  36.     Shifting(arry, 5, len);  
  37.     cout << arry << endl;  
  38.     return 0;  
  39. }  

4、几位读者指出,既然所有的三个旋转算法需要的运行时间都正比于n,杂技算法那的运行速度显然是求逆算法的两倍。杂技算法对数组中的每个元素进存储和读取一次。而求逆算法需要两次。在实际的计算机上进行实验以比较两者的速度差异,特别注意内存引用位置附近的问题。

答:可以将bc看做一个整体,然后运用向量旋转算法,得到bca。然后对bc运用向量旋转算法,得到cb。最后变换后的向量为即cba.

5、向量旋转函数将向量ab变为向量ba。如何将向量abc变为cba?(这对交换非相邻内存块的问题进行了建模)


6、XXX。。。。要查询名字Mike Lesk.而已按“LESK*M*”(也就是“5375^*6*”),随后,系统会输出他的电话号码。这样的服务随处可见。现在的问题是,不同的名字可能具有相同的按键编码。在Lesk的系统中发生这种情况时,系统会询问永和更多的信息。给定一个大的名字文件(例如标准的大城市电话号码簿),如何定位这些“错误匹配”?(当Lesk在这种规模的电话号码簿上做实验时,他发现错误匹配发生的概率仅仅是0.2%)如何实现一个以名字的按键编码为参数,并返回所有可能的匹配名字的函数??


7、程序员需要转置一个存储在磁带上的4000*4000的矩阵(每条记录的格式相同,为数十个字节)。最初提出的程序需要运行50个小时。程序员是如何将运行时间减少到半小时的??


8、给定一个n元师叔集合,一个实数t和一个整数k,如何快速确定是否存在一个k元子集,其元素纸盒不超过t??


9、顺序搜索和二分搜索代表了搜索时间和预处理时间之间的折中。处理一个n元表格时,需要执行多少次二分搜索才能弥补对表进行排序所消耗的预处理时间?


10、爱迪生要求某人计算一个空灯泡壳的容积。在使用测径仪和微积分进行数小时的计算后,他给出了答案——150立方厘米。而爱迪生在几秒钟之内就计算完毕并给出了“更

接近155”。他是如何实现的???

这篇关于编程珠玑——第二章习题的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/481460

相关文章

C#多线程编程中导致死锁的常见陷阱和避免方法

《C#多线程编程中导致死锁的常见陷阱和避免方法》在C#多线程编程中,死锁(Deadlock)是一种常见的、令人头疼的错误,死锁通常发生在多个线程试图获取多个资源的锁时,导致相互等待对方释放资源,最终形... 目录引言1. 什么是死锁?死锁的典型条件:2. 导致死锁的常见原因2.1 锁的顺序问题错误示例:不同

PyCharm接入DeepSeek实现AI编程的操作流程

《PyCharm接入DeepSeek实现AI编程的操作流程》DeepSeek是一家专注于人工智能技术研发的公司,致力于开发高性能、低成本的AI模型,接下来,我们把DeepSeek接入到PyCharm中... 目录引言效果演示创建API key在PyCharm中下载Continue插件配置Continue引言

C#反射编程之GetConstructor()方法解读

《C#反射编程之GetConstructor()方法解读》C#中Type类的GetConstructor()方法用于获取指定类型的构造函数,该方法有多个重载版本,可以根据不同的参数获取不同特性的构造函... 目录C# GetConstructor()方法有4个重载以GetConstructor(Type[]

【C++ Primer Plus习题】13.4

大家好,这里是国中之林! ❥前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站。有兴趣的可以点点进去看看← 问题: 解答: main.cpp #include <iostream>#include "port.h"int main() {Port p1;Port p2("Abc", "Bcc", 30);std::cout <<

Linux 网络编程 --- 应用层

一、自定义协议和序列化反序列化 代码: 序列化反序列化实现网络版本计算器 二、HTTP协议 1、谈两个简单的预备知识 https://www.baidu.com/ --- 域名 --- 域名解析 --- IP地址 http的端口号为80端口,https的端口号为443 url为统一资源定位符。CSDNhttps://mp.csdn.net/mp_blog/creation/editor

【Python编程】Linux创建虚拟环境并配置与notebook相连接

1.创建 使用 venv 创建虚拟环境。例如,在当前目录下创建一个名为 myenv 的虚拟环境: python3 -m venv myenv 2.激活 激活虚拟环境使其成为当前终端会话的活动环境。运行: source myenv/bin/activate 3.与notebook连接 在虚拟环境中,使用 pip 安装 Jupyter 和 ipykernel: pip instal

【编程底层思考】垃圾收集机制,GC算法,垃圾收集器类型概述

Java的垃圾收集(Garbage Collection,GC)机制是Java语言的一大特色,它负责自动管理内存的回收,释放不再使用的对象所占用的内存。以下是对Java垃圾收集机制的详细介绍: 一、垃圾收集机制概述: 对象存活判断:垃圾收集器定期检查堆内存中的对象,判断哪些对象是“垃圾”,即不再被任何引用链直接或间接引用的对象。内存回收:将判断为垃圾的对象占用的内存进行回收,以便重新使用。

Go Playground 在线编程环境

For all examples in this and the next chapter, we will use Go Playground. Go Playground represents a web service that can run programs written in Go. It can be opened in a web browser using the follow

深入理解RxJava:响应式编程的现代方式

在当今的软件开发世界中,异步编程和事件驱动的架构变得越来越重要。RxJava,作为响应式编程(Reactive Programming)的一个流行库,为Java和Android开发者提供了一种强大的方式来处理异步任务和事件流。本文将深入探讨RxJava的核心概念、优势以及如何在实际项目中应用它。 文章目录 💯 什么是RxJava?💯 响应式编程的优势💯 RxJava的核心概念

函数式编程思想

我们经常会用到各种各样的编程思想,例如面向过程、面向对象。不过笔者在该博客简单介绍一下函数式编程思想. 如果对函数式编程思想进行概括,就是f(x) = na(x) , y=uf(x)…至于其他的编程思想,可能是y=a(x)+b(x)+c(x)…,也有可能是y=f(x)=f(x)/a + f(x)/b+f(x)/c… 面向过程的指令式编程 面向过程,简单理解就是y=a(x)+b(x)+c(x)