java钓鱼收信代码_数据结构题目训练记录(Java书写) One

此篇笔记,涉及到 数据结构中 序列,链表的使用

一、最大子列和问题

给定K个整数组成的序列{ N​1​​, N​2​​, ..., N​K​​ },“连续子列”被定义为{ N​i​​, N​i+1​​, ..., N​j​​ },其中 1。“最大子列和”则被定义为所有连续子列元素的和中最大者。例如给定序列{ -2, 11, -4, 13, -5, -2 },其连续子列{ 11, -4, 13 }有最大的和20。现要求你编写程序,计算给定整数序列的最大子列和。

本题旨在测试各种不同的算法在各种数据情况下的表现。各组测试数据特点如下:

数据1:与样例等价,测试基本正确性;

数据2:102个随机整数;

数据3:103个随机整数;

数据4:104个随机整数;

数据5:105个随机整数;

输入格式:

输入第1行给出正整数K (≤);第2行给出K个整数,其间以空格分隔。

输出格式:

在一行中输出最大子列和。如果序列中所有整数皆为负数,则输出0。

输入样例:

6

-2 11 -4 13 -5 -2

输出样例:

20

第一种方法:三重循环法,时间复杂度为 O(n3)

1 /**

2 * 这里用的第一种方法是三重循环方法 时间复杂度为 O(n^3)3 * 法一:三重循环。第一重标记子列最左端,第二重标记子列最右端,第三重由子列左端累加到子列右端。4 */

5 public classMaxSum1{6 public static int MaxSum1s(intA[])7 {8 int ThisSum = 0, MaxSum = 0;9 inti, j ,k;10 for(i = 0; i < A.length; i++) //i 是子列最左端

11 {12 for(j = i; j < A.length; j++)13 {14 ThisSum = 0; //每次都要将 ThisSum 归零,累加新一轮的子列和

15 for (k = i; k < j; k++) //将 A[i] 到 A[j] 累加,得到子列和

16 ThisSum +=A[k];17 if(ThisSum > MaxSum) //如果这一轮的子列和比最大子列和还大,存入 MaxSum

18 MaxSum =ThisSum;19 }20 }21 returnMaxSum;22 }23

24 public static voidmain(String[] args)25 {26 int lists[] = new int[] {-2 ,11, -4, 13, -5, -2};27 System.out.println(MaxSum1s(lists));28 }29 }

第二种方法:二重循环法

1 /**

2 * 法二:二重循环。对于相同的子列左端位置 i ,不同的右端位置 j ,我们只要每次在右端累加一项,即可求得每一个子列和。3 */

4 public classMaxSum2{5 public static int MaxSums(int[] A)6 {7 int MaxSum = 0, ThisSum = 0;8 inti, j;9 for(i = 0; i < A.length; i++)10 {11 ThisSum = 0;12 for(j = i; j < A.length; j++)13 {14 ThisSum +=A[j];15 if (ThisSum > MaxSum) //这里改成了,从 i 到 任意一处 j 来进行比较

16 {17 MaxSum =ThisSum;18 }19 }20 }21 returnMaxSum;22 }23

24 public static voidmain(String [] args)25 {26 int lists[] = new int[] {-2 ,11, -4, 13, -5, -2};27 System.out.println(MaxSums(lists));28 }29 }

第三种方法:分而治之

1 /**

2 *@author小喵钓鱼3 * @date 2020-02-02 13:534 * @veision 1.105 * 方法三:分而治之。6 * 将序列从中分为左右两个子序列。7 * 递归求得两个子列的最大和。8 * 从中分点分头向左、右两边扫描,找出跨过分界线的最大子列和。9 * 输出这三个子列和最大的一个。10 */

11 public classMaxSum3 {12 //比较三个数的

13 public static int Max3(int A, int B, intC)14 {15 return (A>B)?(A>C?A:C):(B>C?B:C);16 }17

18 /**

19 * 分治 list[left] 和 list[right] 的最大子列和20 *@paramList21 *@paramleft22 *@paramright23 *@return

24 */

25 public static int DivideAndConquer(int List[], int left, intright)26 {27 int MaxLeftSum, MaxRightSum; //存放左右子问题的解。

28 int MaxLeftBorderSum, MaxRightBorderSum; //存放跨分界线的结果。

29

30 intLeftBorderSum, RightBorderSum;31 intcenter, i;32

33 /*递归的终止条件,子列只有1个数字*/

34 if ( left ==right ) {35 if ( List[left] > 0 ) returnList[left];36 else return 0;37 }38

39 /*“分”的过程*/

40 center = ( left + right ) / 2; //找到中分点。

41 MaxLeftSum = DivideAndConquer ( List, left, center ); //递归求左子列和。

42 MaxRightSum = DivideAndConquer ( List, center+1, right ); //递归求右子列和。

43

44 /*求跨分界线的最大子列和*/

45 MaxLeftBorderSum = 0; LeftBorderSum = 0;46 for ( i = center; i >= left; i--) {47 LeftBorderSum +=List[i];48 if ( LeftBorderSum >MaxLeftBorderSum )49 MaxLeftBorderSum =LeftBorderSum;50 }//左边扫描结束。

51

52 MaxRightBorderSum = 0; RightBorderSum = 0;53 for ( i = center+1; i <= right; i++) {54 RightBorderSum +=List[i];55 if ( RightBorderSum >MaxRightBorderSum )56 MaxRightBorderSum =RightBorderSum;57 }//右边扫描结束。

58

59 /*返回“治”的结果*/

60 return Max3(MaxLeftSum, MaxRightSum, MaxLeftBorderSum +MaxRightBorderSum );61 }62

63 /*此函数用于保持接口相同*/

64 public static int MaxSum3 ( int List[], intN ) {65 return DivideAndConquer(List, 0, N - 1);66 }67

68 public static voidmain(String[] args) {69 int lists[] = new int[] {-2 ,11, -4, 13, -5, -2};70 System.out.println(MaxSum3(lists, lists.length));71 }72 }

二、Maximum Subsequence Sum (最大序列和,此题和上题比较类似)

Given a sequence of K integers { N​1​​, N​2​​, ..., N​K​​ }. A continuous subsequence is defined to be { N​i​​, N​i+1​​, ..., N​j​​ } where 1. The Maximum Subsequence is the continuous subsequence which has the largest sum of its elements. For example, given sequence { -2, 11, -4, 13, -5, -2 }, its maximum subsequence is { 11, -4, 13 } with the largest sum being 20.

Now you are supposed to find the largest sum, together with the first and the last numbers of the maximum subsequence.

Input Specification:

Each input file contains one test case. Each case occupies two lines. The first line contains a positive integer K (≤). The second line contains K numbers, separated by a space.

Output Specification:

For each test case, output in one line the largest sum, together with the first and the last numbers of the maximum subsequence. The numbers must be separated by one space, but there must be no extra space at the end of a line. In case that the maximum subsequence is not unique, output the one with the smallest indices i and j (as shown by the sample case). If all the K numbers are negative, then its maximum sum is defined to be 0, and you are supposed to output the first and the last numbers of the whole sequence.

Sample Input:

10

-10 1 2 3 4 -5 -23 3 7 -21

Sample Output:

10 1 4

1 /**

2 *@author小喵钓鱼3 * @date 2020-02-02 14:284 * @veision 1.105 */

6 public classMaximum {7 public static void Maximums(int list[], intN)8 {9 intThisSum, MaxSum, Forntdata, Enddata;10 int sublen; //设置 子列差

11 sublen = Forntdata = Enddata = ThisSum = 0;12 MaxSum = -1;13 for (int i = 0; i < N; i++)14 {15 ThisSum +=list[i];16 sublen ++; //差 + 1

17 if (ThisSum > MaxSum) //如果子列和大于最大子列和

18 {19 MaxSum = ThisSum; //最大和

20 Enddata = list[i]; //结尾子序列数据

21 Forntdata = list[i - sublen + 1]; //开始子序列数据

22 }23 if (ThisSum < 0) //如果子列和 < 0

24 {25 ThisSum = 0;26 sublen = 0;27 }28 }29

30 if (MaxSum < 0)31 {32 System.out.println(0 + " " + list[0] + " " + list[N - 1]);33 }34 else

35 {36 System.out.println(MaxSum + " " + Forntdata + " " +Enddata);37 }38 }39

40 public static voidmain(String[] args) {41 int list [] = new int[]{-10, 1, 2, 3, 4, -5, -23, 3, 7, -21};42 int N =list.length;43 Maximums(list, N);44 }45 }

三、二分查找

顾名思义,就是从中间比较,不断分,来进行查找的一种方法,但是缺点是查找的子序列必须是已经排好序了的

1 /**

2 *@author小喵钓鱼3 * @date 2020-02-02 14:384 * @veision 1.105 */

6 public classbinary_search {7 public static int binary_search_pp(int list[], intsearchKey)8 {9 int Center; //中间坐标

10 int lower = 0;11 int upper = list.length - 1;12 while (true)13 {14 Center = (lower + upper) / 2; //更新

15 if (list[Center] == searchKey){ //如果第一次就找到,直接返回

16 returnCenter;17 }18

19 else if(lower > upper) //如果最低坐标,比最高坐标大,那么代表这个数组就一个元素

20 {21 returnlist.length;22 }23 else{24 if (list[Center] < searchKey) //如果 <

25 lower = Center + 1;26 else //如果 大

27 upper = Center - 1;28 }29 }30 }31

32 public static voidmain(String[] args) {33 int key [] = new int[]{1, 2, 3, 4 ,5 ,6};34 System.out.println(binary_search_pp(key, 3));35 }36 }

四、两个有序链表序列的合并

怎么说呢,感觉自己写的有点小问题,不过无伤大雅,虽然是倒叙就是了,不过思路还是可以借鉴的

虽然是用 Java写的,但是并没有用到 相应的库,自行写的 单向链表类。

1 /**

2 *@author小喵钓鱼3 * @date 2020-02-02 14:594 * @veision 1.105 * L1和L2是给定的带头结点的单链表,其结点存储的数据是递增有序的;函数Merge要将L1和L2合并为一个非递减的整数序列。应直接使用原序列中的结点,返回归并后的带头结点的链表头指针。6 */

7 public classLink{8 public int iData; //data item

9 public double dData; //data item

10 public Link next; //next link in list

11 public Link(int id, doubledd)12 {13 iData = id; //initializa data

14 dData =dd;15 }16 public voiddisplayLink()17 {18 System.out.println("{" + iData + ", " + dData + "}");19 }20 }21

22

23 classLinkList {24 private Link first; //ref to first link on list

25

26 public voidLinkList() {27 first = null;28 }29

30 public booleanisEmpty() {31 return (first == null);32 }33

34 public void insertFirst(int id, doubledd) {35 Link newLink = newLink(id, dd);36 newLink.next = first; //newLink --> old first

37 first = newLink; //first --> newLink

38 }39

40 publicLink deleteFirst() {41 Link temp =first;42 first =first.next;43 returntemp;44 }45

46 public voiddisplayList() {47 System.out.println("List(first --> last)");48 Link current = first; //start at beginning of list

49 while (current != null) {50 current.displayLink(); //print data

51 current = current.next; //move to next link

52 }53 System.out.println(" ");54 }55

56 public Link find(intKey) {57 Link current =first;58 while (current.dData !=Key) {59 if (current.next == null)60 return null; //didn't find it

61 else

62 current =current.next;63 }64 returncurrent;65 }66

67 public voidMerge(LinkList L1)68 {69 LinkList L = newLinkList();70 Link pa, pb, pc;71 pa =first;72 pb =L1.first;73 pc =L.first;74 int count = 0;75 while (pa != null && pb != null)76 {77 System.out.println(pa.dData + "=" +pb.dData);78 if (pa.dData >=pb.dData)79 {80 if (count < 1)81 {82 L.first =pa;83 count ++;84 }85 else{86 pc.next =pa;87 }88 pc =pa;89 pa =pa.next;90 }91 else{92 if (count < 1)93 {94 L.first =pb;95 count++;96 //pc .next = pb;

97 }98 else{99 pc.next =pb;100 }101 pc =pb;102 pb =pb.next;103 }104 }105

106 pc.next = pa != null?pa: pb;107 L1.first = null;108 this.first =L.first;109 }110 }111

112 classLinkListApp{113 public static voidmain(String [] args)114 {115 LinkList theList = new LinkList(); //make new list

116

117 theList.insertFirst(1, 2.29); //insert four items

118 theList.insertFirst(4, 4.29);119 theList.insertFirst(6, 6.99);120 theList.insertFirst(7, 8.99);121

122

123 LinkList nextList = newLinkList();124 nextList.insertFirst(2, 2.30);125 nextList.insertFirst(3, 3.40);126 nextList.insertFirst(5, 5.33);127

128

129 theList.Merge(nextList);130 theList.displayList();131 }132 }

五、一元多项式的乘法与加法运算

设计函数分别求两个一元多项式的乘积与和。

输入格式:

输入分2行,每行分别先给出多项式非零项的个数,再以指数递降方式输入一个多项式非零项系数和指数(绝对值均为不超过1000的整数)。数字间以空格分隔。

输出格式:

输出分2行,分别以指数递降方式输出乘积多项式以及和多项式非零项的系数和指数。数字间以空格分隔,但结尾不能有多余空格。零多项式应输出0 0。

输入样例:

4 3 4 -5 2 6 1 -2 0

3 5 20 -7 4 3 1

输出样例:

15 24 -25 22 30 21 -10 20 -21 8 35 6 -33 5 14 4 -15 3 18 2 -6 1

5 20 -4 4 -5 2 9 1 -2 0

代码示例

1 /**

2 *@author小喵钓鱼3 * @date 2020-02-02 18:184 * @veision 1.105 * 设计函数分别求两个一元多项式的乘积与和。6 *7 * 输入格式:8 * 输入分2行,每行分别先给出多项式非零项的个数,再以指数递降方式输入一个多项式非零项系数和指数(绝对值均为不超过1000的整数)。数字间以空格分隔。9 *10 * 输出格式:11 * 输出分2行,分别以指数递降方式输出乘积多项式以及和多项式非零项的系数和指数。数字间以空格分隔,但结尾不能有多余空格。零多项式应输出0 0。12 */

13 classLinks14 {15 public intiData;16 public intdData;17 public Links next; //next Link

18 public Links(int id, intdd)19 {20 iData =id;21 dData =dd;22 }23

24 public voiddisplayLink()25 {26 System.out.println("{" + iData + ":" + dData + "}");27 }28

29 public void setId(intid)30 {31 this.iData =id;32 }33 }34 classLinkList{35 public Links first; //ref to the first link

36 public Links last; //ref to the last link

37

38 public voidLinkList()39 {40 first = null;41 last = null;42 }43

44 public booleanisEmpty()45 {46 return (first == null);47 }48

49 public void insertFirst(int id, intdd)50 {51 Links newLink = newLinks(id, dd);52 if(isEmpty())53 {54 last = newLink; //newLink

55 }56 newLink.next = first; //newLink --> old first

57 first =newLink;58 }59

60 public void insertAfter(int id, intdd)61 {62 Links newLink = newLinks(id, dd);63 if(isEmpty())64 {65 first = newLink; //first --> newLink

66 }67 else

68 last.next = newLink; //old last --> newLink

69 last = newLink; //newLink

70 }71

72 public voiddisplayLink()73 {74 System.out.println("List(first --> last)");75 Links current = first; //start at beginning of list

76 while (current != null) {77 current.displayLink(); //print data

78 current = current.next; //move to next link

79 }80 System.out.println(" ");81 }82

83 }84 public classMult_Add {85 public static voidReadOnly(LinkList P1)86 {87 Scanner scanner = newScanner(System.in);88 int N = scanner.nextInt(); //位数

89 for (int i = 0; i < N; i++)90 {91 int idata =scanner.nextInt();92 int ddata =scanner.nextInt();93 P1.insertAfter(idata, ddata);94 }95 }96

97 public staticLinkList Add(LinkList T1, LinkList T2)98 {99 LinkList P = newLinkList();100

101 if (T1 == null || T2 == null)102 {103 return null;104 }105 //分别指向 T1, T2 的第一个元素

106 Links link1 =T1.first;107 Links link2 =T2.first;108

109 while (link1 != null && link2 != null) { //两者均不为空时

110 if (link1.dData >link2.dData) {111 P.insertAfter(link1.iData, link1.dData);112 link1 =link1.next;113 }114 else if(link1.dData

120 if (link1.iData + link2.iData != 0) {121 P.insertAfter(link1.iData +link2.iData, link1.dData);122 }123 link1 =link1.next;124 link2 =link2.next;125 }126 }127

128 while (link1 != null)129 {130 P.insertAfter(link1.iData, link1.dData);131 link1 =link1.next;132 }133 while (link2 != null)134 {135 P.insertAfter(link2.iData, link2.dData);136 link2 =link2.next;137 }138 returnP;139 }140

141

142 public staticLinkList Mult(LinkList T1, LinkList T2)143 {144 LinkList P = newLinkList();145 //分别指向第一个元素

146 Links link1 =T1.first;147 Links link2 =T2.first;148

149 /**

150 * 这里用的方法是先将两者每一个都像乘法那样相乘,然后进行同类项的合并151 */

152 while (link1 != null)153 {154 while (link2 != null)155 {156 int idata = link1.iData *link2.iData;157 int ddata = link1.dData +link2.dData;158 P.insertAfter(idata, ddata);159 link2 =link2.next;160 }161 link1 =link1.next;162 link2 =T2.first;163 }164

165 //合并同类项

166 Links link3 = P.first; //指向 P 的 第一个元素

167 Links tempPrevious = link3; //同指

168 Links temp = link3.next; //指向第二个元素

169 while (link3.next != null) //当Link3 不等于 last 时。。。

170 {171 while (temp != null)172 {173 if (temp.dData != link3.dData) //如果 前一个和后一个的指数不同,则都向下进一个

174 {175 temp =temp.next;176 tempPrevious =tempPrevious.next;177 }178 else //如果两者指数相同

179 {180 link3.setId(link3.iData + temp.iData); //更改前者系数

181 tempPrevious.next = temp.next; //将 前者改成 temp

182 temp = temp.next; //temp = temp.next

183 }184 }185 link3 =link3.next;186 tempPrevious =link3;187 temp =link3.next;188 }189 returnP;190 }191

192 public static voidmain(String[] args) {193 LinkList p1 = newLinkList();194 ReadOnly(p1);195 p1.displayLink();196

197 LinkList p2 = newLinkList();198 ReadOnly(p2);199 p2.displayLink();200 LinkList P =Add(p1, p2);201 P.displayLink();202

203 LinkList P3 =Mult(p1, p2);204 P3.displayLink();205 }206 }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值