一些简单常用算法整理学习 转

001 // test5.2.cpp : 定义控制台应用程序的入口点。
002 //
003 // 2010.5.9
004 //sylar
005 //
006 #include "stdafx.h"
007 #include <iostream>  
008 using namespace std;  
009  
010 //动态规划:0-1背包问题  
011 //bestValue[i][j]=max ( bestValue[i+1][j-w[i]]+v[i] ,bestValue[i+1][j] )  w[i]<=j  
012 //bestValue[i][j]=bestValue[i+1][j]        w[i]>j  
013  
014 class Knapsack  
015 {  
016 private :  
017      int *weight; //物品重量数组  
018      int *value; //物品价值数组  
019      int numOfItems; //物品数量  
020      int bagSpace; //背包容量  
021      int **bestValue; //动态规划表格,记录bestValue[i][j]的价值,为最优价值,i表示物品i...n装入容量为j的背包能达到的最大价值  
022      int **path; //为了求出取得最优值时的解,记录动态规划表不同表项的选择与否  
023 public :  
024      //构造函数  
025      Knapsack( int numOfItems, int bagSpace)  
026      {  
027          weight= new int [numOfItems+1];  
028          value= new int [numOfItems+1];  
029          this ->bagSpace=bagSpace;  
030          this ->numOfItems=numOfItems;  
031  
032          bestValue= new int * [numOfItems+1];  
033          for ( int i=0;i<numOfItems+1;i++)  
034          {  
035              bestValue[i]= new int [bagSpace+1];  
036          }  
037  
038          path= new int * [numOfItems+1];  
039          for ( int i=0;i<numOfItems+1;i++)  
040          {  
041              path[i]= new int [bagSpace+1];  
042          }     
043      }  
044      //输入物品的重量与价值  
045      void input()  
046      {  
047          int i=1;  
048          while (i<=numOfItems)  
049          {  
050              cout<< "输入第" <<i<< "个物品的重量" <<endl;  
051              cin>>weight[i];  
052              cout<< "输入第" <<i<< "个物品的价值" <<endl;  
053              cin>>value[i];  
054              ++i;  
055          }  
056      }  
057      //动态规划核心算法  
058      void knapsack()  
059      {  
060          //初始化递归最底层,即将bestValue[n][0:c]进行初始化  
061          for ( int i=0;i<=bagSpace;i++)  
062          {  
063              if (weight[numOfItems]<=i)  
064              {  
065                  bestValue[numOfItems][i]=value[numOfItems];  
066                  path[numOfItems][i]=1;  
067              }  
068              else  
069              {  
070                  bestValue[numOfItems][i]=0;  
071                  path[numOfItems][i]=0;  
072              }  
073          }  
074          //递推的进行动态规划,自底向上,最终bestValue[1][bageSpace]为1-n物品放入容量bagSpace内的最大价值  
075          for ( int k=numOfItems-1;k>=1;k--)  
076          {  
077              for ( int j=0;j<=bagSpace;j++)  
078              {  
079                  bestValue[k][j]=bestValue[k+1][j];  
080                  path[k][j]=0; //不放入的情况  
081                  if (weight[k]<=j) //如果容量足够放入当前物品  
082                  {  
083                      if (bestValue[k+1][j-weight[k]]+value[k]>bestValue[k][j]) //如果放入的价值大于不放的价值  
084                      {  
085                          bestValue[k][j]=bestValue[k+1][j-weight[k]]+value[k];  
086                          path[k][j]=1; //那么就选择放入  
087                      }  
088                  }  
089              }  
090          }  
091      }  
092      //输出最大价值,并且输出选择方式  
093      void display()  
094      {  
095          //打印出bestValue[1][bagSpace],表示1...numOfItems的物品装入容量为bagSpace的最大价值  
096          int i=1;  
097          int j=bagSpace;  
098          cout<< "最大价值为" <<bestValue[1][j]<<endl;  
099          //根据path[1][bagSpace]的记录开始,递归到path[n][某容量],从而打印出每个物品是否被选择进入背包  
100          while (i<=numOfItems)  
101          {  
102              if (path[i][j]==0) //如果i物品没被放入,看i+1个物品装入容量j背包  
103              {  
104                  ++i;  
105              }  
106              else  
107              {  
108                  cout<< "<重量:" <<weight[i]<< ",价值:" <<value[i]<< ">" <<endl;  
109                  j-=weight[i];  
110                  ++i;  
111              }  
112          }  
113      }  
114 };  
115  
116 /*
117 void main()  
118 {  
119      Knapsack test(5,50);//5个物品,背包容量50  
120      test.input();//输入5个物品的价值与重量  
121      test.knapsack();//动态规划  
122      test.display();//打印选择与最大价值  
123
124 */
125  
126  
127 //动态规划:0-1背包问题
128 //bestValue[i][j]=max ( bestValue[i+1][j-w[i]]+v[i] ,bestValue[i+1][j] )  w[i]<=j
129 //bestValue[i][j]=bestValue[i+1][j]        w[i]>j
130  
131  
132 /*
133 思路总结: 看到一个题目,首先看问什么,下面以此题举例分析一下。
134  
135 0-1背包问题
136  
137 1,问题要求什么? 
138 答:求把n个物品放入容量C的背包内能达到的最大价值
139  
140 2,转换成一个抽象一点的数学表达式是什么? 
141 答:bestValue[n][C],表示n个物品放入容量C的背包的最大价值
142  
143 3,不考虑算法应该怎么选择,我们实际去解决这个问题的时候,是从哪里开始去做的?
144 答:我们有n个物品,C容量背包。  于是我们开始解决问题,我先放第一个物品,如果能放进去,我就放进去,当然,我也可以不放。
145 第一个物品处理结束以后,我们着手于第二个物品,能放进去就放进去,当然,我们也可以不放。 
146 所以,这就是一个决策问题,决策是从我们实际处理问题中抽象出来的,我们放物品的时候只能一个一个放,决策是放或者不放。
147  
148 4,在决策了解的情况,我们应该考虑当前要求的bestValue[n][C],在决策放入或者不放入的情况,分别等于什么?
149 答:如果能够放入,那么我们的背包还有C-w[i], 物品还有n-1个,当然,我们也可以选择不放进去,那么我们背包依旧有C容量,物品还有n-1个。 所以我们修改一下我们对bestValue[n][C]的定义,从而就得到了一个最优子结构的递归公式。
150  
151 为了我们决策的进行,即我们每次决策都是最第i个物品进行决策,所以bestValue[n][C]修改为best[i][C],表示i,i+1,i+2...n个物品放入容量为C的背包的最大价值。
152  
153 所以:bestValue[i][j]=max ( bestValue[i+1][j-w[i]]+v[i] ,bestValue[i+1][j] )  w[i]<=j
154 bestValue[i][j]=bestValue[i+1][j]        w[i]>j
155  
156 意思是:
157 如果当前容量j装不下物品i,那么i到n装入j的最大价值就等于i+1到n装入j的最大价值,就是公式的第二行。
158 如 果当前容量j可以装下物品i,那么我们可以装进去,当然,也可以犯贱,不装进去,看看结果如何,所以i到n个物品装入j容量背包的最大价值就等于 i+1到n物品装入j-w[i]容量的背包可以达到的最大价值+value[i] ,i+1到n物品装入j容量背包的最大价值,这两种不同决策的一个最大值。
159  
160 总结:解决什么?  从哪里开始做起?  有哪些决策?  决策后会怎么样?
161  
162 找 出了递归式,它具有最优子结构性质,即可以简单的理解为:当前的最优产生于子问题的最优,然后子问题的最优不受当前最优的影响,并且通过观察递归公式,应 该找到递归的最底层的i,j分别是什么,我们观察到i在逐渐增加,j在逐渐减小,所以我们在递推的时候,首先把最底层进行初始化,然后利用递归公式向上递 推。 所以我们需要首先初始化bestValue[n][0:C],即记录第n个物品装入0到C的背包的能达到的价值,当w[n]<=j 时,bestValue[n][j]等于value[n],如果w[n]>j,即容量不够,那么就是0.
163  
164 我们能够从底向上递推的重要原因就是:最优子结构+无后效性 。 多多体会吧。 这是基础理解了。
165  
166 */
167  
168  
169  
170 #include <stdio.h>
171 int a[100],n,temp;
172 void QuickSort( int h, int t)
173 {
174      if (h>=t) return ;
175      int mid=(h+t)/2,i=h,j=t,x;
176      x=a[mid];
177      while (1)
178      {
179          while (a[i]<x) i++;
180          while (a[j]>x) j--;
181          if (i>=j) break ;
182          temp=a[i];
183          a[i]=a[j];
184          a[j]=temp;
185      }
186      a[mid]=a[j];
187      a[j]=x;
188      QuickSort(h,j-1);
189      QuickSort(j+1,t);
190      return ;
191 }
192 /*
193 int main()
194 {
195      int i;
196      scanf("%d",&n);
197      for(i=0;i<n;i++) scanf("%d",&a[i]);
198      QuickSort(0,n-1);
199      for(i=0;i<n;i++) printf("%d ",a[i]);
200      return(0);
201 }
202 */
203  
204  
205  
206 #include "stdafx.h"
207 #include<stdio.h>
208 #include<math.h>
209 #include <string.h>
210 #include <iostream>
211 using namespace std;
212  
213 /*
214 //伪代码
215 //
216 if  等于 ' '
217 {
218 直接输出5个
219 }
220 else if 不等于' '
221 {
222 if 这5个字符串是连续的
223 {
224 直接输出这5个字符
225 }
226  
227 if 这5个字符中含有' '
228 {
229 只输出' '前面的几个字符
230 }
231 }
232 */
233  
234 /*
235 //有一个字符串,由字符和空格组成,输入一个每行最大字符数line_size,则按照每行line_size输出,不够则换行例如
236 //输入 abcdef ghij kl mn opq  r stxyzuvw  line_size=5
237 //输出
238 abcde
239 f
240 ghij
241 kl mn
242 opq  r
243 stxyz
244 uvw
245 */
246  
247  
248 int fun1( char * str, int line_size)
249 {
250      char *p1;
251      char * p2;
252      int i;
253      p1=p2 =str;
254      int flag = 0;
255      char * out = new char [line_size + 1];
256      for (i = 0;  i < strlen (str); i += line_size)
257      {
258          memset (out, '/0' , line_size + 1);
259          if ( *(p1 + line_size) == ' ' ) ///
260          {
261              p1 ++;
262              strncpy (out, p1, line_size);
263              cout << out;
264              p1 = p1 + line_size;
265              cout<<endl;
266          }
267          else
268          {
269              p2 = p1 + line_size;
270              while (*(--p2) != ' ' && p2 != p1);
271              if (p1 == p2)
272              {
273                  strncpy (out, p1, line_size);
274                  cout << out;
275                  p1 = p1 + line_size;
276                  cout<<endl;
277                  continue ;
278              }
279              else
280              {
281                  strncpy (out, p1, p2 - p1);
282                  cout << out;
283                  p1 = p2;
284                  cout<<endl;
285                  continue ;
286              }
287          }
288      }
289      delete [] out;
290      out = NULL;
291      return 1;
292 }
293  
294 /*
295 int main()
296 {
297 //关键:每5个判断一次,判断位置信息 如果为空,跳过,如果有数字 则计算
298 char a[1024] = "abcdef ghij kl mn opq r stxyzuvw";
299 //  fun(a, 5);
300 fun1(a, 5);
301 return 1;
302 }
303 */
304  
305  
306 //输入两个整数 n 和 m,从数列1,2,3.......n 中 随意取几个数,使其和等于 m ,要求将其中所有的可能组合列出来.编程求解
307  
308  
309  
310 //3)写出在母串中查找子串出现次数的代码.
311 int count1( char * str, char * s)
312 {
313      char *src = str;
314      char *des = s;
315      int times = 0;
316      while ( *src != '/0' )
317      {
318          if (*src == *des )
319          {
320              char * temp1 = src;
321              char * temp2 = des;
322              while (  *temp2 != '/0'   && *(temp2++) == *(temp1++)  );
323              if (*temp2 == '/0' ) //如果完全匹配
324              {
325                  times++;      //出现次数加一
326                  src += strlen (s);
327                  continue ;
328              }
329          }
330          src++;  //不匹配
331      }
332      return times;
333 }
334  
335 //2)写出二分查找的代码.
336 int
337 bfind( int * a, int len, int val)
338 {
339      int temp;
340      int i,j;
341      i = 0; j = len - 1;
342      //if ()
343      while (i <= j)
344      {
345          temp = (a[i] + a[j])/2;
346          if (temp == val)
347          {
348              return (i + j)/2;
349          }
350          else if (temp > val)
351          {
352              j = (i + j)/2 - 1 ;
353          }
354          else if (temp < val)
355          {
356              i = (i + j)/2 + 1 ;
357          }
358      }
359      return -1;
360 }
361  
362 //快速排序:
363 void quick_sort( int *x, int low, int high)
364 {
365      int i, j, t;
366      if (low < high)
367      {
368          i = low;
369          j = high;
370          t = *(x+low);
371          while (i<j)
372          {
373              while (i<j && *(x+j)>t)
374              {
375                  j--;
376              }
377              if (i<j)
378              {
379                  *(x+i) = *(x+j);
380                  i++;
381              }
382              while (i<j && *(x+i)<=t)
383              {
384                  i++;
385              }
386              if (i<j)
387              {
388                  *(x+j) = *(x+i);
389                  j--;
390              }
391          }
392          *(x+i) = t;
393          quick_sort(x,low,i-1);
394          quick_sort(x,i+1,high);
395      }
396 }
397 /*
398 void main()
399 {
400      int temp[] ={3,8,6,2,9,7,1};
401      quick_sort(temp, 0, 6);
402 }
403 */
404  
405 //快速排序:
406 int partition1( int * a, int begin, int end)
407 {
408      int value;
409      int temp;
410      int i, j;
411      int pos;
412      value = a[begin];
413      j = end;
414      i = begin;
415      pos = begin;
416      if (begin == end)
417      {
418          return 1;
419      }
420      while (i < j)
421      {
422          while (a[j] > value)  j--;
423          while (a[i] < value)  i++;
424  
425          temp = a[i];
426          a[i] = a[j];
427          a[j] = temp;
428      }
429      partition1(a, begin, i);
430      partition1(a, i, end);
431      return 1;
432 }
433  
434 // max1(12, 8);
435 int max1( int m, int n)
436 {
437      int temp;
438      while (m%n != 0)
439      {
440          temp = n;
441          n = m%n;
442          m = temp;
443      }
444      return n;
445 }
446  
447 //算法复杂度 m + n
448 void merge( int a[], int n, int b[], int m, int *c)
449 {
450      int i = 0;
451      int j = 0;
452      int k = 0;
453      while (i < n && j < m)
454      {
455          if (a[i] < b[j] && i < n)
456          {
457              c[k] = a[i];
458              i++;
459          }
460          else if (a[i] >= b[j] && j < m)
461          {
462              c[k] = b[i];
463              j++;
464          }
465          k++;
466      }
467 }
468  
469 /*
470 int main()
471 {
472  
473 int str1[5] ={1,3,5,7,9};
474 int str2[5] ={1,2,4,6,8};
475 int out[30];
476 merge(str1,5,str2,5,out);
477 //  char a[100] = "abcababaabc";
478 //  /char b[100] = "ab";
479 //  int num = count1(a, b);
480  
481 //  int bf[10] =  {1,2,3,4,5,6,7,8,9,10};
482 //  num = bfind(bf, 10, 10);
483 int ttt = max1(20, 12);
484  
485 int a[10] = {4,6,8,1,3,5,7,9,2,10};
486 partition1(a, 0 , 9);
487  
488 return 1;
489 }
490  
491 */
492  
493  
494  
495  
496 //栈(数组栈,指针栈)
497 //来个简单的数组栈把
498  
499 template < class T>
500 class xj_stack
501 {
502 public :
503      xj_stack()
504      {
505          memset (array, 0, sizeof (array));
506          totol_num = 0;
507      }
508      T pop_stack()
509      {
510          if (totol_num == 0)
511          {
512              return T(1);
513          }
514          return array[--totol_num];
515      }
516      int push_stack(T num)
517      {
518          array[totol_num++] = num;
519          return 1;
520      }
521      int is_empty()
522      {
523          if (totol_num==0)
524          {
525              return 1;
526          }
527          return 0;
528      }
529 protected :
530 private :
531      T array[30];
532      int totol_num;
533 };
534  
535 typedef struct _btree
536 {
537      struct _btree * left;
538      struct _btree * right;
539      int node_value;
540 }btree, *pbtree;
541  
542 //建立一个二叉树
543 //
544 //
545 int create_ntree(pbtree& pnode)
546 {
547      //pbtree pnode;
548      int value;
549      cin>>value;
550      if (value == 0)
551      {
552          return 0;
553      }
554      pnode = new btree;
555      memset (pnode, '/0' , sizeof (btree));
556      pnode->node_value = value;
557      create_ntree(pnode->left);
558      create_ntree(pnode->right);
559      return 1;
560 }
561  
562 //先序遍历一个二叉树,递归实现
563 void pre_order(pbtree root)
564 {
565      if (root == NULL)
566      {
567          return ;
568      }
569      cout<<root->node_value;
570      pre_order(root->left);
571      pre_order(root->right);
572 }
573  
574 //先序遍历一个二叉树,非递归实现
575 void pre_order_ex1(pbtree root)
576 {
577      xj_stack<pbtree> m_stack;
578      while (root != NULL || m_stack.is_empty() != 1)
579      {
580          if (root != NULL)
581          {
582              cout<<root->node_value;
583              m_stack.push_stack(root);
584              root = root->left;
585          }
586          else
587          {
588              root = m_stack.pop_stack();
589              root = root->right;
590          }
591      }
592 }
593  
594 pbtree root = NULL;
595 /*
596 void main()
597 {
598      create_ntree(root);
599      pre_order(root);
600      cout<<endl;
601      pre_order_ex1(root);
602 }
603 */
604  
605  
606 //寻找第i小的数
607 #include <iostream>
608 using namespace std;
609 const int N=10;
610 int partition( int *, int , int );
611 void exchange( int &, int &);
612  
613 int find_mid_num( int *A, int p, int r, int i){
614      if (p==r)
615          return A[p];
616      int q=partition(A, p, r);
617      int k=q-p+1;
618      if (k==i)
619          return A[q];
620      else if (k<i)
621          return find_mid_num(A, q+1,r,i-k);
622      else
623          return find_mid_num(A, p, q-1, i);
624 }
625  
626 int partition( int *A, int p, int r){
627      int x=A[r];
628      int i=p-1;
629      for ( int j=p;j<r;j++)
630          if (A[j]<=x)
631          {
632              i++;
633              exchange(A[j],A[i]);
634          }
635          exchange(A[i+1],A[r]);
636          return i+1;
637 }
638  
639 void exchange( int &x, int &y)
640 {
641      int z=x;
642      x=y;
643      y=z;
644 }
645  
646 int main()
647 {
648      int Array[10]={1,4,5,3,8,7,5,9,6,2};
649      int m=N/2;
650      int output=find_mid_num(Array, 0, N-1, m);
651      cout << output << endl;
652      while (1);
653      return 0;
654 }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值